MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED - c

im trying to code a Diffie-Hellman key Exchange (client side) into a XMC4500 and I'm using ARMmbed lib.
This is the code I got (based on dh_client.c):
int dhm (void)
{
int ret;
size_t n, buflen;
unsigned char *p, *end;
unsigned char buf[512];
unsigned char hash[32];
const char *pers = "dh_client";
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_rsa_context rsa;
mbedtls_dhm_context dhm;
mbedtls_aes_context aes;
mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA256 );
mbedtls_dhm_init( &dhm );
mbedtls_aes_init( &aes );
mbedtls_ctr_drbg_init( &ctr_drbg );
/*
* 1. Setup the RNG
*/
mbedtls_entropy_init( &entropy );
ret = mbedtls_ctr_drbg_seed( &ctr_drbg,
mbedtls_entropy_func,
&entropy,
(const unsigned char *) pers,
strlen( pers ) );
mbedtls_aes_free( &aes );
mbedtls_rsa_free( &rsa );
mbedtls_dhm_free( &dhm );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );
return ret;}
I did not try to go further this, because it is not working and it is the very beginning of dhm algorithm. The function mbedtls_ctr_drbg_seed is returning MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED.
Also in the ctr_drbg.h I had to edit the MBEDTLS_CTR_DRBG_MAX_SEED_INPUT from 384(default) to 336, otherwise the code would crash. Everything else is default.
Someone knows why is returning this error?
Thanks in advance.
Note: Im calling this function in main. Running the code gives me no errors.

This error is returned when your entropy function(mbedtls_entropy_func) fails. Do you have an entropy source enabled? You probably don't have any strong entropy source configured in your platform, thus causing this failure.

Related

In C code using OpenSSL 3, how do you convert DES_crypt to use EVP APIs?

As stated in OpenSSL 3, DES_crypt macro is deprecated.
We are encouraged to use the sequence EVP_EncryptInit_ex(3), EVP_EncryptUpdate(3) and EVP_EncryptFinal_ex(3) as stated here:
https://www.openssl.org/docs/manmaster/man3/DES_crypt.html
However, it doesn't state where the old parameters are going to be placed.
Where is the "buf" and "salt" going on which EVP API? Which is the *In, Key, IV value on the EVP APIs?
Which cipher should I use?
Sample of our old code:
char* theDESCrypt (const char *myBuf, const char *mySalt)
{
// some code here
// ...
return DES_crypt(myBuf, mySalt);
}
This is what I tried to use. Is the placement of buffer and salt correct on this one?
char* theDESCrypt (const char *myBuf, const char *mySalt)
{
int myRetLen = 0;
int myRetLenFinal = 0;
unsigned char *myRet = malloc(strlen(myBuf) + 1);
/* fetch cipher */
EVP_CIPHER *des_cipher = EVP_CIPHER_fetch(NULL, "DES", NULL);
/* setup context */
EVP_CIPHER_CTX *p_Ctx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(p_Ctx);
/* encrypt data */
EVP_EncryptInit_ex2(p_Ctx, des_cipher, NULL, mySalt, NULL);
EVP_EncryptUpdate(p_Ctx, myRet, &myRetLen, (unsigned char*)myBuf, strlen(myBuf)+1);
EVP_EncryptFinal_ex(p_Ctx, &myRet[myRetLen], &myRetLenFinal);
/* cleanup contexts*/
EVP_CIPHER_free(des_cipher);
EVP_CIPHER_CTX_free(p_Ctx);
return myBuf;
}
I tried using the above code and it fails our unit tests so I'm not sure if my changes are correct.

How can a callback function be executed within a driver on linux?

I have to modify a driver that runs on linux to add a callback function that is invoked from an external application. I already have the code implemented but when it is executed when the computer starts up, the system gives an error and is blocked.
This is my new code on the driver side:
typedef void (*callbackFunctionNoParams) ();
typedef struct T_EXI_CONFIGURE_BUS_
{
T_mode mode;
unsigned short NumeroRT;
T_SA_Enable SA_Enable;
unsigned short MINOR_CYCLE;
callbackFunctionNoParams callback;
} T_EXI_CONFIGURE_BUS;
typedef struct PciExiDev_
{
/**
* It represents a char device to read/write
*/
struct cdev charDevice;
/**
* IRQ assigned
*/
unsigned int irq;
/**
* Callback function to be invoked
*/
callbackFunctionNoParams callback;
/**
* Device control block
*/
EXI_DCB theDCB;
} PciExiDev;
Execution code on driver side:
static long exi_ioctl( struct file * filep, unsigned int cmd, unsigned long arg )
{
PciExiDev * aPciExiDev = (PciExiDev *) filep->private_data;
int result = SUCCESS;
int i, j;
long ret = 0;
//printk("Ioctl received %d.\n",cmd);
switch( cmd )
{
case FIO_EXI_CONFIGURE_BUS:
{
T_EXI_CONFIGURE_BUS config;
T_LISTA_TRANS *auxTrans1, *auxTrans2;
T_TRANSACTION_DCB *transDCB1;
T_OPI opi;
T_EXIS exis;
unsigned short dato;
unsigned short datolong[2];
unsigned short ControlBlock[12];
// printk("Exi configure bus initiated.\n");
printk("TNB. Exi ioctl CONFIGURE BUS.\n");
copy_from_user( &config, (T_EXI_CONFIGURE_BUS *) arg, sizeof(T_EXI_CONFIGURE_BUS) );
LeerDatos( &aPciExiDev->theDCB, OPI_ADDRESS, 1, (unsigned short *) &opi, 1 );
aPciExiDev->callback = config.callback;
aPciExiDev->theDCB.modo = config.mode;
aPciExiDev->theDCB.CicloMenor = config.MINOR_CYCLE;
(*aPciExiDev->callback)();
...
New code on client side:
if( theHWConfiguration.existExi() )
{
T_EXI_CONFIGURE_BUS bus_config;
// Configura la tarjega exi en modo Bus Controller.
bus_config.mode = BC;
bus_config.NumeroRT = 28;
bus_config.MINOR_CYCLE = 20;
bus_config.callback = &bcInterruptHandler2;
status = ioctl( A_fd_exi, FIO_EXI_CONFIGURE_BUS, reinterpret_cast<long>( &bus_config ) );
}
return status;
}
void C_EXI::bcInterruptHandler2()
{
std::cout<< "bcInterruptHandler2" << endl;
}
And this is the execution code result:
Crash Image
If someone could help me or propose an alternative way of doing this I would be very grateful.
Your callback is bound to run at kernel space and then you write it to std::cout. While going through your code, it tells that there is a conflict between kernel mode address space and userside process address space. This means that if the callback function is declared in the userside but instead called in the kernel space, there would be an error.
The crash image suggests that somewhere in your code you have an invalid pointer that you are trying to access. I am afraid I cannot debug your code with the little context provided, but I can give you some suggestions:
Try to avoid casting until is strictly necessary.
When you are casting to a pointer, double-check that this is exactly what you need to do.
In the error message there is also the call stack: take a look at it in order to identify where is the error.
You can simply add some printk("%p", pointer) in your code to debug the content of your variables.

mbedtls: error on mbedtls_ctr_drbg_seed

I'm using mbedtls to run SSL server.
The function mbedtls_ctr_drbg_seed returned -34.
My code is below:
const char *pers = "ssl_server2";
mbedtls_havege_state hs;
mbedtls_ssl_session ssn;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
// One HTTPS Request Handling
memset( &ssn, 0, sizeof( mbedtls_ssl_session ) );
/*
* 4. Setup stuff
*/
mbedtls_ssl_init( &ssl );
mbedtls_ssl_config_init( &conf );
mbedtls_ctr_drbg_init( &ctr_drbg );
mbedtls_entropy_init( &entropy );
printf( " . Setting up the RNG and SSL data...." );
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, sizeof( pers ) ) ) != 0 )
{
printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret );
goto ExitFunction;
}
else
printf( " mbedtls_ctr_drbg_seed returned 0x%x ok\n", ret );
As #Gilles rightfully said, the error you are receiving is probably -0x34, which is MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED. This error is returned when the function mbedtls_entropy_func() fails. Please check the the entropy source you are using is strong enough, meaning you have at least one entropy source which is strong, when added with mbedtls_entropy_add_source(). You should also verify that the entropy source you are using can collect enough entropy, and exceeds the threshold set to the source.
There are other locations where mbedtls_entropy_func() might fail, therefore I suggest you check these locations as well.

ffmpeg, 'protocol not found' error

i'm using next code:
const char *sFileOutput;
AVOutputFormat *ofmt;
AVFormatContext *ofcx;
int main( int argc, char* argv[] )
{
av_log_set_level( AV_LOG_DEBUG );
av_register_all();
avcodec_register_all();
avformat_network_init();
char s1[40]={0};
const time_t timer = time(NULL);
u = localtime(&timer);
strftime(s1, 40, "%d.%m.%Y-%H:%M:%S.avi", u);
sFileOutput=&s1;
//char *sFileOutput = "01.01.2017-23.23.23.avi";
ofmt = av_guess_format( NULL, sFileOutput, NULL );
ofcx = avformat_alloc_context();
ofcx->oformat = ofmt;
int ret2=avio_open( &ofcx->pb, sFileOutput, AVIO_FLAG_WRITE);
if(ret2<0){
fprintf(stderr, "\nError occurred when opening output file: %s\n",av_err2str(ret2));
}
}
When i run it, i have error in console:
Error occurred when opening output file: Protocol not found
but if i uncomment string
char *sFileOutput = "01.01.2017-23.23.23.avi";
evirything is ok, progam is working without errors. please tell me what is wrong.
thank you for your answer, it helps me too.
But real problem was that generated name contained ':'. i changed string to
strftime(s1, 40, "%d.%m.%Y-%H.%M.%S.avi", u);
and it works well.
When you do:
sFileOutput=&s1
&s1 creates a pointer of type char (*)[40] and not a pointer to the first element of the array like you expect. You are passing around a pointer to the entire array which gets converted to an incompatible type. Check the compilation warnings/errors.
The solution is to use either the implicit conversion:
sFileOutput=s1
or:
sFileOutput=&s1[0]

Compile Lua script to unsigned char buffer

Im working on a server in C that dynamically generating Lua commands on the fly and send them by socket to the clients. Right now the server is using plain text, but I would like the server to pre-compile the script before sending it to the clients.
I check luac.c but couldn't find how to be able to do something like this:
char lua_commands[ 1024 ] = { "a = 123; b = 456; c = a + b;" };
int socket
unsigned int send_buffer_size
unsigned char *send_buffer
/* Compile lua_commands and store the binary script into send_buffer without
having to write first the .out on disk then read it again in order store the content
into send_buffer */
send( socket, send_buffer, send_buffer_size, 0 );
Anybody can help me to achieve this?
[ Update ]
Ok, I think I figure it out:
#include "lua.h"
#include "lauxlib.h"
#include "ldo.h"
#include "lfunc.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstring.h"
#include "lundump.h"
#define toproto(L,i) (clvalue(L->top+(i))->l.p)
static int writer( lua_State *L, const void *p, size_t size, void *u ){
unsigned int i = 0;
unsigned char *d = ( unsigned char * )p;
// Print all the bytes on the console.
while( i != size ) {
printf("%d ", d[ i ] );
++i;
}
return 0;
}
void compile( lua_State *L, char *command ){
const Proto* f;
if (luaL_loadstring( L, command ) !=0 ) {
printf( "%s\n", lua_tostring( L, -1 ) );
}
f = toproto( L,-1 );
lua_lock( L );
luaU_dump( L, f, writer, NULL, 1 );
lua_unlock( L );
}
int main (int argc, const char * argv[]) {
lua_State *L = lua_open();
compile( L, "a = 123; b = 456; c = a + b; print( c );" );
lua_close( L );
return 0;
}
However that leads me to another question, do I have to close and reopen (lua_open, lua_close) the Lua state every time I'm calling my compile() function with other Lua commands or the output will only be the result of the latest luaL_loadstring?
Im not sure but look to me from the toproto macro definition that the top most stack will be returned am I correct?
You should use lua_dump() instead of internal toproto() + luaU_dump() functions. As an added bonus, this way your code will support LuaJIT 2.
It is not necessary to recreate the state each time you get the dump.
BUT. I would avoid executing Lua bytecode that came from the untrusted source (and server often is untrusted to the client). It is not safe, and may lead to severe security issues. (No such problems with source code — but you still have to sandbox it, of course.)
In general, always make sure that you check that the code you load from untrusted source is not bytecode (it is, if first byte is 27 decimal). Always execute such code in a sandbox.
If all that you need is to pass data in Lua-friendly way, pick some proper data serialization library instead. Aside of sandboxing and portability problems, loadstring() is rather slow.
For example, we're using using my luatexts library for similar purposes (make sure to pore through this list for alternatives). Luatexts supports tuples, which plays nicely with function calls. For example (in pseudocode):
Server:
my_send(luatexts.lua.save("myMethod", { param = true }, 42))
Client:
local actions = { }
function actions.myMethod(params, number)
print(params.param, number) --> true, 42
end
local function handle_action(ok, name, ...)
assert(ok, name) -- name would contain error message if not OK
local handler = assert(actions[name], "unknown action")
return handler(...)
end
local str = my_receive()
handle_action(luatexts.load(str))
Open a ticket if you want luatexts.save or streaming support implemented in C.

Resources