Hello.
I know that the documentation says that RSA encrypt and decrypt functions are not working, but well, I see that the examples directory has the files rsa-encrypt.c and rsa-decrypt.c, and they seem to work (I compiled and tested them).
So, I don't really want to do the traditional RSA encryption where an AES (or other cypher) key is encrypted with RSA, and the text is encrypted with the AES key. Suppose I have a list of symmetric cypher keys (possibly for different algorithms, or diferent lengths). I'd then use the the rsa_encrypt and rsa_decrypt functions defined in rsa.h on each of the keys.
I have tried to make that work but rsa-decrypt complains that it can't decrypt the message, and I can't tell exactly how (the rsa-decrypt code may return zero in 4 different situations). Maybe it could set some error variable (like errno) to tell the user what went wrong?
BTW, I'm including the programs I was trying to use. The two functions are supposed to encrypt and decrypt a short message (which will actually be a symmetric cypher key). The encrypted message is returned in base64 from __cryptengine_nettle_asym_enc, so it can be stored in C++ strings and written to newline-separated files. Similarly, __cryptengine_nettle_asym_dec decodes a base64 string and then tries to decrypt the result. Encrypting doesn't give me any errors, but decrypting fails.
Is there something obviously wrong in this?
J.
PS: the two functions:
#include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <nettle/aes.h> #include <nettle/base64.h> #include <nettle/cbc.h> #include <gmp.h> #include <nettle/bignum.h> #include <nettle/rsa.h> #include <nettle/yarrow.h>
char * __cryptengine_nettle_asym_enc (const char *text, const char *pubk, const long size, const int keysize) {
uint8_t random_data[20]; int file_desc=open("/dev/random",O_RDONLY); read (file_desc,random_data,20); close (file_desc); struct yarrow256_ctx yarrow; struct rsa_public_key key; mpz_t x;
rsa_public_key_init(&key); if (!rsa_keypair_from_sexp(&key, NULL, 0, keysize, (uint8_t *) pubk)) { return NULL; }
yarrow256_init(&yarrow, 0, NULL); yarrow256_seed(&yarrow, 20, random_data);
yarrow256_random(&yarrow, size, (uint8_t *)text);
mpz_init(x);
if (!rsa_encrypt(&key, &yarrow, (nettle_random_func) yarrow256_random, size, (uint8_t *)text, x)) { fprintf(stderr,"RSA_ENCRYPT FAILED for size %d\n",size); return NULL; }; fprintf(stderr,"RSA_ENCRYPT SUCEEDED for size %d\n",size);
rsa_public_key_clear(&key);
int new_size = nettle_mpz_sizeinbase_256_u (x); char * pre_result = (char *) malloc (new_size * sizeof(char)); nettle_mpz_get_str_256(new_size, pre_result, x);
// // Encode using base64: //
int encoded_size = BASE64_ENCODE_LENGTH(new_size); uint8_t * result = (uint8_t *) calloc (encoded_size, sizeof(uint8_t));
struct base64_encode_ctx b64_ctx; base64_encode_init(&b64_ctx);
int done = base64_encode_update(&b64_ctx, result, new_size, pre_result); done += base64_encode_final(&b64_ctx, result);
result = (uint8_t *) realloc (result, done + 1); result[done] = '\0'; free (pre_result); return result; }
char * __cryptengine_nettle_asym_dec (const char *text, const char *prik, const long size, const int keysize) {
// // Decode from base64: //
unsigned decoded_size = BASE64_DECODE_LENGTH(size); uint8_t * decoded_text = (uint8_t *) calloc (decoded_size, sizeof(uint8_t));
struct base64_decode_ctx b64_ctx; base64_decode_init(&b64_ctx); int done = base64_decode_update(&b64_ctx, &decoded_size, decoded_text, size, (uint8_t *)text); base64_decode_final(&b64_ctx);
char * result = (char *) malloc (decoded_size * sizeof(char));
mpz_t x; struct rsa_private_key key; rsa_private_key_init(&key);
if (!rsa_keypair_from_sexp(NULL, &key, 0, keysize, (uint8_t *) prik)) { fprintf(stderr,"Can't read private key\n"); return NULL; };
nettle_mpz_init_set_str_256_u(x, decoded_size, decoded_text); nettle_mpz_set_str_256_u(x, decoded_size, decoded_text);
unsigned length = decoded_size; int res; if (! (res = rsa_decrypt(&key, &length, result, x)) || length != decoded_size) { fprintf(stderr,"Can't decrypt. res = %d, length = %d, dec_size = %d\n",res,length,decoded_size); return NULL; }
return result; }