i need a command or a script returning supported hashing algorithms (for hashing passwords) on a system, i mean algorithms can be used with pam.d configuration files or login.defs .
generally md5,bigcrypt,sha256, sha512 and blowfish are supported but i need to programmatically check if new algorithm is supported and determine it in my script.i checked /proc/crypto but is was too less than what i mentioned before
thanks
/proc/crypto is just a list of the algorithms that the kernel knows about; this has nothing to do with PAM.
There is no way to directly query PAM to find out what hashes it can support; it knows this internally, of course, but it is not exposed by any public API.
One thing you could do is use crypt and attempt to hash a pass with the various id types, essentially probing PAM (or more properly, probing libc's crypt, which PAM uses for shadowed passwords). Simple example:
#include <unistd.h>
#include <stdio.h>
#include <string>
bool test_crypt_method(const char* id)
{
const std::string salt =
std::string("$") + id + "$" + "testsalt$";
std::string crypt_result = ::crypt("password", salt.c_str());
/*
* If the hash ID is not supported, glibc unfortunately
* then treats it as a old-style DES crypt rather than
* failing; find this situation.
*/
if(crypt_result.size() == 13 &&
crypt_result[0] == '$' &&
crypt_result.find('$', 1) == std::string::npos)
return false;
return true;
}
int main()
{
if(test_crypt_method("1"))
printf("md5 ");
if(test_crypt_method("2a"))
printf("blowfish ");
if(test_crypt_method("4")) // test for false positives
printf("undefined ");
if(test_crypt_method("5"))
printf("sha256 ");
if(test_crypt_method("6"))
printf("sha512 ");
printf("\n");
}
Related
I'm trying to read the value of ccount register on esp8266. Though the first read after reset seems to be sensible, the rest values seem to be fishy.
Here is a complete code snippet I'm using
/* Hello World Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
static inline uint32_t get_ccount(void)
{
volatile uint32_t r;
__asm__ __volatile__("rsr %0,ccount":"=a" (r));
return r;
}
static void print_ccount()
{
uint32_t c = get_ccount();
printf("ccount: %u\n", c);
}
void app_main()
{
for (int i = 10; i >= 0; i--) {
print_ccount();
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
printf("Restarting now.\n");
fflush(stdout);
esp_restart();
}
First read after reset is usually something like 659430, 110466 etc, but the rest values is usually recurring '1981' value or something similar. Even after reset, all reads after the first read return '1981' value.
Sometimes the output looks like this:
�ccount: 110466
I'm afraid that there is some garbage on the stack but I can't figure out what is the cause.
Since two days I am trying to make printf\sprintf working in my project...
MCU: STM32F722RETx
I tried to use newLib, heap3, heap4, etc, etc. nothing works. HardFault_Handler is run evry time.
Now I am trying to use simple implementation from this link and still the same problem. I suppose my device has some problem with double numbers, becouse program run HardFault_Handler from this line if (value != value) in _ftoa function.( what is strange because this stm32 support FPU)
Do you guys have any idea? (Now I am using heap_4.c)
My compiller options:
target_compile_options(${PROJ_NAME} PUBLIC
$<$<COMPILE_LANGUAGE:CXX>:
-std=c++14
>
-mcpu=cortex-m7
-mthumb
-mfpu=fpv5-d16
-mfloat-abi=hard
-Wall
-ffunction-sections
-fdata-sections
-O1 -g
-DLV_CONF_INCLUDE_SIMPLE
)
Linker options:
target_link_options(${PROJ_NAME} PUBLIC
${LINKER_OPTION} ${LINKER_SCRIPT}
-mcpu=cortex-m7
-mthumb
-mfloat-abi=hard
-mfpu=fpv5-sp-d16
-specs=nosys.specs
-specs=nano.specs
# -Wl,--wrap,malloc
# -Wl,--wrap,_malloc_r
-u_printf_float
-u_sprintf_float
)
Linker script:
/* Highest address of the user mode stack */
_estack = 0x20040000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}
UPDATE:
I don't think so it is stack problem, I have set configCHECK_FOR_STACK_OVERFLOW to 2, but hook function is never called. I found strange think: This soulution works:
float d = 23.5f;
char buffer[20];
sprintf(buffer, "temp %f", 23.5f);
but this solution not:
float d = 23.5f;
char buffer[20];
sprintf(buffer, "temp %f",d);
No idea why passing variable by copy, generate a HardFault_Handler...
You can implement a hard fault handler that at least will provide you with the SP location to where the issue is occurring. This should provide more insight.
https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html
It should let you know if your issue is due to a floating point error within the MCU or if it is due to a branching error possibly caused by some linking problem
I also had error with printf when using FreeRTOS for my SiFive HiFive Rev B.
To solve it, I rewrite _fstat and _write functions to change output function of printf
/*
* Retarget functions for printf()
*/
#include <errno.h>
#include <sys/stat.h>
int _fstat (int file, struct stat * st) {
errno = -ENOSYS;
return -1;
}
int _write (int file, char * ptr, int len) {
extern int uart_putc(int c);
int i;
/* Turn character to capital letter and output to UART port */
for (i = 0; i < len; i++) uart_putc((int)*ptr++);
return 0;
}
And create another uart_putc function for UART0 of SiFive HiFive Rev B hardware:
void uart_putc(int c)
{
#define uart0_txdata (*(volatile uint32_t*)(0x10013000)) // uart0 txdata register
#define UART_TXFULL (1 << 31) // uart0 txdata flag
while ((uart0_txdata & UART_TXFULL) != 0) { }
uart0_txdata = c;
}
The newlib C-runtime library (used in many embedded tool chains) internally uses it's own malloc-family routines. newlib maintains some internal buffers and requires some support for thread-safety:
http://www.nadler.com/embedded/newlibAndFreeRTOS.html
hard fault can caused by unaligned Memory Access:
https://www.keil.com/support/docs/3777.htm
I working on little ECC crypto problem.
The goal is to write a program in C or bash, which will take as input a hash composed of 128 characters in hexadecimal
(Example: 8A9A35145C4EA5260DF9972C804FE2D3F9F3D7A2AC01A6BEB21C82BB30957B3952273AC9166B90C1207347A925780F84A1D2359E7AA05201C674D2B9746FCA07)
and which will generate from the input hash a private key and a public key of type Elliptic Curve and display the key pair generated.
Can someone clarify for me the problem. I can't understand why we need a hash(or any string) to generate a pair key, as I found In many online solution like this one ther's no need to give a hash. Maybe is it a parphase ? Maybe It's the curve key or somthing similar.
I think all we need is to do something like this for the private key:
openssl ecparam -genkey -noout -out myprivatekey.pem
and for the public key generation:
openssl -ec -in myprivatekey.pem -pubout -out mypublickey.pem
The question is : why we need an input a hash composed of 128 to generate our pair keys? Is it a passphrase for security reason? how made the trick with openssl ?
You could use a hash if you've got some kind of input binary value which you need to convert to a key.
You can use a hash as input for a private key. To convert it you should first convert it to a number and then perform a calculation modulo n on it, where n is the order of the ECC domain parameters. The resulting value can be called s Then you can calculate the public key out of it by performing s * G, i.e. point multiplication with the base point.
OpenSSL is not a low level crypto library, so you'd have to program it, possibly using the OpenSSL API and the BN (big number) library that comes with it. It is not that tricky, but if you're still talking about 128 characters instead of 64 bytes then you may have a lot of learning to do.
In fact this is my own code, you can improve it and edit the solution bellow:
// gcc -Wall ecdsapubkey.c -o ecdsapubkey -lcrypto
#include <stdio.h>
#include <stdlib.h>
#include <openssl/ec.h>
#include <openssl/obj_mac.h>
#include <openssl/bn.h>
int main()
{
EC_KEY *eckey = NULL;
EC_POINT *pub_key = NULL;
const EC_GROUP *group = NULL;
BIGNUM *start;
BIGNUM *res;
BN_CTX *ctx;
start = BN_new();
ctx = BN_CTX_new(); // ctx is an optional buffer to save time from allocating and deallocating memory whenever required
res = start;
BN_hex2bn(&res,"8A9A35145C4EA5260DF9972C804FE2D3F9F3D7A2AC01A6BEB21C82BB30957B3952273AC9166B90C1207347A925780F84A1D2359E7AA05201C674D2B9746FCA07");
eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
group = EC_KEY_get0_group(eckey);
pub_key = EC_POINT_new(group);
printf("private key : "); BN_print_fp(stdout, res); printf("\n");
EC_KEY_set_private_key(eckey, res);
/* pub_key is a new uninitialized `EC_POINT*`. priv_key res is a `BIGNUM*`. */
if (!EC_POINT_mul(group, pub_key, res, NULL, NULL, ctx))
printf("Error at EC_POINT_mul.\n");
EC_KEY_set_public_key(eckey, pub_key);
char *cc = EC_POINT_point2hex(group, pub_key, 4, ctx);
char *c=cc;
int i;
printf("public key : ");
for (i=0; i<130; i++) // 1 byte 0x42, 32 bytes for X coordinate, 32 bytes for Y coordinate
{
printf("%c", *c++);
}
printf("\n");
BN_CTX_free(ctx);
free(cc);
return 0;
}
Okay, I spent the last couple of days researching this, and I can't believe Apache's natively supported hashing functions are that outdated.
I discovered a couple of ways to do this, which are mod_perl and mod_authnz_external, both of which are too slow, because apache runs that whenever any object inside a protected directory is called. That means that a user may have to be authenticated hundreds of times in a single session.
Has anyone ever managed to get Apache to use something that's more secure than MD5 and SHA-1 without moving authentication away from Apache? Salted SHA-2 would be a real bonus.
Thanks!
If you're on a GNU/Linux system with a version of glibc2 released in the last 5 or so years, you can modify htpasswd's crypt() implementation to prepend "$6$" to the salt, and then it'd be as simple as:
# htpasswd -d -c .htpasswd someusername
When the salt starts with "$6$", glibc2 will use salted SHA-512, with the up to 16 characters after that being the salt, in the range [a-zA-Z0-9./].
See man 3 crypt.
I'm not aware of any patch to support this, but it should be a simple one.
EDIT: I'd also like to mention that one round of even salted SHA-512 is breakable if your attacker is determined enough. I'd recommend, and am using in most things I've been able to edit, 128000 rounds of PBKDF2 with HMAC-SHA512, but this would be a very extensive edit, unless you want to link htpasswd against openssl, which has a PKCS5_PBKDF2_HMAC() function.
EDIT 2: Also, using openssl to do strong hashing isn't hard, if you're interested:
abraxas ~ # cat pbkdf2.c
#include <string.h>
#include <stdio.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#define PBKDF2_SALT_PREFIX "$pbkdf2sha512$"
#define PBKDF2_SALT_PREFIX_LENGTH strlen(PBKDF2_SALT_PREFIX)
#define PBKDF2_PRF_ALGORITHM EVP_sha512()
#define PBKDF2_DIGEST_LENGTH SHA512_DIGEST_LENGTH
#define PBKDF2_SALT_LENGTH 32
#define PBKDF2_RESULT_LENGTH PBKDF2_SALT_PREFIX_LENGTH + (2 * PBKDF2_DIGEST_LENGTH) + PBKDF2_SALT_LENGTH + 2
#define PBKDF2_ROUNDS 128000
void hash_password(const char* pass, const unsigned char* salt, char* result)
{
unsigned int i;
static unsigned char digest[PBKDF2_DIGEST_LENGTH];
memcpy(result, PBKDF2_SALT_PREFIX, PBKDF2_SALT_PREFIX_LENGTH);
memcpy(result + PBKDF2_SALT_PREFIX_LENGTH, salt, PBKDF2_SALT_LENGTH);
result[PBKDF2_SALT_PREFIX_LENGTH + PBKDF2_SALT_LENGTH] = '$';
PKCS5_PBKDF2_HMAC(pass, strlen(pass), salt, PBKDF2_SALT_LENGTH, PBKDF2_ROUNDS, PBKDF2_PRF_ALGORITHM, PBKDF2_DIGEST_LENGTH, digest);
for (i = 0; i < sizeof(digest); i++)
sprintf(result + PBKDF2_SALT_PREFIX_LENGTH + PBKDF2_SALT_LENGTH + 1 + (i * 2), "%02x", 255 & digest[i]);
}
int main(void)
{
char result[PBKDF2_RESULT_LENGTH];
char pass[] = "password";
unsigned char salt[] = "178556d2988b6f833f239cd69bc07ed3";
printf("Computing PBKDF2(HMAC-SHA512, '%s', '%s', %d, %d) ...\n", pass, salt, PBKDF2_ROUNDS, PBKDF2_DIGEST_LENGTH);
memset(result, 0, PBKDF2_RESULT_LENGTH);
hash_password(pass, salt, result);
printf("Result: %s\n", result);
return 0;
}
abraxas ~ # gcc -Wall -Wextra -O3 -lssl pbkdf2.c -o pbkdf2
abraxas ~ # time ./pbkdf2
Computing PBKDF2(HMAC-SHA512, 'password', '178556d2988b6f833f239cd69bc07ed3', 128000, 64) ...
Result: $pbkdf2sha512$178556d2988b6f833f239cd69bc07ed3$3acb79896ce3e623c3fac32f91d4421fe360fcdacfb96ee3460902beac26807d28aca4ed01394de2ea37b363ab86ba448286eaf21e1d5b316149c0b9886741a7
real 0m0.320s
user 0m0.319s
sys 0m0.001s
abraxas ~ #
Do you know the format in which GNU Radio ( File Sink in GNU Radio Companion) stores the samples in the Binary File?
I need to read these samples in Matlab, but the problem is the file is too big to be read in Matlab.
I am writing the program in C++ to read this binary file.
The file sink is just a dump of the data stream. If the data stream content was simple bytes then the content of the file is straightforward. If the data stream contained complex numbers then the file will contain a list of complex numbers where each complex number is given by two floats and each float by (usually) 4 bytes.
See the files gnuradio/gnuradio-core/src/lib/io/gr_file_sink.cc and gr_file_source.cc for the implementations of the gnuradio file reading and writing blocks.
You could also use python and gnuradio to convert the files into some other format.
from gnuradio import gr
# Assuming the data stream was complex numbers.
src = gr.file_source(gr.sizeof_gr_complex, "the_file_name")
snk = gr.vector_sink_c()
tb = gr.top_block()
tb.connect(src, snk)
tb.run()
# The complex numbers are then accessible as a python list.
data = snk.data()
Ben's answer still stands – but it's from a time long past (the module organization points at GNU Radio 3.6, I think). Organizationally, things are different now; data-wise, the File Sink remained the same.
GNU Radio now has relatively much block documentation in their wiki. In particular, the File Sink documentation page has a section on Handling File Sink data; not to overquote that:
// This is C++17
#include <algorithm>
#include <cmath>
#include <complex>
#include <cstddef>
#include <filesystem>
#include <fstream>
#include <string_view>
#include <vector>
#include <fmt/format.h>
#include <fmt/ranges.h>
using sample_t = std::complex<float>;
using power_t = float;
constexpr std::size_t read_block_size = 1 << 16;
int main(int argc, char *argv[]) {
// expect exactly one argument, a file name
if (argc != 2) {
fmt::print(stderr, "Usage: {} FILE_NAME", argv[0]);
return -1;
}
// just for convenience; we could as well just use `argv[1]` throughout the
// code
std::string_view filename(argv[1]);
// check whether file exists
if (!std::filesystem::exists(filename.data())) {
fmt::print(stderr, "file '{:s}' not found\n", filename);
return -2;
}
// calculate how many samples to read
auto file_size = std::filesystem::file_size(std::filesystem::path(filename));
auto samples_to_read = file_size / sizeof(sample_t);
// construct and reserve container for resulting powers
std::vector<power_t> powers;
powers.reserve(samples_to_read);
std::ifstream input_file(filename.data(), std::ios_base::binary);
if (!input_file) {
fmt::print(stderr, "error opening '{:s}'\n", filename);
return -3;
}
// construct and reserve container for read samples
// if read_block_size == 0, then read the whole file at once
std::vector<sample_t> samples;
if (read_block_size)
samples.resize(read_block_size);
else
samples.resize(samples_to_read);
fmt::print(stderr, "Reading {:d} samples…\n", samples_to_read);
while (samples_to_read) {
auto read_now = std::min(samples_to_read, samples.size());
input_file.read(reinterpret_cast<char *>(samples.data()),
read_now * sizeof(sample_t));
for (size_t idx = 0; idx < read_now; ++idx) {
auto magnitude = std::abs(samples[idx]);
powers.push_back(magnitude * magnitude);
}
samples_to_read -= read_now;
}
// we're not actually doing anything with the data. Let's print it!
fmt::print("Power\n{}\n", fmt::join(powers, "\n"));
}