Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
bctoolbox
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
3
Merge Requests
3
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
External Wiki
External Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
BC
public
bctoolbox
Commits
81faf2e5
Commit
81faf2e5
authored
Sep 11, 2017
by
johan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enhance ECDH API
+fix memory leak in tests
parent
02caea7d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
151 additions
and
23 deletions
+151
-23
crypto.h
include/bctoolbox/crypto.h
+23
-2
ecc.c
src/crypto/ecc.c
+66
-11
crypto.c
tester/crypto.c
+62
-10
No files found.
include/bctoolbox/crypto.h
View file @
81faf2e5
...
...
@@ -597,7 +597,7 @@ typedef struct bctbx_ECDHContext_struct {
* @return The initialised context for the ECDH calculation(must then be freed calling the destroyECDHContext function), NULL on error
*
*/
BCTBX_PUBLIC
bctbx_ECDHContext_t
*
bctbx_CreateECDHContext
(
uint8_t
ECDHAlgo
);
BCTBX_PUBLIC
bctbx_ECDHContext_t
*
bctbx_CreateECDHContext
(
const
uint8_t
ECDHAlgo
);
/**
*
...
...
@@ -618,7 +618,28 @@ BCTBX_PUBLIC void bctbx_ECDHCreateKeyPair(bctbx_ECDHContext_t *context, int (*rn
* @param[in] secret The buffer holding the secret, is duplicated in the ECDH context
* @param[in] secretLength Length of previous buffer, must match the algo type setted at context creation
*/
BCTBX_PUBLIC
void
bctbx_ECDHSetSecretKey
(
bctbx_ECDHContext_t
*
context
,
uint8_t
*
secret
,
size_t
secretLength
);
BCTBX_PUBLIC
void
bctbx_ECDHSetSecretKey
(
bctbx_ECDHContext_t
*
context
,
const
uint8_t
*
secret
,
const
size_t
secretLength
);
/**
*
* @brief Set the given self public key in the ECDH context
* Warning: no check if it matches the private key value
*
* @param[in/out] context ECDH context, will store the given self public key if length is matching the pre-setted algo for this context
* @param[in] selfPublic The buffer holding the self public key, is duplicated in the ECDH context
* @param[in] selfPublicLength Length of previous buffer, must match the algo type setted at context creation
*/
BCTBX_PUBLIC
void
bctbx_ECDHSetSelfPublicKey
(
bctbx_ECDHContext_t
*
context
,
const
uint8_t
*
selfPublic
,
const
size_t
selfPublicLength
);
/**
*
* @brief Set the given peer public key in the ECDH context
*
* @param[in/out] context ECDH context, will store the given peer public key if length is matching the pre-setted algo for this context
* @param[in] peerPublic The buffer holding the peer public key, is duplicated in the ECDH context
* @param[in] peerPublicLength Length of previous buffer, must match the algo type setted at context creation
*/
BCTBX_PUBLIC
void
bctbx_ECDHSetPeerPublicKey
(
bctbx_ECDHContext_t
*
context
,
const
uint8_t
*
peerPublic
,
const
size_t
peerPublicLength
);
/**
*
...
...
src/crypto/ecc.c
View file @
81faf2e5
...
...
@@ -51,7 +51,7 @@ uint32_t bctbx_key_agreement_algo_list(void) {
/*****************************************************************************/
/* Create and initialise the ECDH Context */
bctbx_ECDHContext_t
*
bctbx_CreateECDHContext
(
uint8_t
ECDHAlgo
)
{
bctbx_ECDHContext_t
*
bctbx_CreateECDHContext
(
const
uint8_t
ECDHAlgo
)
{
/* create the context */
bctbx_ECDHContext_t
*
context
=
(
bctbx_ECDHContext_t
*
)
bctbx_malloc
(
sizeof
(
bctbx_ECDHContext_t
));
memset
(
context
,
0
,
sizeof
(
bctbx_ECDHContext_t
));
...
...
@@ -91,13 +91,52 @@ bctbx_ECDHContext_t *bctbx_CreateECDHContext(uint8_t ECDHAlgo) {
* @param[in] secret The buffer holding the secret, is duplicated in the ECDH context
* @param[in] secretLength Length of previous buffer, must match the algo type setted at context creation
*/
void
bctbx_ECDHSetSecretKey
(
bctbx_ECDHContext_t
*
context
,
uint8_t
*
secret
,
size_t
secretLength
)
{
void
bctbx_ECDHSetSecretKey
(
bctbx_ECDHContext_t
*
context
,
const
uint8_t
*
secret
,
const
size_t
secretLength
)
{
if
(
context
!=
NULL
&&
context
->
secretLength
==
secretLength
)
{
context
->
secret
=
(
uint8_t
*
)
bctbx_malloc
(
context
->
secretLength
);
if
(
context
->
secret
==
NULL
)
{
/* allocate a new buffer */
context
->
secret
=
(
uint8_t
*
)
bctbx_malloc
(
context
->
secretLength
);
}
else
{
/* or make sure we wipe out the existing one */
memset
(
context
->
secret
,
0
,
context
->
secretLength
);
}
memcpy
(
context
->
secret
,
secret
,
secretLength
);
}
}
/**
*
* @brief Set the given self public key in the ECDH context
* Warning: no check if it matches the private key value
*
* @param[in/out] context ECDH context, will store the given self public key if length is matching the pre-setted algo for this context
* @param[in] selfPublic The buffer holding the self public key, is duplicated in the ECDH context
* @param[in] selfPublicLength Length of previous buffer, must match the algo type setted at context creation
*/
void
bctbx_ECDHSetSelfPublicKey
(
bctbx_ECDHContext_t
*
context
,
const
uint8_t
*
selfPublic
,
const
size_t
selfPublicLength
)
{
if
(
context
!=
NULL
&&
context
->
pointCoordinateLength
==
selfPublicLength
)
{
if
(
context
->
selfPublic
==
NULL
)
{
context
->
selfPublic
=
(
uint8_t
*
)
bctbx_malloc
(
selfPublicLength
);
}
memcpy
(
context
->
selfPublic
,
selfPublic
,
selfPublicLength
);
}
}
/**
*
* @brief Set the given peer public key in the ECDH context
*
* @param[in/out] context ECDH context, will store the given peer public key if length is matching the pre-setted algo for this context
* @param[in] peerPublic The buffer holding the peer public key, is duplicated in the ECDH context
* @param[in] peerPublicLength Length of previous buffer, must match the algo type setted at context creation
*/
BCTBX_PUBLIC
void
bctbx_ECDHSetPeerPublicKey
(
bctbx_ECDHContext_t
*
context
,
const
uint8_t
*
peerPublic
,
const
size_t
peerPublicLength
)
{
if
(
context
!=
NULL
&&
context
->
pointCoordinateLength
==
peerPublicLength
)
{
/* allocate public key buffer if needed */
if
(
context
->
peerPublic
==
NULL
)
{
context
->
peerPublic
=
(
uint8_t
*
)
bctbx_malloc
(
peerPublicLength
);
}
memcpy
(
context
->
peerPublic
,
peerPublic
,
peerPublicLength
);
}
}
/**
*
* @brief Derive the public key from the secret setted in context and using preselected algo, following RFC7748
...
...
@@ -106,8 +145,10 @@ void bctbx_ECDHSetSecretKey(bctbx_ECDHContext_t *context, uint8_t *secret, size_
*/
void
bctbx_ECDHDerivePublicKey
(
bctbx_ECDHContext_t
*
context
)
{
if
(
context
!=
NULL
&&
context
->
secret
!=
NULL
)
{
/* allocate public key buffer */
context
->
selfPublic
=
(
uint8_t
*
)
bctbx_malloc
(
context
->
pointCoordinateLength
);
/* allocate public key buffer if needed */
if
(
context
->
selfPublic
==
NULL
)
{
context
->
selfPublic
=
(
uint8_t
*
)
bctbx_malloc
(
context
->
pointCoordinateLength
);
}
/* then generate the public value */
switch
(
context
->
algo
)
{
...
...
@@ -127,7 +168,11 @@ void bctbx_ECDHDerivePublicKey(bctbx_ECDHContext_t *context) {
void
bctbx_ECDHCreateKeyPair
(
bctbx_ECDHContext_t
*
context
,
int
(
*
rngFunction
)(
void
*
,
uint8_t
*
,
size_t
),
void
*
rngContext
)
{
if
(
context
!=
NULL
)
{
/* first generate the random bytes of self secret and store it in context(do it directly instead of creating a temp buffer and calling SetSecretKey) */
context
->
secret
=
(
uint8_t
*
)
bctbx_malloc
(
context
->
secretLength
);
if
(
context
->
secret
==
NULL
)
{
/* allocate buffer if needed */
context
->
secret
=
(
uint8_t
*
)
bctbx_malloc
(
context
->
secretLength
);
}
else
{
/* otherwise make sure we wipe out previous secret */
memset
(
context
->
secret
,
0
,
context
->
secretLength
);
}
rngFunction
(
rngContext
,
context
->
secret
,
context
->
secretLength
);
/* Then derive the public key */
...
...
@@ -138,19 +183,24 @@ void bctbx_ECDHCreateKeyPair(bctbx_ECDHContext_t *context, int (*rngFunction)(vo
/* compute secret - the ->peerPublic field of context must have been set before calling this function */
void
bctbx_ECDHComputeSecret
(
bctbx_ECDHContext_t
*
context
,
int
(
*
rngFunction
)(
void
*
,
uint8_t
*
,
size_t
),
void
*
rngContext
)
{
if
(
context
!=
NULL
&&
context
->
secret
!=
NULL
&&
context
->
peerPublic
!=
NULL
)
{
/* allocate shared secret buffer */
context
->
sharedSecret
=
(
uint8_t
*
)
bctbx_malloc
(
context
->
pointCoordinateLength
);
if
(
context
->
sharedSecret
==
NULL
)
{
/* allocate buffer if needed */
context
->
sharedSecret
=
(
uint8_t
*
)
bctbx_malloc
(
context
->
pointCoordinateLength
);
}
else
{
/* otherwise make sure we wipe out previous secret */
memset
(
context
->
sharedSecret
,
0
,
context
->
pointCoordinateLength
);
}
switch
(
context
->
algo
)
{
case
BCTBX_ECDH_X25519
:
if
(
decaf_x25519
(
context
->
sharedSecret
,
context
->
peerPublic
,
context
->
secret
)
==
DECAF_FAILURE
)
{
bctbx_free
(
context
->
sharedSecret
);
memset
(
context
->
sharedSecret
,
0
,
context
->
pointCoordinateLength
);
context
->
sharedSecret
=
NULL
;
}
break
;
case
BCTBX_ECDH_X448
:
if
(
decaf_x448
(
context
->
sharedSecret
,
context
->
peerPublic
,
context
->
secret
)
==
DECAF_FAILURE
)
{
bctbx_free
(
context
->
sharedSecret
);
memset
(
context
->
sharedSecret
,
0
,
context
->
pointCoordinateLength
);
context
->
sharedSecret
=
NULL
;
}
break
;
...
...
@@ -167,14 +217,17 @@ void bctbx_DestroyECDHContext(bctbx_ECDHContext_t *context) {
if
(
context
->
secret
!=
NULL
)
{
memset
(
context
->
secret
,
0
,
context
->
secretLength
);
free
(
context
->
secret
);
context
->
secret
=
NULL
;
}
free
(
context
->
selfPublic
);
context
->
selfPublic
=
NULL
;
if
(
context
->
sharedSecret
!=
NULL
)
{
memset
(
context
->
sharedSecret
,
0
,
context
->
pointCoordinateLength
);
free
(
context
->
sharedSecret
);
context
->
sharedSecret
=
NULL
;
}
free
(
context
->
peerPublic
);
free
(
context
->
cryptoModuleData
)
;
context
->
peerPublic
=
NULL
;
free
(
context
);
}
}
...
...
@@ -461,9 +514,11 @@ uint32_t bctbx_key_agreement_algo_list(void) {
/* We do not have lib decaf, implement empty stubs */
int
bctbx_crypto_have_ecc
(
void
)
{
return
FALSE
;}
bctbx_ECDHContext_t
*
bctbx_CreateECDHContext
(
uint8_t
ECDHAlgo
)
{
return
NULL
;}
bctbx_ECDHContext_t
*
bctbx_CreateECDHContext
(
const
uint8_t
ECDHAlgo
)
{
return
NULL
;}
void
bctbx_ECDHCreateKeyPair
(
bctbx_ECDHContext_t
*
context
,
int
(
*
rngFunction
)(
void
*
,
uint8_t
*
,
size_t
),
void
*
rngContext
)
{
return
;}
void
bctbx_ECDHSetSecretKey
(
bctbx_ECDHContext_t
*
context
,
uint8_t
*
secret
,
size_t
secretLength
){
return
;}
void
bctbx_ECDHSetSecretKey
(
bctbx_ECDHContext_t
*
context
,
const
uint8_t
*
secret
,
const
size_t
secretLength
){
return
;}
void
bctbx_ECDHSetSelfPublicKey
(
bctbx_ECDHContext_t
*
context
,
const
uint8_t
*
selfPublic
,
const
size_t
selfPublicLength
){
return
;}
void
bctbx_ECDHSetPeerPublicKey
(
bctbx_ECDHContext_t
*
context
,
const
uint8_t
*
peerPublic
,
const
size_t
peerPublicLength
){
return
;}
void
bctbx_ECDHDerivePublicKey
(
bctbx_ECDHContext_t
*
context
){
return
;}
void
bctbx_ECDHComputeSecret
(
bctbx_ECDHContext_t
*
context
,
int
(
*
rngFunction
)(
void
*
,
uint8_t
*
,
size_t
),
void
*
rngContext
){
return
;}
void
bctbx_DestroyECDHContext
(
bctbx_ECDHContext_t
*
context
){
return
;}
...
...
tester/crypto.c
View file @
81faf2e5
...
...
@@ -92,10 +92,8 @@ static void DHM(void) {
static
void
ECDH_exchange
(
bctbx_ECDHContext_t
*
alice
,
bctbx_ECDHContext_t
*
bob
)
{
/* exchange public keys */
alice
->
peerPublic
=
(
uint8_t
*
)
malloc
(
alice
->
pointCoordinateLength
*
sizeof
(
uint8_t
));
memcpy
(
alice
->
peerPublic
,
bob
->
selfPublic
,
alice
->
pointCoordinateLength
);
bob
->
peerPublic
=
(
uint8_t
*
)
malloc
(
alice
->
pointCoordinateLength
*
sizeof
(
uint8_t
));
memcpy
(
bob
->
peerPublic
,
alice
->
selfPublic
,
alice
->
pointCoordinateLength
);
bctbx_ECDHSetPeerPublicKey
(
alice
,
bob
->
selfPublic
,
alice
->
pointCoordinateLength
);
bctbx_ECDHSetPeerPublicKey
(
bob
,
alice
->
selfPublic
,
bob
->
pointCoordinateLength
);
/* compute shared secrets */
bctbx_ECDHComputeSecret
(
alice
,
NULL
,
NULL
);
...
...
@@ -161,6 +159,30 @@ static void ECDH(void) {
/* clear contexts */
bctbx_rng_context_free
(
RNG
);
/********************************************************************/
/*** Run an exchange using patterns from RFC7748 */
/********************************************************************/
/*** Run it on the X25519 patterns ***/
/* set contexts */
alice
=
bctbx_CreateECDHContext
(
BCTBX_ECDH_X25519
);
bob
=
bctbx_CreateECDHContext
(
BCTBX_ECDH_X25519
);
/* Set private and public value */
bctbx_ECDHSetSecretKey
(
alice
,
ECDHpattern_X25519_alicePrivate
,
32
);
bctbx_ECDHSetSelfPublicKey
(
alice
,
ECDHpattern_X25519_alicePublic
,
32
);
bctbx_ECDHSetSecretKey
(
bob
,
ECDHpattern_X25519_bobPrivate
,
32
);
bctbx_ECDHSetSelfPublicKey
(
bob
,
ECDHpattern_X25519_bobPublic
,
32
);
/* Perform the key exchange and compute shared secret, it will check shared secrets are matching */
ECDH_exchange
(
alice
,
bob
);
/* check shared secret according to RFC7748 patterns */
BC_ASSERT_TRUE
(
memcmp
(
alice
->
sharedSecret
,
ECDHpattern_X25519_sharedSecret
,
32
)
==
0
);
/* clear contexts */
bctbx_DestroyECDHContext
(
alice
);
bctbx_DestroyECDHContext
(
bob
);
/********************************************************************/
/*** Run an key derivation and exchange using patterns from RFC7748 */
/********************************************************************/
...
...
@@ -216,6 +238,30 @@ static void ECDH(void) {
bctbx_DestroyECDHContext
(
alice
);
bctbx_DestroyECDHContext
(
bob
);
/********************************************************************/
/*** Run an exchange using patterns from RFC7748 */
/********************************************************************/
/*** Run it on the X448 patterns ***/
/* set contexts */
alice
=
bctbx_CreateECDHContext
(
BCTBX_ECDH_X448
);
bob
=
bctbx_CreateECDHContext
(
BCTBX_ECDH_X448
);
/* Set private and derive the public value */
bctbx_ECDHSetSecretKey
(
alice
,
ECDHpattern_X448_alicePrivate
,
56
);
bctbx_ECDHSetSelfPublicKey
(
alice
,
ECDHpattern_X448_alicePublic
,
56
);
bctbx_ECDHSetSecretKey
(
bob
,
ECDHpattern_X448_bobPrivate
,
56
);
bctbx_ECDHSetSelfPublicKey
(
bob
,
ECDHpattern_X448_bobPublic
,
56
);
/* Perform the key exchange and compute shared secret, it will check shared secrets are matching */
ECDH_exchange
(
alice
,
bob
);
/* check shared secret according to RFC7748 patterns */
BC_ASSERT_TRUE
(
memcmp
(
alice
->
sharedSecret
,
ECDHpattern_X448_sharedSecret
,
56
)
==
0
);
/* clear contexts */
bctbx_DestroyECDHContext
(
alice
);
bctbx_DestroyECDHContext
(
bob
);
/********************************************************************/
/*** Run an key derivation and exchange using patterns from RFC7748 */
/********************************************************************/
...
...
@@ -251,7 +297,7 @@ static void ECDH25519compat(void) {
#ifdef HAVE_MBEDTLS
int
i
;
bctbx_ECDHContext_t
*
alice
;
bctbx_ECDHContext_t
*
alice
=
NULL
;
bctbx_rng_context_t
*
RNG
;
mbedtls_ecdh_context
*
bob
=
NULL
;
uint8_t
tmpBuffer
[
32
];
...
...
@@ -270,7 +316,7 @@ static void ECDH25519compat(void) {
/* Create Alice and Bob contexts */
alice
=
bctbx_CreateECDHContext
(
BCTBX_ECDH_X25519
);
bob
=
(
mbedtls_ecdh_context
*
)
malloc
(
sizeof
(
mbedtls_ecdh_context
));
bob
=
(
mbedtls_ecdh_context
*
)
bctbx_
malloc
(
sizeof
(
mbedtls_ecdh_context
));
mbedtls_ecdh_init
(
bob
);
mbedtls_ecp_group_load
(
&
(
bob
->
grp
),
MBEDTLS_ECP_DP_CURVE25519
);
...
...
@@ -311,6 +357,8 @@ static void ECDH25519compat(void) {
/* clear contexts */
bctbx_DestroyECDHContext
(
alice
);
mbedtls_ecdh_free
(
bob
);
free
(
bob
);
/* clear contexts */
bctbx_rng_context_free
(
RNG
);
...
...
@@ -378,6 +426,8 @@ static void EdDSA(void) {
bctbx_DestroyEDDSAContext
(
james
);
bctbx_DestroyEDDSAContext
(
world
);
}
bctbx_rng_context_free
(
RNG
);
}
static
void
ed25519_to_x25519_keyconversion
(
void
)
{
...
...
@@ -418,10 +468,10 @@ static void ed25519_to_x25519_keyconversion(void) {
static
void
sign_and_key_exchange
(
void
)
{
int
i
;
bctbx_rng_context_t
*
RNG
;
bctbx_ECDHContext_t
*
aliceECDH
=
bctbx_CreateECDHContext
(
BCTBX_ECDH_X25519
);
bctbx_EDDSAContext_t
*
aliceEDDSA
=
bctbx_CreateEDDSAContext
(
BCTBX_EDDSA_25519
);
bctbx_ECDHContext_t
*
bobECDH
=
bctbx_CreateECDHContext
(
BCTBX_ECDH_X25519
);
bctbx_EDDSAContext_t
*
bobEDDSA
=
bctbx_CreateEDDSAContext
(
BCTBX_EDDSA_25519
);
bctbx_ECDHContext_t
*
aliceECDH
=
NULL
;
//
bctbx_CreateECDHContext(BCTBX_ECDH_X25519);
bctbx_EDDSAContext_t
*
aliceEDDSA
=
NULL
;
//
bctbx_CreateEDDSAContext(BCTBX_EDDSA_25519);
bctbx_ECDHContext_t
*
bobECDH
=
NULL
;
//
bctbx_CreateECDHContext(BCTBX_ECDH_X25519);
bctbx_EDDSAContext_t
*
bobEDDSA
=
NULL
;
//
bctbx_CreateEDDSAContext(BCTBX_EDDSA_25519);
uint8_t
availableAlgosEDDSA
[
2
]
=
{
BCTBX_EDDSA_25519
,
BCTBX_EDDSA_448
};
uint8_t
availableAlgosECDH
[
2
]
=
{
BCTBX_ECDH_X25519
,
BCTBX_ECDH_X448
};
uint8_t
availableAlgosNb
=
2
;
...
...
@@ -494,6 +544,8 @@ static void sign_and_key_exchange(void) {
bctbx_DestroyEDDSAContext
(
bobEDDSA
);
bctbx_DestroyECDHContext
(
bobECDH
);
}
bctbx_rng_context_free
(
RNG
);
}
static
void
hash_test
(
void
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment