Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
bctoolbox
Commits
51e8bd01
Commit
51e8bd01
authored
Feb 15, 2016
by
johan
Browse files
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
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
567 additions
and
1 deletion
+567
-1
include/bctoolbox/crypto.h
include/bctoolbox/crypto.h
+140
-1
src/crypto_mbedtls.c
src/crypto_mbedtls.c
+214
-0
src/crypto_polarssl.c
src/crypto_polarssl.c
+213
-0
No files found.
include/bctoolbox/crypto.h
View file @
51e8bd01
...
...
@@ -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
...
...
src/crypto_mbedtls.c
View file @
51e8bd01
...
...
@@ -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
);
}
src/crypto_polarssl.c
View file @
51e8bd01
...
...
@@ -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
));