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;
}