Commit 51e8bd01 authored by johan's avatar johan

Add AES128/256 CFB mode and DHM 2048 and 3072 needed for ZRTP

Available settings for these algorithms are limited to the one
requested by ZRTP.
parent 1d12ff45
......@@ -27,6 +27,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define BCTOOLBOX_PUBLIC
#endif
/* DHM settings defines */
#define BCTOOLBOX_DHM_UNSET 0
#define BCTOOLBOX_DHM_2048 1
#define BCTOOLBOX_DHM_3072 2
/* SSL settings defines */
#define BCTOOLBOX_SSL_UNSET -1
......@@ -318,6 +323,71 @@ BCTOOLBOX_PUBLIC int32_t bctoolbox_ssl_get_dtls_srtp_key_material(bctoolbox_ssl_
BCTOOLBOX_PUBLIC uint8_t bctoolbox_dtls_srtp_supported(void);
/*****************************************************************************/
/***** Diffie-Hellman-Merkle key exchange *****/
/*****************************************************************************/
/**
* @brief Context for the Diffie-Hellman-Merkle key exchange
* Use RFC3526 values for G and P
*/
typedef struct bctoolbox_DHMContext_struct {
uint8_t algo; /**< Algorithm used for the key exchange mapped to an int: BCTOOLBOX_DHM_2048, BCTOOLBOX_DHM_3072 */
uint16_t primeLength; /**< Prime number length in bytes(256 or 384)*/
uint8_t *secret; /**< the random secret (X), this field may not be used if the crypto module implementation already store this value in his context */
uint8_t secretLength; /**< in bytes */
uint8_t *key; /**< the key exchanged (G^Y)^X mod P */
uint8_t *self; /**< this side of the public exchange G^X mod P */
uint8_t *peer; /**< the other side of the public exchange G^Y mod P */
void *cryptoModuleData; /**< a context needed by the crypto implementation */
}bctoolbox_DHMContext_t;
/**
*
* @brief Create a context for the DHM key exchange
* This function will also instantiate the context needed by the actual implementation of the crypto module
*
* @param[in] DHMAlgo The algorithm type(BCTOOLBOX_DHM_2048 or BCTOOLBOX_DHM_3072)
* @param[in] secretLength The length in byte of the random secret(X).
*
* @return The initialised context for the DHM calculation(must then be freed calling the destroyDHMContext function), NULL on error
*
*/
BCTOOLBOX_PUBLIC bctoolbox_DHMContext_t *bctoolbox_CreateDHMContext(uint8_t DHMAlgo, uint8_t secretLength);
/**
*
* @brief Generate the private secret X and compute the public value G^X mod P
* G, P and X length have been set by previous call to DHM_CreateDHMContext
*
* @param[in/out] context DHM context, will store the public value in ->self after this call
* @param[in] rngFunction pointer to a random number generator used to create the secret X
* @param[in] rngContext pointer to the rng context if neeeded
*
*/
BCTOOLBOX_PUBLIC void bctoolbox_DHMCreatePublic(bctoolbox_DHMContext_t *context, int (*rngFunction)(void *, uint8_t *, size_t), void *rngContext);
/**
*
* @brief Compute the secret key G^X^Y mod p
* G^X mod P has been computed in previous call to DHMCreatePublic
* G^Y mod P must have been set in context->peer
*
* @param[in/out] context Read the public values from context, export the key to context->key
* @param[in] rngFunction Pointer to a random number generation function, used for blinding countermeasure, may be NULL
* @param[in] rngContext Pointer to the RNG function context
*
*/
BCTOOLBOX_PUBLIC void bctoolbox_DHMComputeSecret(bctoolbox_DHMContext_t *context, int (*rngFunction)(void *, uint8_t *, size_t), void *rngContext);
/**
*
* @brief Clean DHM context
*
* @param context The context to deallocate
*
*/
BCTOOLBOX_PUBLIC void bctoolbox_DestroyDHMContext(bctoolbox_DHMContext_t *context);
/*****************************************************************************/
/***** Hashing *****/
/*****************************************************************************/
......@@ -424,7 +494,7 @@ BCTOOLBOX_PUBLIC int32_t bctoolbox_aes_gcm_encrypt_and_tag(const uint8_t *key, s
* @param[in] tagLength Length in bytes for the authentication tag
* @param[out] output Buffer holding the output, shall be at least the length of cipherText buffer
*
* @return 0 on succes, BCTOOLBOX_ERROR_AUTHENTICATION_FAILED if tag doesn't match or polarssl error code
* @return 0 on succes, BCTOOLBOX_ERROR_AUTHENTICATION_FAILED if tag doesn't match or crypto library error code
*/
BCTOOLBOX_PUBLIC int32_t bctoolbox_aes_gcm_decrypt_and_auth(const uint8_t *key, size_t keyLength,
const uint8_t *cipherText, size_t cipherTextLength,
......@@ -477,6 +547,75 @@ BCTOOLBOX_PUBLIC int32_t bctoolbox_aes_gcm_process_chunk(bctoolbox_aes_gcm_conte
BCTOOLBOX_PUBLIC int32_t bctoolbox_aes_gcm_finish(bctoolbox_aes_gcm_context_t *context,
uint8_t *tag, size_t tagLength);
/**
* @brief Wrapper for AES-128 in CFB128 mode encryption
* Both key and IV must be 16 bytes long
*
* @param[in] key encryption key, 128 bits long
* @param[in] IV Initialisation vector, 128 bits long, is not modified by this function.
* @param[in] input Input data buffer
* @param[in] inputLength Input data length
* @param[out] output Output data buffer
*
*/
BCTOOLBOX_PUBLIC void bctoolbox_aes128CfbEncrypt(const uint8_t *key,
const uint8_t *IV,
const uint8_t *input,
size_t inputLength,
uint8_t *output);
/**
* @brief Wrapper for AES-128 in CFB128 mode decryption
* Both key and IV must be 16 bytes long
*
* @param[in] key decryption key, 128 bits long
* @param[in] IV Initialisation vector, 128 bits long, is not modified by this function.
* @param[in] input Input data buffer
* @param[in] inputLength Input data length
* @param[out] output Output data buffer
*
*/
BCTOOLBOX_PUBLIC void bctoolbox_aes128CfbDecrypt(const uint8_t *key,
const uint8_t *IV,
const uint8_t *input,
size_t inputLength,
uint8_t *output);
/**
* @brief Wrapper for AES-256 in CFB128 mode encryption
* The key must be 32 bytes long and the IV must be 16 bytes long
*
* @param[in] key encryption key, 256 bits long
* @param[in] IV Initialisation vector, 128 bits long, is not modified by this function.
* @param[in] input Input data buffer
* @param[in] inputLength Input data length
* @param[out] output Output data buffer
*
*/
BCTOOLBOX_PUBLIC void bctoolbox_aes256CfbEncrypt(const uint8_t *key,
const uint8_t *IV,
const uint8_t *input,
size_t inputLength,
uint8_t *output);
/**
* @brief Wrapper for AES-256 in CFB128 mode decryption
* The key must be 32 bytes long and the IV must be 16 bytes long
*
* @param[in] key decryption key, 256 bits long
* @param[in] IV Initialisation vector, 128 bits long, is not modified by this function.
* @param[in] input Input data buffer
* @param[in] inputLength Input data length
* @param[out] output Output data buffer
*
*/
BCTOOLBOX_PUBLIC void bctoolbox_aes256CfbDecrypt(const uint8_t *key,
const uint8_t *IV,
const uint8_t *input,
size_t inputLength,
uint8_t *output);
#ifdef __cplusplus
}
#endif
......
......@@ -680,6 +680,98 @@ int32_t bctoolbox_x509_certificate_unset_flag(uint32_t *flags, uint32_t flags_to
return 0;
}
/*** Diffie-Hellman-Merkle ***/
/* initialise de DHM context according to requested algorithm */
bctoolbox_DHMContext_t *bctoolbox_CreateDHMContext(uint8_t DHMAlgo, uint8_t secretLength)
{
mbedtls_dhm_context *mbedtlsDhmContext;
/* create the context */
bctoolbox_DHMContext_t *context = (bctoolbox_DHMContext_t *)malloc(sizeof(bctoolbox_DHMContext_t));
memset (context, 0, sizeof(bctoolbox_DHMContext_t));
/* create the mbedtls context for DHM */
mbedtlsDhmContext=(mbedtls_dhm_context *)malloc(sizeof(mbedtls_dhm_context));
memset(mbedtlsDhmContext, 0, sizeof(mbedtls_dhm_context));
context->cryptoModuleData=(void *)mbedtlsDhmContext;
/* initialise pointer to NULL to ensure safe call to free() when destroying context */
context->secret = NULL;
context->self = NULL;
context->key = NULL;
context->peer = NULL;
/* set parameters in the context */
context->algo=DHMAlgo;
context->secretLength = secretLength;
switch (DHMAlgo) {
case BCTOOLBOX_DHM_2048:
/* set P and G in the mbedtls context */
if ((mbedtls_mpi_read_string(&(mbedtlsDhmContext->P), 16, MBEDTLS_DHM_RFC3526_MODP_2048_P) != 0) ||
(mbedtls_mpi_read_string(&(mbedtlsDhmContext->G), 16, MBEDTLS_DHM_RFC3526_MODP_2048_G) != 0)) {
return NULL;
}
context->primeLength=256;
mbedtlsDhmContext->len=256;
break;
case BCTOOLBOX_DHM_3072:
/* set P and G in the mbedtls context */
if ((mbedtls_mpi_read_string(&(mbedtlsDhmContext->P), 16, MBEDTLS_DHM_RFC3526_MODP_3072_P) != 0) ||
(mbedtls_mpi_read_string(&(mbedtlsDhmContext->G), 16, MBEDTLS_DHM_RFC3526_MODP_3072_G) != 0)) {
return NULL;
}
context->primeLength=384;
mbedtlsDhmContext->len=384;
break;
default:
free(context);
return NULL;
break;
}
return context;
}
/* generate the random secret and compute the public value */
void bctoolbox_DHMCreatePublic(bctoolbox_DHMContext_t *context, int (*rngFunction)(void *, uint8_t *, size_t), void *rngContext) {
/* get the mbedtls context */
mbedtls_dhm_context *mbedtlsContext = (mbedtls_dhm_context *)context->cryptoModuleData;
/* allocate output buffer */
context->self = (uint8_t *)malloc(context->primeLength*sizeof(uint8_t));
mbedtls_dhm_make_public(mbedtlsContext, context->secretLength, context->self, context->primeLength, (int (*)(void *, unsigned char *, size_t))rngFunction, rngContext);
}
/* compute secret - the ->peer field of context must have been set before calling this function */
void bctoolbox_DHMComputeSecret(bctoolbox_DHMContext_t *context, int (*rngFunction)(void *, uint8_t *, size_t), void *rngContext) {
size_t keyLength;
/* import the peer public value G^Y mod P in the mbedtls dhm context */
mbedtls_dhm_read_public((mbedtls_dhm_context *)(context->cryptoModuleData), context->peer, context->primeLength);
/* compute the secret key */
keyLength = context->primeLength; /* undocumented but this value seems to be in/out, so we must set it to the expected key length */
context->key = (uint8_t *)malloc(keyLength*sizeof(uint8_t)); /* allocate key buffer */
mbedtls_dhm_calc_secret((mbedtls_dhm_context *)(context->cryptoModuleData), context->key, keyLength*sizeof(uint8_t), &keyLength, (int (*)(void *, unsigned char *, size_t))rngFunction, rngContext);
}
/* clean DHM context */
void bctoolbox_DestroyDHMContext(bctoolbox_DHMContext_t *context) {
if (context!= NULL) {
free(context->secret);
free(context->self);
free(context->key);
free(context->peer);
mbedtls_dhm_free((mbedtls_dhm_context *)context->cryptoModuleData);
free(context->cryptoModuleData);
free(context);
}
}
/*** SSL Client ***/
/*
* Default profile used to configure ssl_context, allow 1024 bits keys(while mbedtls default is 2048)
......@@ -1458,3 +1550,125 @@ int32_t bctoolbox_aes_gcm_finish(bctoolbox_aes_gcm_context_t *context,
return ret;
}
/*
* @brief Wrapper for AES-128 in CFB128 mode encryption
* Both key and IV must be 16 bytes long, IV is not updated
*
* @param[in] key encryption key, 128 bits long
* @param[in] IV Initialisation vector, 128 bits long, is not modified by this function.
* @param[in] input Input data buffer
* @param[in] inputLength Input data length
* @param[out] output Output data buffer
*
*/
void bctoolbox_aes128CfbEncrypt(const uint8_t key[16],
const uint8_t IV[16],
const uint8_t *input,
size_t inputLength,
uint8_t *output)
{
uint8_t IVbuffer[16];
size_t iv_offset=0; /* is not used by us but needed and updated by mbedtls */
mbedtls_aes_context context;
memset (&context, 0, sizeof(mbedtls_aes_context));
/* make a local copy of IV which is modified by the mbedtls AES-CFB function */
memcpy(IVbuffer, IV, 16*sizeof(uint8_t));
/* initialise the aes context and key */
mbedtls_aes_setkey_enc(&context, key, 128);
/* encrypt */
mbedtls_aes_crypt_cfb128 (&context, MBEDTLS_AES_ENCRYPT, inputLength, &iv_offset, IVbuffer, input, output);
}
/*
* @brief Wrapper for AES-128 in CFB128 mode decryption
* Both key and IV must be 16 bytes long, IV is not updated
*
* @param[in] key decryption key, 128 bits long
* @param[in] IV Initialisation vector, 128 bits long, is not modified by this function.
* @param[in] input Input data buffer
* @param[in] inputLength Input data length
* @param[out] output Output data buffer
*
*/
void bctoolbox_aes128CfbDecrypt(const uint8_t key[16],
const uint8_t IV[16],
const uint8_t *input,
size_t inputLength,
uint8_t *output)
{
uint8_t IVbuffer[16];
size_t iv_offset=0; /* is not used by us but needed and updated by mbedtls */
mbedtls_aes_context context;
memset (&context, 0, sizeof(mbedtls_aes_context));
/* make a local copy of IV which is modified by the mbedtls AES-CFB function */
memcpy(IVbuffer, IV, 16*sizeof(uint8_t));
/* initialise the aes context and key - use the aes_setkey_enc function as requested by the documentation of aes_crypt_cfb128 function */
mbedtls_aes_setkey_enc(&context, key, 128);
/* encrypt */
mbedtls_aes_crypt_cfb128 (&context, MBEDTLS_AES_DECRYPT, inputLength, &iv_offset, IVbuffer, input, output);
}
/*
* @brief Wrapper for AES-256 in CFB128 mode encryption
* The key must be 32 bytes long and the IV must be 16 bytes long, IV is not updated
*
* @param[in] key encryption key, 256 bits long
* @param[in] IV Initialisation vector, 128 bits long, is not modified by this function.
* @param[in] input Input data buffer
* @param[in] inputLength Input data length
* @param[out] output Output data buffer
*
*/
void bctoolbox_aes256CfbEncrypt(const uint8_t key[32],
const uint8_t IV[16],
const uint8_t *input,
size_t inputLength,
uint8_t *output)
{
uint8_t IVbuffer[16];
size_t iv_offset=0;
mbedtls_aes_context context;
memcpy(IVbuffer, IV, 16*sizeof(uint8_t));
memset (&context, 0, sizeof(mbedtls_aes_context));
mbedtls_aes_setkey_enc(&context, key, 256);
/* encrypt */
mbedtls_aes_crypt_cfb128 (&context, MBEDTLS_AES_ENCRYPT, inputLength, &iv_offset, IVbuffer, input, output);
}
/*
* @brief Wrapper for AES-256 in CFB128 mode decryption
* The key must be 32 bytes long and the IV must be 16 bytes long, IV is not updated
*
* @param[in] key decryption key, 256 bits long
* @param[in] IV Initialisation vector, 128 bits long, is not modified by this function.
* @param[in] input Input data buffer
* @param[in] inputLength Input data length
* @param[out] output Output data buffer
*
*/
void bctoolbox_aes256CfbDecrypt(const uint8_t key[32],
const uint8_t IV[16],
const uint8_t *input,
size_t inputLength,
uint8_t *output)
{
uint8_t IVbuffer[16];
size_t iv_offset=0;
mbedtls_aes_context context;
memcpy(IVbuffer, IV, 16*sizeof(uint8_t));
memset (&context, 0, sizeof(mbedtls_aes_context));
mbedtls_aes_setkey_enc(&context, key, 256);
/* decrypt */
mbedtls_aes_crypt_cfb128 (&context, MBEDTLS_AES_DECRYPT, inputLength, &iv_offset, IVbuffer, input, output);
}
......@@ -555,6 +555,97 @@ int32_t bctoolbox_x509_certificate_unset_flag(uint32_t *flags, uint32_t flags_to
return 0;
}
/*** Diffie-Hellman-Merkle ***/
/* initialise de DHM context according to requested algorithm */
bctoolbox_DHMContext_t *bctoolbox_CreateDHMContext(uint8_t DHMAlgo, uint8_t secretLength)
{
dhm_context *polarsslDhmContext;
/* create the context */
bctoolbox_DHMContext_t *context = (bctoolbox_DHMContext_t *)malloc(sizeof(bctoolbox_DHMContext_t));
memset (context, 0, sizeof(bctoolbox_DHMContext_t));
/* create the polarssl context for DHM */
polarsslDhmContext=(dhm_context *)malloc(sizeof(dhm_context));
memset(polarsslDhmContext, 0, sizeof(dhm_context));
context->cryptoModuleData=(void *)polarsslDhmContext;
/* initialise pointer to NULL to ensure safe call to free() when destroying context */
context->secret = NULL;
context->self = NULL;
context->key = NULL;
context->peer = NULL;
/* set parameters in the context */
context->algo=DHMAlgo;
context->secretLength = secretLength;
switch (DHMAlgo) {
case BCTOOLBOX_DHM_2048:
/* set P and G in the polarssl context */
if ((mpi_read_string(&(polarsslDhmContext->P), 16, POLARSSL_DHM_RFC3526_MODP_2048_P) != 0) ||
(mpi_read_string(&(polarsslDhmContext->G), 16, POLARSSL_DHM_RFC3526_MODP_2048_G) != 0)) {
return NULL;
}
context->primeLength=256;
polarsslDhmContext->len=256;
break;
case BCTOOLBOX_DHM_3072:
/* set P and G in the polarssl context */
if ((mpi_read_string(&(polarsslDhmContext->P), 16, POLARSSL_DHM_RFC3526_MODP_3072_P) != 0) ||
(mpi_read_string(&(polarsslDhmContext->G), 16, POLARSSL_DHM_RFC3526_MODP_3072_G) != 0)) {
return NULL;
}
context->primeLength=384;
polarsslDhmContext->len=384;
break;
default:
free(context);
return NULL;
break;
}
return context;
}
/* generate the random secret and compute the public value */
void bctoolbox_DHMCreatePublic(bctoolbox_DHMContext_t *context, int (*rngFunction)(void *, uint8_t *, size_t), void *rngContext) {
/* get the polarssl context */
dhm_context *polarsslContext = (dhm_context *)context->cryptoModuleData;
/* allocate output buffer */
context->self = (uint8_t *)malloc(context->primeLength*sizeof(uint8_t));
dhm_make_public(polarsslContext, context->secretLength, context->self, context->primeLength, (int (*)(void *, unsigned char *, size_t))rngFunction, rngContext);
}
/* compute secret - the ->peer field of context must have been set before calling this function */
void bctoolbox_DHMComputeSecret(bctoolbox_DHMContext_t *context, int (*rngFunction)(void *, uint8_t *, size_t), void *rngContext) {
size_t keyLength;
/* import the peer public value G^Y mod P in the polar ssl context */
dhm_read_public((dhm_context *)(context->cryptoModuleData), context->peer, context->primeLength);
/* compute the secret key */
keyLength = context->primeLength; /* undocumented but this value seems to be in/out, so we must set it to the expected key length */
context->key = (uint8_t *)malloc(keyLength*sizeof(uint8_t)); /* allocate key buffer */
dhm_calc_secret((dhm_context *)(context->cryptoModuleData), context->key, &keyLength, (int (*)(void *, unsigned char *, size_t))rngFunction, rngContext);
}
/* clean DHM context */
void bctoolbox_DestroyDHMContext(bctoolbox_DHMContext_t *context) {
if (context!= NULL) {
free(context->secret);
free(context->self);
free(context->key);
free(context->peer);
dhm_free((dhm_context *)context->cryptoModuleData);
free(context->cryptoModuleData);
free(context);
}
}
/*** SSL Client ***/
/** context **/
......@@ -1293,3 +1384,125 @@ int32_t bctoolbox_aes_gcm_finish(bctoolbox_aes_gcm_context_t *context,
return ret;
}
/*
* @brief Wrapper for AES-128 in CFB128 mode encryption
* Both key and IV must be 16 bytes long, IV is not updated
*
* @param[in] key encryption key, 128 bits long
* @param[in] IV Initialisation vector, 128 bits long, is not modified by this function.
* @param[in] input Input data buffer
* @param[in] inputLength Input data length
* @param[out] output Output data buffer
*
*/
void bctoolbox_aes128CfbEncrypt(const uint8_t key[16],
const uint8_t IV[16],
const uint8_t *input,
size_t inputLength,
uint8_t *output)
{
uint8_t IVbuffer[16];
size_t iv_offset=0; /* is not used by us but needed and updated by polarssl */
aes_context context;
memset (&context, 0, sizeof(aes_context));
/* make a local copy of IV which is modified by the polar ssl AES-CFB function */
memcpy(IVbuffer, IV, 16*sizeof(uint8_t));
/* initialise the aes context and key */
aes_setkey_enc(&context, key, 128);
/* encrypt */
aes_crypt_cfb128 (&context, AES_ENCRYPT, inputLength, &iv_offset, IVbuffer, input, output);
}
/*
* @brief Wrapper for AES-128 in CFB128 mode decryption
* Both key and IV must be 16 bytes long, IV is not updated
*
* @param[in] key decryption key, 128 bits long
* @param[in] IV Initialisation vector, 128 bits long, is not modified by this function.
* @param[in] input Input data buffer
* @param[in] inputLength Input data length
* @param[out] output Output data buffer
*
*/
void bctoolbox_aes128CfbDecrypt(const uint8_t key[16],
const uint8_t IV[16],
const uint8_t *input,
size_t inputLength,
uint8_t *output)
{
uint8_t IVbuffer[16];
size_t iv_offset=0; /* is not used by us but needed and updated by polarssl */
aes_context context;
memset (&context, 0, sizeof(aes_context));
/* make a local copy of IV which is modified by the polar ssl AES-CFB function */
memcpy(IVbuffer, IV, 16*sizeof(uint8_t));
/* initialise the aes context and key - use the aes_setkey_enc function as requested by the documentation of aes_crypt_cfb128 function */
aes_setkey_enc(&context, key, 128);
/* encrypt */
aes_crypt_cfb128 (&context, AES_DECRYPT, inputLength, &iv_offset, IVbuffer, input, output);
}
/*
* @brief Wrapper for AES-256 in CFB128 mode encryption
* The key must be 32 bytes long and the IV must be 16 bytes long, IV is not updated
*
* @param[in] key encryption key, 256 bits long
* @param[in] IV Initialisation vector, 128 bits long, is not modified by this function.
* @param[in] input Input data buffer
* @param[in] inputLength Input data length
* @param[out] output Output data buffer
*
*/
void bctoolbox_aes256CfbEncrypt(const uint8_t key[32],
const uint8_t IV[16],
const uint8_t *input,
size_t inputLength,
uint8_t *output)
{
uint8_t IVbuffer[16];
size_t iv_offset=0;
aes_context context;
memcpy(IVbuffer, IV, 16*sizeof(uint8_t));
memset (&context, 0, sizeof(aes_context));
aes_setkey_enc(&context, key, 256);
/* encrypt */
aes_crypt_cfb128 (&context, AES_ENCRYPT, inputLength, &iv_offset, IVbuffer, input, output);
}
/*
* @brief Wrapper for AES-256 in CFB128 mode decryption
* The key must be 32 bytes long and the IV must be 16 bytes long, IV is not updated
*
* @param[in] key decryption key, 256 bits long
* @param[in] IV Initialisation vector, 128 bits long, is not modified by this function.
* @param[in] input Input data buffer
* @param[in] inputLength Input data length
* @param[out] output Output data buffer
*
*/
void bctoolbox_aes256CfbDecrypt(const uint8_t key[32],
const uint8_t IV[16],
const uint8_t *input,
size_t inputLength,
uint8_t *output)
{
uint8_t IVbuffer[16];
size_t iv_offset=0;
aes_context context;
memcpy(IVbuffer, IV, 16*sizeof(uint8_t));
memset (&context, 0, sizeof(aes_context));
aes_setkey_enc(&context, key, 256);
/* decrypt */
aes_crypt_cfb128 (&context, AES_DECRYPT, inputLength, &iv_offset, IVbuffer, input, output);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment