Add more mbedtls updates (#65)
Perform some warning clean up
Initialize the mbedtls rng generator
Add more mbedtls support for various algorithms - Note we cannot currently support ECDH because of the lack of support for compressed points in mbedtls.
diff --git a/include/configure.h b/include/configure.h
index 4d927f5..f29966c 100644
--- a/include/configure.h
+++ b/include/configure.h
@@ -18,7 +18,6 @@
// Define which AES GCM algorithms are being used
//
-#if !defined(USE_MBED_TLS)
#define USE_AES_GCM_128
#define USE_AES_GCM_192
#define USE_AES_GCM_256
@@ -26,7 +25,6 @@
#if defined(USE_AES_GCM_128) || defined(USE_AES_GCM_192) || defined(USE_AES_GCM_256)
#define USE_AES_GCM
#endif
-#endif // !defined(USE_MBED_TLS)
//
// Define which AES CCM algorithms are being used
diff --git a/include/cose.h b/include/cose.h
index 85e70e0..0b2ef02 100644
--- a/include/cose.h
+++ b/include/cose.h
@@ -1,9 +1,10 @@
#include <cn-cbor/cn-cbor.h>
+#include "configure.h"
#ifdef __cplusplus
extern "C" {
#endif
-
+
typedef unsigned char byte;
typedef struct _cose * HCOSE;
diff --git a/src/cose_int.h b/src/cose_int.h
index 2cd8a6b..524fe82 100644
--- a/src/cose_int.h
+++ b/src/cose_int.h
@@ -238,6 +238,7 @@
//#define DO_ASSERT assert(false);
#define DO_ASSERT
#define CHECK_CONDITION(condition, error) { if (!(condition)) { DO_ASSERT; if (perr != NULL) {perr->err = error;} goto errorReturn;}}
+#define CHECK_CONDITION0(condition, error) { if ((condition)) { DO_ASSERT; if (perr != NULL) {perr->err = error;} goto errorReturn;}}
#define FAIL_CONDITION(error) { DO_ASSERT; if (perr != NULL) {perr->err = error;} goto errorReturn;}
#define CHECK_CONDITION_CBOR(condition, error) { if (!(condition)) { DO_ASSERT; if (perr != NULL) {perr->err = _MapFromCBOR(error);} goto errorReturn;}}
diff --git a/src/mbedtls.c b/src/mbedtls.c
index 2180f61..07d7dae 100644
--- a/src/mbedtls.c
+++ b/src/mbedtls.c
@@ -16,6 +16,10 @@
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ecdsa.h"
+#include "mbedtls/gcm.h"
+#include "mbedtls/ecp.h"
+#include "mbedtls/ecdh.h"
+#include "mbedtls/nist_kw.h"
bool FUseCompressed = true;
@@ -145,22 +149,23 @@
mbedtls_ccm_free(&ctx);
return false;
}
-/*
+
bool AES_GCM_Decrypt(COSE_Enveloped * pcose, const byte * pbKey, size_t cbKey, const byte * pbCrypto, size_t cbCrypto, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
- EVP_CIPHER_CTX ctx;
+ mbedtls_gcm_context ctx;
int cbOut;
byte * rgbOut = NULL;
int outl = 0;
byte rgbIV[15] = { 0 };
const cn_cbor * pIV = NULL;
- const EVP_CIPHER * cipher;
#ifdef USE_CBOR_CONTEXT
cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif
int TSize = 128 / 8;
- EVP_CIPHER_CTX_init(&ctx);
+ // Make it first so we can clean it up
+ mbedtls_gcm_init(&ctx);
+
// Setup the IV/Nonce and put it into the message
@@ -170,26 +175,19 @@
errorReturn:
if (rgbOut != NULL) COSE_FREE(rgbOut, context);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ mbedtls_gcm_free(&ctx);
return false;
}
- CHECK_CONDITION(pIV->length == 96/8, COSE_ERR_INVALID_PARAMETER);
+ CHECK_CONDITION(pIV->length == 96 / 8, COSE_ERR_INVALID_PARAMETER);
memcpy(rgbIV, pIV->v.str, pIV->length);
// Setup and run the OpenSSL code
switch (cbKey) {
case 128 / 8:
- cipher = EVP_aes_128_gcm();
- break;
-
case 192 / 8:
- cipher = EVP_aes_192_gcm();
- break;
-
case 256 / 8:
- cipher = EVP_aes_256_gcm();
break;
default:
@@ -199,15 +197,7 @@
// Do the setup for OpenSSL
- CHECK_CONDITION(EVP_DecryptInit_ex(&ctx, cipher, NULL, NULL, NULL), COSE_ERR_DECRYPT_FAILED);
-
- CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, TSize, (void *)&pbCrypto[cbCrypto - TSize]), COSE_ERR_DECRYPT_FAILED);
-
- CHECK_CONDITION(EVP_DecryptInit(&ctx, 0, pbKey, rgbIV), COSE_ERR_DECRYPT_FAILED);
-
- // Pus in the AAD
-
- CHECK_CONDITION(EVP_DecryptUpdate(&ctx, NULL, &outl, pbAuthData, (int) cbAuthData), COSE_ERR_DECRYPT_FAILED);
+ CHECK_CONDITION0(mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, pbKey, cbKey * 8), COSE_ERR_CRYPTO_FAIL);
//
@@ -217,17 +207,20 @@
// Process content
- CHECK_CONDITION(EVP_DecryptUpdate(&ctx, rgbOut, &cbOut, pbCrypto, (int)cbCrypto - TSize), COSE_ERR_DECRYPT_FAILED);
+ byte tag[128 / 8];
+ CHECK_CONDITION0(mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT, cbOut,
+ rgbIV, 96 / 8,
+ pbAuthData, cbAuthData,
+ pbCrypto, rgbOut,
+ TSize, tag), COSE_ERR_CRYPTO_FAIL);
- // Process Tag
+ // CHECK TAG HERE
+ bool f = false;
+ byte * pb = pbCrypto + cbOut;
+ for (int i = 0; i < (unsigned int)TSize; i++) f |= (pb[i] != tag[i]);
+ CHECK_CONDITION(!f, COSE_ERR_CRYPTO_FAIL);
- CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, TSize, (byte *)pbCrypto + cbCrypto - TSize), COSE_ERR_DECRYPT_FAILED);
-
- // Check the result
-
- CHECK_CONDITION(EVP_DecryptFinal(&ctx, rgbOut + cbOut, &cbOut), COSE_ERR_DECRYPT_FAILED);
-
- EVP_CIPHER_CTX_cleanup(&ctx);
+ mbedtls_gcm_free(&ctx);
pcose->pbContent = rgbOut;
pcose->cbContent = cbOut;
@@ -237,7 +230,7 @@
bool AES_GCM_Encrypt(COSE_Enveloped * pcose, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
- EVP_CIPHER_CTX ctx;
+ mbedtls_gcm_context ctx;
int cbOut;
byte * rgbOut = NULL;
int outl = 0;
@@ -245,14 +238,13 @@
byte * pbIV = NULL;
const cn_cbor * cbor_iv = NULL;
cn_cbor * cbor_iv_t = NULL;
- const EVP_CIPHER * cipher;
#ifdef USE_CBOR_CONTEXT
cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif
cn_cbor_errback cbor_error;
// Make it first so we can clean it up
- EVP_CIPHER_CTX_init(&ctx);
+ mbedtls_gcm_init(&ctx);
// Setup the IV/Nonce and put it into the message
@@ -276,17 +268,10 @@
}
- switch (cbKey*8) {
+ switch (cbKey * 8) {
case 128:
- cipher = EVP_aes_128_gcm();
- break;
-
case 192:
- cipher = EVP_aes_192_gcm();
- break;
-
case 256:
- cipher = EVP_aes_256_gcm();
break;
default:
@@ -296,37 +281,33 @@
// Setup and run the OpenSSL code
- CHECK_CONDITION(EVP_EncryptInit_ex(&ctx, cipher, NULL, NULL, NULL), COSE_ERR_CRYPTO_FAIL);
+ CHECK_CONDITION0(mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, pbKey, cbKey * 8), COSE_ERR_CRYPTO_FAIL);
- CHECK_CONDITION(EVP_EncryptInit(&ctx, 0, pbKey, rgbIV), COSE_ERR_CRYPTO_FAIL);
+ CHECK_CONDITION0(mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT, rgbIV, 96 / 8, pbAuthData, cbAuthData), COSE_ERR_CRYPTO_FAIL);
- CHECK_CONDITION(EVP_EncryptUpdate(&ctx, NULL, &outl, pbAuthData, (int) cbAuthData), COSE_ERR_CRYPTO_FAIL);
-
- rgbOut = (byte *)COSE_CALLOC(pcose->cbContent + 128/8, 1, context);
+ rgbOut = (byte *)COSE_CALLOC(pcose->cbContent + 128 / 8, 1, context);
CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);
- CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, pcose->pbContent, (int)pcose->cbContent), COSE_ERR_CRYPTO_FAIL);
+ CHECK_CONDITION0(mbedtls_gcm_update(&ctx, pcose->cbContent, pcose->pbContent, rgbOut), COSE_ERR_CRYPTO_FAIL);
- CHECK_CONDITION(EVP_EncryptFinal_ex(&ctx, &rgbOut[cbOut], &cbOut), COSE_ERR_CRYPTO_FAIL);
+ CHECK_CONDITION0(mbedtls_gcm_finish(&ctx, &rgbOut[pcose->cbContent], 128 / 8), COSE_ERR_CRYPTO_FAIL);
- CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, 128/8, &rgbOut[pcose->cbContent]), COSE_ERR_CRYPTO_FAIL);
-
- cn_cbor * cnTmp = cn_cbor_data_create(rgbOut, (int)pcose->cbContent + 128/8, CBOR_CONTEXT_PARAM_COMMA NULL);
+ cn_cbor * cnTmp = cn_cbor_data_create(rgbOut, (int)pcose->cbContent + 128 / 8, CBOR_CONTEXT_PARAM_COMMA NULL);
CHECK_CONDITION(cnTmp != NULL, COSE_ERR_CBOR);
rgbOut = NULL;
CHECK_CONDITION(_COSE_array_replace(&pcose->m_message, cnTmp, INDEX_BODY, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ mbedtls_gcm_free(&ctx);
return true;
errorReturn:
if (pbIV != NULL) COSE_FREE(pbIV, context);
if (cbor_iv_t != NULL) COSE_FREE(cbor_iv_t, context);
if (rgbOut != NULL) COSE_FREE(rgbOut, context);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ mbedtls_gcm_free(&ctx);
return false;
}
-
+/*
bool AES_CBC_MAC_Create(COSE_MacMessage * pcose, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
@@ -545,88 +526,83 @@
EVP_CIPHER_CTX_cleanup(&ctx);
return false;
}
-
+*/
bool HKDF_Extract(COSE * pcose, const byte * pbKey, size_t cbKey, size_t cbitDigest, byte * rgbDigest, size_t * pcbDigest, CBOR_CONTEXT_COMMA cose_errback * perr)
{
- byte rgbSalt[EVP_MAX_MD_SIZE] = { 0 };
- int cbSalt;
- cn_cbor * cnSalt;
- HMAC_CTX ctx;
- const EVP_MD * pmd = NULL;
- unsigned int cbDigest;
+ mbedtls_md_info_t * pmd;
+ mbedtls_md_type_t mdType;
- HMAC_CTX_init(&ctx);
+ int cbSalt;
+ cn_cbor * cnSalt;
+ unsigned int cbDigest;
- if (0) {
- errorReturn:
- HMAC_cleanup(&ctx);
- return false;
- }
+ if (0) {
+ errorReturn:
+ return false;
+ }
- switch (cbitDigest) {
- case 256: pmd = EVP_sha256(); cbSalt = 256 / 8; break;
- case 384: pmd = EVP_sha384(); cbSalt = 384 / 8; break;
- case 512: pmd = EVP_sha512(); cbSalt = 512 / 8; break;
- default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
- }
+ switch (cbitDigest) {
+ case 256: mdType = MBEDTLS_MD_SHA256; cbDigest = 256 / 8; break;
+ case 384: mdType = MBEDTLS_MD_SHA384; cbDigest = 384 / 8; break;
+ case 512: mdType = MBEDTLS_MD_SHA512; cbDigest = 512 / 8; break;
+ default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
+ }
- cnSalt = _COSE_map_get_int(pcose, COSE_Header_HKDF_salt, COSE_BOTH, perr);
+ pmd = mbedtls_md_info_from_type(mdType);
+ if (pmd == NULL) goto errorReturn;
- if (cnSalt != NULL) {
- CHECK_CONDITION(HMAC_Init(&ctx, cnSalt->v.bytes, (int) cnSalt->length, pmd), COSE_ERR_CRYPTO_FAIL);
- }
- else {
- CHECK_CONDITION(HMAC_Init(&ctx, rgbSalt, cbSalt, pmd), COSE_ERR_CRYPTO_FAIL);
- }
- CHECK_CONDITION(HMAC_Update(&ctx, pbKey, (int)cbKey), COSE_ERR_CRYPTO_FAIL);
- CHECK_CONDITION(HMAC_Final(&ctx, rgbDigest, &cbDigest), COSE_ERR_CRYPTO_FAIL);
- *pcbDigest = cbDigest;
- HMAC_cleanup(&ctx);
- return true;
+ cbSalt = 0;
+ byte * pbSalt = NULL;
+
+ cnSalt = _COSE_map_get_int(pcose, COSE_Header_HKDF_salt, COSE_BOTH, perr);
+
+ if (cnSalt != NULL) {
+ pbSalt = cnSalt->v.bytes;
+ cbSalt = (int)cnSalt->length;
+ }
+
+ CHECK_CONDITION0(mbedtls_hkdf_extract(pmd, pbSalt, cbSalt, pbKey, cbKey, rgbDigest), 0);
+
+ *pcbDigest = cbDigest;
+
+ return true;
}
bool HKDF_Expand(COSE * pcose, size_t cbitDigest, const byte * pbPRK, size_t cbPRK, const byte * pbInfo, size_t cbInfo, byte * pbOutput, size_t cbOutput, cose_errback * perr)
{
- HMAC_CTX ctx;
- const EVP_MD * pmd = NULL;
+ mbedtls_md_type_t mdType;
+ mbedtls_md_info_t * pmd;
+
size_t ib;
- int cbSalt;
- unsigned int cbDigest = 0;
- byte rgbDigest[EVP_MAX_MD_SIZE];
- byte bCount = 1;
+ int cbSalt;
+ unsigned int cbDigest = 0;
+ byte bCount = 1;
- HMAC_CTX_init(&ctx);
+ if (0) {
+ errorReturn:
+ return false;
+ }
- if (0) {
- errorReturn:
- HMAC_cleanup(&ctx);
- return false;
- }
+ switch (cbitDigest) {
+ case 256: mdType = MBEDTLS_MD_SHA256; cbDigest = 256 / 8; break;
+ case 384: mdType = MBEDTLS_MD_SHA384; cbDigest = 384 / 8; break;
+ case 512: mdType = MBEDTLS_MD_SHA512; cbDigest = 512 / 8; break;
+ default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
+ }
- switch (cbitDigest) {
- case 256: pmd = EVP_sha256(); cbSalt = 256 / 8; break;
- case 384: pmd = EVP_sha384(); cbSalt = 384 / 8; break;
- case 512: pmd = EVP_sha512(); cbSalt = 512 / 8; break;
- default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
- }
+ pmd = mbedtls_md_info_from_type(mdType);
+ if (pmd == NULL) goto errorReturn;
- for (ib = 0; ib < cbOutput; ib += cbDigest, bCount += 1) {
- CHECK_CONDITION(HMAC_Init_ex(&ctx, pbPRK, (int)cbPRK, pmd, NULL), COSE_ERR_CRYPTO_FAIL);
- CHECK_CONDITION(HMAC_Update(&ctx, rgbDigest, cbDigest), COSE_ERR_CRYPTO_FAIL);
- CHECK_CONDITION(HMAC_Update(&ctx, pbInfo, cbInfo), COSE_ERR_CRYPTO_FAIL);
- CHECK_CONDITION(HMAC_Update(&ctx, &bCount, 1), COSE_ERR_CRYPTO_FAIL);
- CHECK_CONDITION(HMAC_Final(&ctx, rgbDigest, &cbDigest), COSE_ERR_CRYPTO_FAIL);
+ if (mbedtls_hkdf_expand(pmd, pbPRK, cbPRK, pbInfo, cbInfo, pbOutput, cbOutput) != 0) {
+ goto errorReturn;
+ }
- memcpy(pbOutput + ib, rgbDigest, MIN(cbDigest, cbOutput - ib));
- }
-
- HMAC_cleanup(&ctx);
- return true;
+ return true;
}
-
+/*
void dump_output(byte* b, size_t s){
for(int i = 0; i < s; i++){
printf("%02x", *b);
@@ -1007,7 +983,6 @@
#endif
}
-
bool ECDSA_Verify(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr)
{
mbedtls_ecp_keypair keypair;
@@ -1062,55 +1037,63 @@
return result;
}
-/*
+#ifdef MBEDTLS_NIST_KW_C
bool AES_KW_Decrypt(COSE_Enveloped * pcose, const byte * pbKeyIn, size_t cbitKey, const byte * pbCipherText, size_t cbCipherText, byte * pbKeyOut, int * pcbKeyOut, cose_errback * perr)
{
- byte rgbOut[512 / 8];
- AES_KEY key;
+ mbedtls_nist_kw_context ctx;
- CHECK_CONDITION(AES_set_decrypt_key(pbKeyIn, (int)cbitKey, &key) == 0, COSE_ERR_CRYPTO_FAIL);
+ mbedtls_nist_kw_init(&ctx);
- CHECK_CONDITION(AES_unwrap_key(&key, NULL, rgbOut, pbCipherText, (int) cbCipherText), COSE_ERR_CRYPTO_FAIL);
+ CHECK_CONDITION0(mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, pbKeyIn, cbitKey, FALSE), COSE_ERR_CRYPTO_FAIL);
- memcpy(pbKeyOut, rgbOut, cbCipherText - 8);
- *pcbKeyOut = (int) (cbCipherText - 8);
+ CHECK_CONDITION0(mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, pbCipherText, cbCipherText,
+ pbKeyOut, pcbKeyOut, cbCipherText-8), COSE_ERR_CRYPTO_FAIL);
- return true;
+ mbedtls_nist_kw_free(&ctx);
+ return true;
+
errorReturn:
- return false;
+ mbedtls_nist_kw_free(&ctx);
+ return false;
}
bool AES_KW_Encrypt(COSE_RecipientInfo * pcose, const byte * pbKeyIn, int cbitKey, const byte * pbContent, int cbContent, cose_errback * perr)
{
- byte *pbOut = NULL;
- AES_KEY key;
+ byte *pbOut = NULL;
#ifdef USE_CBOR_CONTEXT
- cn_cbor_context * context = &pcose->m_encrypt.m_message.m_allocContext;
+ cn_cbor_context * context = &pcose->m_encrypt.m_message.m_allocContext;
#endif
- cn_cbor * cnTmp = NULL;
+ cn_cbor * cnTmp = NULL;
+ mbedtls_nist_kw_context ctx;
+ size_t cbOut;
- pbOut = COSE_CALLOC(cbContent + 8, 1, context);
- CHECK_CONDITION(pbOut != NULL, COSE_ERR_OUT_OF_MEMORY);
+ mbedtls_nist_kw_init(&ctx);
- CHECK_CONDITION(AES_set_encrypt_key(pbKeyIn, cbitKey, &key) == 0, COSE_ERR_CRYPTO_FAIL);
+ pbOut = COSE_CALLOC(cbContent + 8, 1, context);
+ CHECK_CONDITION(pbOut != NULL, COSE_ERR_OUT_OF_MEMORY);
- CHECK_CONDITION(AES_wrap_key(&key, NULL, pbOut, pbContent, cbContent), COSE_ERR_CRYPTO_FAIL);
+ CHECK_CONDITION0(mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, pbKeyIn, cbitKey, FALSE), COSE_ERR_CRYPTO_FAIL);
- cnTmp = cn_cbor_data_create(pbOut, (int)cbContent + 8, CBOR_CONTEXT_PARAM_COMMA NULL);
- CHECK_CONDITION(cnTmp != NULL, COSE_ERR_CBOR);
- pbOut = NULL;
- CHECK_CONDITION(_COSE_array_replace(&pcose->m_encrypt.m_message, cnTmp, INDEX_BODY, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);
- cnTmp = NULL;
+ CHECK_CONDITION0(mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, pbContent, cbContent,
+ pbOut, &cbOut, cbContent+8), COSE_ERR_CRYPTO_FAIL);
- return true;
+ cnTmp = cn_cbor_data_create(pbOut, (int)cbContent + 8, CBOR_CONTEXT_PARAM_COMMA NULL);
+ CHECK_CONDITION(cnTmp != NULL, COSE_ERR_CBOR);
+ pbOut = NULL;
+ CHECK_CONDITION(_COSE_array_replace(&pcose->m_encrypt.m_message, cnTmp, INDEX_BODY, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);
+ cnTmp = NULL;
+
+ mbedtls_nist_kw_free(&ctx);
+ return true;
errorReturn:
- COSE_FREE(cnTmp, context);
- if (pbOut != NULL) COSE_FREE(pbOut, context);
- return false;
+ COSE_FREE(cnTmp, context);
+ if (pbOut != NULL) COSE_FREE(pbOut, context);
+ mbedtls_nist_kw_free(&ctx);
+ return false;
}
+#endif // MBEDTLS_NIST_KW_C
-*/
/*
//#include <stdio.h> //TODO
void rand_bytes(byte * pb, size_t cb){
@@ -1134,6 +1117,7 @@
printf("rand byute done\n");
}*/
//TODO HOW TO GENERATE GOOD RANDOM BYTES
+#if 0
static const unsigned char entropy_source_pr[96] =
{ 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
@@ -1147,11 +1131,13 @@
0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
+#endif
static const unsigned char nonce_pers_pr[16] =
{ 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
+/*
static size_t test_offset;
static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, size_t len ) {
const unsigned char *p = data;
@@ -1159,15 +1145,25 @@
test_offset += len;
return( 0 );
}
+*/
+
+mbedtls_ctr_drbg_context ctx;
+int ctx_setup = 0;
+mbedtls_entropy_context entropy;
void rand_bytes(byte* pb, size_t cb){
- mbedtls_ctr_drbg_context ctx;
// unsigned char buf[16];
+
+ if (!ctx_setup) {
+ mbedtls_entropy_init(&entropy);
+
+ mbedtls_ctr_drbg_init( &ctx );
- mbedtls_ctr_drbg_init( &ctx );
-
- mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, (void *) entropy_source_pr, nonce_pers_pr, 16, 32 );
+ mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_entropy_func, (void *) &entropy, nonce_pers_pr, 16, 32 );
+
+ ctx_setup = 1;
+ }
//mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
@@ -1175,10 +1171,18 @@
//mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE );
//memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
- mbedtls_ctr_drbg_free( &ctx );
+ // mbedtls_ctr_drbg_free( &ctx );
}
+
+int rand_bytes2(void * pv, unsigned char * pb, size_t cb)
+{
+ rand_bytes(pb, cb);
+ return 0;
+}
+
//END OF TODO RANDOM BYTES
+#if USE_ECDH
/*!
*
* @param[in] pRecipent Pointer to the message object
@@ -1190,54 +1194,150 @@
* @param[out] perr location to return error information
* @returns success of the function
*/
-/*
+
bool ECDH_ComputeSecret(COSE * pRecipient, cn_cbor ** ppKeyPrivate, const cn_cbor * pKeyPublic, byte ** ppbSecret, size_t * pcbSecret, CBOR_CONTEXT_COMMA cose_errback *perr)
{
- EC_KEY * peckeyPrivate = NULL;
- EC_KEY * peckeyPublic = NULL;
- int cbGroup;
- int cbsecret;
- byte * pbsecret = NULL;
- bool fRet = false;
+ int cbGroup;
+ int cbsecret;
+ byte * pbsecret = NULL;
+ bool fRet = false;
+ mbedtls_ecp_group_id groupId;
+ mbedtls_ecp_keypair keypair;
+ mbedtls_ecdh_context ctx;
+ mbedtls_mpi d;
+ cn_cbor * p = NULL;
+ mbedtls_mpi z;
+ cn_cbor * pkey = NULL;
+ int cose_group;
+
+ mbedtls_mpi_init(&z);
+ mbedtls_ecdh_init(&ctx);
+ mbedtls_mpi_init(&d);
+ mbedtls_ecp_keypair_init(&keypair);
+
- peckeyPublic = ECKey_From(pKeyPublic, &cbGroup, perr);
- if (peckeyPublic == NULL) goto errorReturn;
+ p = cn_cbor_mapget_int(pKeyPublic, COSE_Key_EC_Curve);
+ CHECK_CONDITION((p != NULL) && (p->type == CN_CBOR_UINT), COSE_ERR_INVALID_PARAMETER);
- if (*ppKeyPrivate == NULL) {
- {
- cn_cbor * pCompress = _COSE_map_get_int(pRecipient, COSE_Header_UseCompressedECDH, COSE_BOTH, perr);
- if (pCompress == NULL) FUseCompressed = false;
- else FUseCompressed = (pCompress->type == CN_CBOR_TRUE);
- }
- peckeyPrivate = EC_KEY_new();
- EC_KEY_set_group(peckeyPrivate, EC_KEY_get0_group(peckeyPublic));
- CHECK_CONDITION(EC_KEY_generate_key(peckeyPrivate) == 1, COSE_ERR_CRYPTO_FAIL);
- *ppKeyPrivate = EC_FromKey(peckeyPrivate, CBOR_CONTEXT_PARAM_COMMA perr);
- if (*ppKeyPrivate == NULL) goto errorReturn;
- }
- else {
- peckeyPrivate = ECKey_From(*ppKeyPrivate, &cbGroup, perr);
- if (peckeyPrivate == NULL) goto errorReturn;
- }
+ switch (p->v.uint) {
+ case 1: // P-256
+ groupId = MBEDTLS_ECP_DP_SECP256R1;
+ cbGroup = 256 / 8;
+ cose_group = 1;
+ break;
- pbsecret = COSE_CALLOC(cbGroup, 1, context);
- CHECK_CONDITION(pbsecret != NULL, COSE_ERR_OUT_OF_MEMORY);
+ case 2: // P-384
+ groupId = MBEDTLS_ECP_DP_SECP384R1;
+ cbGroup = 384 / 12;
+ cose_group = 2;
+ break;
- cbsecret = ECDH_compute_key(pbsecret, cbGroup, EC_KEY_get0_public_key(peckeyPublic), peckeyPrivate, NULL);
- CHECK_CONDITION(cbsecret > 0, COSE_ERR_CRYPTO_FAIL);
+ case 3: // P-521
+ groupId = MBEDTLS_ECP_DP_SECP521R1;
+ cbGroup = (521 + 7) / 8;
+ cose_group = 3;
+ break;
- *ppbSecret = pbsecret;
- *pcbSecret = cbsecret;
- pbsecret = NULL;
+ default:
+ FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+ }
+ p = NULL;
- fRet = true;
+ mbedtls_ecp_group group = { 0 };
+ CHECK_CONDITION0(mbedtls_ecp_group_load(&group, groupId), COSE_ERR_INVALID_PARAMETER);
+
+ if (!ECKey_From(pKeyPublic, &keypair, perr)) goto errorReturn;
+
+ if (*ppKeyPrivate == NULL) {
+ {
+ cn_cbor * pCompress = _COSE_map_get_int(pRecipient, COSE_Header_UseCompressedECDH, COSE_BOTH, perr);
+ if (pCompress == NULL) FUseCompressed = false;
+ else FUseCompressed = (pCompress->type == CN_CBOR_TRUE);
+ }
+ mbedtls_ecp_keypair privateKeyPair;
+ mbedtls_ecp_keypair_init(&privateKeyPair);
+
+ CHECK_CONDITION0( mbedtls_ecp_gen_key(groupId, &privateKeyPair, rand_bytes2, NULL), COSE_ERR_CRYPTO_FAIL);
+ CHECK_CONDITION0( mbedtls_mpi_copy(&d, &privateKeyPair.d), COSE_ERR_CRYPTO_FAIL);
+
+ size_t olen = 0;
+ byte buff[528 * 2 / 8 + 1];
+ CHECK_CONDITION0(mbedtls_ecp_point_write_binary(&group, &privateKeyPair.Q, MBEDTLS_ECP_PF_UNCOMPRESSED,
+ &olen, buff, sizeof(buff)), COSE_ERR_CRYPTO_FAIL);
+
+ cn_cbor_errback cbor_error;
+ int cbSize = (olen - 1)/2;
+
+ pkey = cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(pkey != NULL, cbor_error);
+
+ p = cn_cbor_int_create(cose_group, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(p != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_Curve, p, CBOR_CONTEXT_PARAM_COMMA perr), cbor_error);
+ p = NULL;
+
+ pbsecret = COSE_CALLOC(cbSize, 1, context);
+ CHECK_CONDITION(pbsecret != NULL, COSE_ERR_OUT_OF_MEMORY);
+ memcpy(pbsecret, buff + 1, cbSize);
+
+ p = cn_cbor_data_create(pbsecret, (int) cbSize, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(p != NULL, cbor_error);
+ pbsecret = NULL;
+ CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_X, p, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
+ p = NULL;
+
+ pbsecret = COSE_CALLOC(cbSize, 1, context);
+ CHECK_CONDITION(pbsecret != NULL, COSE_ERR_OUT_OF_MEMORY);
+ memcpy(pbsecret, buff + 1 + cbSize, cbSize);
+
+ p = cn_cbor_data_create(pbsecret, cbSize, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(p != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_Y, p, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
+ p = NULL;
+
+ p = cn_cbor_int_create(COSE_Key_Type_EC2, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(p != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_Type, p, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
+ p = NULL;
+
+ *ppKeyPrivate = pkey;
+ pkey = NULL;
+ }
+ else {
+ p = cn_cbor_mapget_int(*ppKeyPrivate, COSE_Key_EC_d);
+ CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER);
+
+ CHECK_CONDITION(p->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
+ CHECK_CONDITION0(mbedtls_mpi_read_binary( &d, p->v.bytes, p->length), COSE_ERR_CRYPTO_FAIL);
+ }
+
+
+
+ CHECK_CONDITION0( mbedtls_ecdh_compute_shared(&group, &z, &keypair.Q, &d, NULL, NULL), COSE_ERR_CRYPTO_FAIL);
+
+ cbsecret = cbGroup;
+ pbsecret = COSE_CALLOC(cbsecret, 1, context);
+ CHECK_CONDITION(pbsecret != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+ CHECK_CONDITION0(mbedtls_mpi_write_binary(&z, pbsecret, cbsecret), COSE_ERR_CRYPTO_FAIL);
+
+ *ppbSecret = pbsecret;
+ *pcbSecret = cbsecret;
+ pbsecret = NULL;
+
+ fRet = true;
errorReturn:
- if (pbsecret != NULL) COSE_FREE(pbsecret, context);
- if (peckeyPublic != NULL) EC_KEY_free(peckeyPublic);
- if (peckeyPrivate != NULL) EC_KEY_free(peckeyPrivate);
+ if (pbsecret != NULL) COSE_FREE(pbsecret, context);
+ if (pkey != NULL) CN_CBOR_FREE(pkey, context);
+ if (p != NULL) CN_CBOR_FREE(pkey, context);
- return fRet;
+ mbedtls_mpi_free(&d);
+ mbedtls_mpi_free(&z);
+ mbedtls_ecp_group_free(&group);
+ mbedtls_ecp_keypair_free(&keypair);
+ mbedtls_ecdh_free(&ctx);
+ return fRet;
}
-*/
+#endif // USE_ECDH
#endif // USE_MBED_TLS
diff --git a/test/encrypt.c b/test/encrypt.c
index 0fb56c8..300f33e 100644
--- a/test/encrypt.c
+++ b/test/encrypt.c
@@ -96,7 +96,7 @@
alg = COSE_Recipient_map_get_int(hRecip2, COSE_Header_Algorithm, COSE_BOTH, NULL);
if (!IsAlgorithmSupported(alg)) fNoSupport = true;
}
- alg = COSE_Recipient_map_get_int(hRecip, COSE_Header_Algorithm, COSE_BOTH, NULL);
+ alg = COSE_Recipient_map_get_int(hRecip1, COSE_Header_Algorithm, COSE_BOTH, NULL);
if (!IsAlgorithmSupported(alg)) fNoSupport = true;
}
diff --git a/test/json.c b/test/json.c
index 9508126..e7931d0 100644
--- a/test/json.c
+++ b/test/json.c
@@ -155,7 +155,7 @@
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '-', '_' };
-static char *decoding_table = NULL;
+static unsigned char *decoding_table = NULL;
static int mod_table[] = { 0, 2, 1 };
@@ -242,7 +242,7 @@
decoding_table = malloc(256);
for (int i = 0; i < 64; i++)
- decoding_table[(int) encoding_table[i]] = (char) i;
+ decoding_table[(int) encoding_table[i]] = (unsigned char) i;
}
diff --git a/test/test.c b/test/test.c
index 1fbc21f..3948453 100644
--- a/test/test.c
+++ b/test/test.c
@@ -21,6 +21,10 @@
#include "test.h"
+#ifdef USE_MBED_TLS
+#include "mbedtls/entropy.h"
+#endif
+
int CFails = 0;
@@ -1007,6 +1011,11 @@
}
}
+#ifdef USE_MBED_TLS
+ mbedtls_entropy_context entropy;
+ mbedtls_entropy_init(&entropy);
+#endif
+
//
// If we are given a file name, then process the file name
//
@@ -1050,5 +1059,5 @@
if (CFails > 0) fprintf(stderr, "Failed %d tests\n", CFails);
else fprintf(stderr, "SUCCESS\n");
- exit(CFails);
+ exit(CFails);
}