diff --git a/IDE/MDK-ARM/LPC43xx/time-LCP43xx.c b/IDE/MDK-ARM/LPC43xx/time-LCP43xx.c index 3c9863254..bf32ef2dd 100644 --- a/IDE/MDK-ARM/LPC43xx/time-LCP43xx.c +++ b/IDE/MDK-ARM/LPC43xx/time-LCP43xx.c @@ -60,10 +60,6 @@ static void init_RTC() *----------------------------------------------------------------------------*/ #include "lpc43xx_timer.h" -//#include "lpc43xx_cgu.h" -//#include "lpc43xx_scu.h" -//#include "lpc43xx_libcfg.h" -//#include "debug_frmwrk.h" static void init_TIM() { diff --git a/IDE/MDK-ARM/MDK-ARM/CyaSSL/main.c b/IDE/MDK-ARM/MDK-ARM/CyaSSL/main.c index 4979473ee..8883a88dd 100644 --- a/IDE/MDK-ARM/MDK-ARM/CyaSSL/main.c +++ b/IDE/MDK-ARM/MDK-ARM/CyaSSL/main.c @@ -108,7 +108,7 @@ void main_task (void) init_TcpNet (); os_tsk_create (tcp_tick, 2); - os_tsk_create (tcp_poll, 1); + os_tsk_create (tcp_poll, 1); #endif #ifdef CYASSL_MDK_SHELL @@ -137,8 +137,8 @@ void main_task (void) int myoptind = 0; char* myoptarg = NULL; - #if defined(DEBUG_CYASSL) - extern void CyaSSL_Debugging_ON(void) ; +#if defined(DEBUG_CYASSL) + extern void CyaSSL_Debugging_ON(void) ; #endif @@ -148,26 +148,25 @@ extern void SystemInit(void); int main() { - SystemInit(); - SER_Init() ; + SystemInit(); + SER_Init() ; #if !defined(NO_FILESYSTEM) - init_card () ; /* initializing SD card */ + init_card () ; /* initializing SD card */ #endif init_time() ; - #if defined(DEBUG_CYASSL) printf("Turning ON Debug message\n") ; CyaSSL_Debugging_ON() ; #endif #ifdef HAVE_KEIL_RTX - os_sys_init (main_task) ; + os_sys_init (main_task) ; #else - main_task() ; + main_task() ; #endif - + return 0 ; /* There should be no return here */ } diff --git a/IDE/MDK-ARM/MDK-ARM/CyaSSL/ssl-dummy.c b/IDE/MDK-ARM/MDK-ARM/CyaSSL/ssl-dummy.c index 2d407b134..261fa2edc 100644 --- a/IDE/MDK-ARM/MDK-ARM/CyaSSL/ssl-dummy.c +++ b/IDE/MDK-ARM/MDK-ARM/CyaSSL/ssl-dummy.c @@ -48,6 +48,6 @@ int CyaSSL_get_using_nonblock(CYASSL* ssl) Signer* GetCAByName(void* vp, byte* hash) { - Signer * ca ; + Signer * ca ; return(ca) ; } diff --git a/IDE/MDK5-ARM/Projects/CryptTest/main.c b/IDE/MDK5-ARM/Projects/CryptTest/main.c index c9054ae89..a0dd1aa3f 100644 --- a/IDE/MDK5-ARM/Projects/CryptTest/main.c +++ b/IDE/MDK5-ARM/Projects/CryptTest/main.c @@ -57,8 +57,6 @@ extern void init_time(void) ; /*----------------------------------------------------------------------------- * mian entry *----------------------------------------------------------------------------*/ -//int myoptind = 0; -//char* myoptarg = NULL; int main() { diff --git a/IDE/MDK5-ARM/Projects/CyaSSL-Full/echoclient.c b/IDE/MDK5-ARM/Projects/CyaSSL-Full/echoclient.c index 0d6b2a706..bc7e26310 100644 --- a/IDE/MDK5-ARM/Projects/CyaSSL-Full/echoclient.c +++ b/IDE/MDK5-ARM/Projects/CyaSSL-Full/echoclient.c @@ -35,7 +35,6 @@ #include "cmsis_os.h" #include "rl_fs.h" #include "rl_net.h" -// #include "config-EchoClient.h" #else #include "rtl.h" #endif diff --git a/IDE/MDK5-ARM/Projects/CyaSSL-Full/shell.c b/IDE/MDK5-ARM/Projects/CyaSSL-Full/shell.c index 9e8e484f0..c79f276ff 100644 --- a/IDE/MDK5-ARM/Projects/CyaSSL-Full/shell.c +++ b/IDE/MDK5-ARM/Projects/CyaSSL-Full/shell.c @@ -609,7 +609,6 @@ void shell_main(void *arg) { printf("Starting Shell\n") ; while(1) { - //while(1) ; if(getline(line, LINESIZE, &args, &bf_flg) > 0) { for(i=0; commandTable[i].func != NULL; i++) { if(strcmp(commandTable[i].command, args.argv[0]) == 0) { diff --git a/ctaocrypt/benchmark/benchmark.c b/ctaocrypt/benchmark/benchmark.c index 4ad39833e..a6143139e 100644 --- a/ctaocrypt/benchmark/benchmark.c +++ b/ctaocrypt/benchmark/benchmark.c @@ -221,11 +221,15 @@ int benchmark_test(void *args) #ifdef BENCH_EMBEDDED const int numBlocks = 25; /* how many kB/megs to test (en/de)cryption */ const char blockType[] = "kB"; /* used in printf output */ -const int times = 1; /* public key iterations */ +const int times = 1; /* public key iterations */ +const int genTimes = 5; +const int agreeTimes = 5; #else const int numBlocks = 5; const char blockType[] = "megs"; -const int times = 100; +const int times = 100; +const int genTimes = 100; +const int agreeTimes = 100; #endif const byte key[] = @@ -879,7 +883,6 @@ void bench_rsaKeyGen(void) RsaKey genKey; double start, total, each, milliEach; int i; - const int genTimes = 5; /* 1024 bit */ start = current_time(1); @@ -1093,7 +1096,7 @@ void bench_eccKeyAgree(void) double current_time(int reset) { - (void) reset; + (void)reset; struct timeval tv; gettimeofday(&tv, 0); diff --git a/ctaocrypt/src/ecc.c b/ctaocrypt/src/ecc.c index e67679aef..0a87e00cb 100644 --- a/ctaocrypt/src/ecc.c +++ b/ctaocrypt/src/ecc.c @@ -33,6 +33,11 @@ #include #include +#ifdef HAVE_ECC_ENCRYPT + #include + #include +#endif + /* map @@ -3484,6 +3489,269 @@ void ecc_fp_free(void) } - #endif /* FP_ECC */ + +#ifdef HAVE_ECC_ENCRYPT + +/* init and set defaults, just holders */ +void ecc_encrypt_init_options(ecEncOptions* options) +{ + if (options) { + XMEMSET(options, 0, sizeof(ecEncOptions)); + + options->encAlgo = ecAES_128_CBC; + options->kdfAlgo = ecHKDF_SHA256; + options->macAlgo = ecHMAC_SHA256; + } +} + + +/* free any resources, clear any keys */ +void ecc_encrypt_free_options(ecEncOptions* options) +{ + if (options) { + XMEMSET(options, 0, sizeof(ecEncOptions)); + } +} + + +static int ecc_get_key_sizes(ecEncOptions* options, int* encKeySz, int* ivSz, + int* keysLen, word32* digestSz, word32* blockSz) +{ + if (options) { + switch (options->encAlgo) { + case ecAES_128_CBC: + *encKeySz = KEY_SIZE_128; + *ivSz = IV_SIZE_64; + *blockSz = AES_BLOCK_SIZE; + break; + default: + return BAD_FUNC_ARG; + } + + switch (options->macAlgo) { + case ecHMAC_SHA256: + *digestSz = SHA256_DIGEST_SIZE; + break; + default: + return BAD_FUNC_ARG; + } + } else + return BAD_FUNC_ARG; + + *keysLen = *encKeySz + *ivSz + *digestSz; + + return 0; +} + + +/* ecc encrypt with shared secret run through kdf + options holds non default algos and inputs + msgSz should be the right size for encAlgo, i.e., already padded + return 0 on success */ +int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, + word32 msgSz, byte* out, word32* outSz, ecEncOptions* opts) +{ + int ret; + word32 blockSz; + word32 digestSz; + ecEncOptions options; + byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ + byte keys[ECC_BUFSIZE]; /* max size */ + word32 sharedSz = sizeof(sharedSecret); + int keysLen; + int encKeySz; + int ivSz; + byte* encKey; + byte* encIv; + byte* macKey; + + if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || + outSz == NULL) + return BAD_FUNC_ARG; + + if (opts) + options = *opts; + else { + ecc_encrypt_init_options(&options); /* defaults */ + } + + ret = ecc_get_key_sizes(&options, &encKeySz, &ivSz, &keysLen, &digestSz, + &blockSz); + if (ret != 0) + return ret; + + if ( (msgSz%blockSz) != 0) + return BAD_FUNC_ARG; + + if (*outSz < (msgSz + digestSz)) + return BUFFER_E; + + ret = ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); + if (ret != 0) + return ret; + + switch (options.kdfAlgo) { + case ecHKDF_SHA256 : + ret = HKDF(SHA256, sharedSecret, sharedSz, options.kdfSalt, + options.kdfSaltSz, options.kdfInfo, + options.kdfInfoSz, keys, keysLen); + if (ret != 0) + return ret; + break; + + default: + return BAD_FUNC_ARG; + } + + encKey = keys; + encIv = encKey + encKeySz; + macKey = encKey + encKeySz + ivSz; + + switch (options.encAlgo) { + case ecAES_128_CBC: + { + Aes aes; + ret = AesSetKey(&aes, encKey,KEY_SIZE_128,encIv,AES_ENCRYPTION); + if (ret != 0) + return ret; + ret = AesCbcEncrypt(&aes, out, msg, msgSz); + if (ret != 0) + return ret; + } + break; + + default: + return BAD_FUNC_ARG; + } + + switch (options.macAlgo) { + case ecHMAC_SHA256: + { + Hmac hmac; + ret = HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE); + if (ret != 0) + return ret; + HmacUpdate(&hmac, out, msgSz); + HmacUpdate(&hmac, options.macSalt, options.macSaltSz); + HmacFinal(&hmac, out+msgSz); + } + break; + + default: + return BAD_FUNC_ARG; + } + + *outSz = msgSz + digestSz; + + return 0; +} + + +int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, + word32 msgSz, byte* out, word32* outSz, ecEncOptions* opts) +{ + int ret; + word32 blockSz; + word32 digestSz; + ecEncOptions options; + byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ + byte keys[ECC_BUFSIZE]; /* max size */ + word32 sharedSz = sizeof(sharedSecret); + int keysLen; + int encKeySz; + int ivSz; + byte* encKey; + byte* encIv; + byte* macKey; + + if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || + outSz == NULL) + return BAD_FUNC_ARG; + + if (opts) + options = *opts; + else { + ecc_encrypt_init_options(&options); /* defaults */ + } + + ret = ecc_get_key_sizes(&options, &encKeySz, &ivSz, &keysLen, &digestSz, + &blockSz); + if (ret != 0) + return ret; + + if ( ((msgSz-digestSz) % blockSz) != 0) + return BAD_FUNC_ARG; + + if (*outSz < (msgSz - digestSz)) + return BUFFER_E; + + ret = ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); + if (ret != 0) + return ret; + + switch (options.kdfAlgo) { + case ecHKDF_SHA256 : + ret = HKDF(SHA256, sharedSecret, sharedSz, options.kdfSalt, + options.kdfSaltSz, options.kdfInfo, + options.kdfInfoSz, keys, keysLen); + if (ret != 0) + return ret; + break; + + default: + return BAD_FUNC_ARG; + } + + encKey = keys; + encIv = encKey + encKeySz; + macKey = encKey + encKeySz + ivSz; + + switch (options.macAlgo) { + case ecHMAC_SHA256: + { + byte verify[SHA256_DIGEST_SIZE]; + Hmac hmac; + ret = HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE); + if (ret != 0) + return ret; + HmacUpdate(&hmac, msg, msgSz-digestSz); + HmacUpdate(&hmac, options.macSalt, options.macSaltSz); + HmacFinal(&hmac, verify); + + if (memcmp(verify, msg + msgSz - digestSz, digestSz) != 0) { + return -1; + } + } + break; + + default: + return BAD_FUNC_ARG; + } + + switch (options.encAlgo) { + case ecAES_128_CBC: + { + Aes aes; + ret = AesSetKey(&aes, encKey,KEY_SIZE_128,encIv,AES_DECRYPTION); + if (ret != 0) + return ret; + ret = AesCbcDecrypt(&aes, out, msg, msgSz-digestSz); + if (ret != 0) + return ret; + } + break; + + default: + return BAD_FUNC_ARG; + } + + *outSz = msgSz - digestSz; + + return 0; +} + + +#endif /* HAVE_ECC_ENCRYPT */ + #endif /* HAVE_ECC */ diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index 7ba1b0b39..5ba050838 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -164,6 +164,9 @@ int pkcs12_test(void); int pbkdf2_test(void); #ifdef HAVE_ECC int ecc_test(void); + #ifdef HAVE_ECC_ENCRYPT + int ecc_encrypt_test(void); + #endif #endif #ifdef HAVE_BLAKE2 int blake2b_test(void); @@ -440,6 +443,12 @@ void ctaocrypt_test(void* args) err_sys("ECC test failed!\n", ret); else printf( "ECC test passed!\n"); + #ifdef HAVE_ECC_ENCRYPT + if ( (ret = ecc_encrypt_test()) != 0) + err_sys("ECC Enc test failed!\n", ret); + else + printf( "ECC Enc test passed!\n"); + #endif #endif #ifdef HAVE_LIBZ @@ -3589,6 +3598,56 @@ int ecc_test(void) return 0; } +#ifdef HAVE_ECC_ENCRYPT + +int ecc_encrypt_test(void) +{ + RNG rng; + int ret; + ecc_key userA, userB; + byte msg[48]; + byte plain[48]; + byte out[80]; + word32 outSz = sizeof(out); + word32 plainSz = sizeof(plain); + int i; + + ret = InitRng(&rng); + if (ret != 0) + return -3001; + + ecc_init(&userA); + ecc_init(&userB); + + ret = ecc_make_key(&rng, 32, &userA); + ret += ecc_make_key(&rng, 32, &userB); + + if (ret != 0) + return -3002; + + for (i = 0; i < 48; i++) + msg[i] = i; + + /* send encrypted msg to B */ + ret = ecc_encrypt(&userA, &userB, msg, sizeof(msg), out, &outSz, NULL); + if (ret != 0) + return -3003; + + /* decrypted msg to B */ + ret = ecc_decrypt(&userB, &userA, out, outSz, plain, &plainSz, NULL); + if (ret != 0) + return -3004; + + if (memcmp(plain, msg, sizeof(msg)) != 0) + return -3005; + + ecc_free(&userB); + ecc_free(&userA); + + return 0; +} + +#endif /* HAVE_ECC_ENCRYPT */ #endif /* HAVE_ECC */ #ifdef HAVE_LIBZ diff --git a/cyassl/ctaocrypt/ecc.h b/cyassl/ctaocrypt/ecc.h index e88c10ab4..683429fec 100644 --- a/cyassl/ctaocrypt/ecc.h +++ b/cyassl/ctaocrypt/ecc.h @@ -119,6 +119,53 @@ CYASSL_API int ecc_sig_size(ecc_key* key); +/* ecc encrypt */ + +enum ecEncAlgo { + ecAES_128_CBC = 1, /* default */ + ecAES_256_CBC = 2 +}; + +enum ecKdfAlgo { + ecHKDF_SHA256 = 1, /* default */ + ecHKDF_SHA1 = 2 +}; + +enum ecMacAlgo { + ecHMAC_SHA256 = 1, /* default */ + ecHMAC_SHA1 = 2 +}; + +enum { + KEY_SIZE_128 = 16, + KEY_SIZE_256 = 32, + IV_SIZE_64 = 8 +}; + +typedef struct ecEncOptions { + byte encAlgo; /* which encryption type */ + byte kdfAlgo; /* which key derivation function type */ + byte macAlgo; /* which mac function type */ + byte* kdfSalt; /* optional salt for kdf */ + byte* kdfInfo; /* optional info for kdf */ + byte* macSalt; /* optional salt for mac */ + word32 kdfSaltSz; /* size of kdfSalt */ + word32 kdfInfoSz; /* size of kdfInfo */ + word32 macSaltSz; /* size of macSalt */ +} ecEncOptions; + +CYASSL_API +void ecc_encrypt_init_options(ecEncOptions*); /* init and set to defaults */ +CYASSL_API +void ecc_encrypt_free_options(ecEncOptions*); /* release/clear options */ + +CYASSL_API +int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, + word32 msgSz, byte* out, word32* outSz, ecEncOptions* options); +CYASSL_API +int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, + word32 msgSz, byte* out, word32* outSz, ecEncOptions* options); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/cyassl/internal.h b/cyassl/internal.h index 950900446..32b8964bf 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1666,6 +1666,9 @@ struct CYASSL_X509 { byte notBefore[MAX_DATE_SZ]; int notAfterSz; byte notAfter[MAX_DATE_SZ]; + int sigOID; + buffer sig; + int pubKeyOID; buffer pubKey; buffer derCert; /* may need */ DNS_entry* altNames; /* alt names list */ diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 1fd697712..bd5f25c38 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -418,6 +418,8 @@ CYASSL_API int CyaSSL_X509_NAME_get_text_by_NID( CYASSL_X509_NAME*, int, char*, int); CYASSL_API int CyaSSL_X509_verify_cert(CYASSL_X509_STORE_CTX*); CYASSL_API const char* CyaSSL_X509_verify_cert_error_string(long); +CYASSL_API int CyaSSL_X509_get_signature_type(CYASSL_X509*); +CYASSL_API int CyaSSL_X509_get_signature(CYASSL_X509*, unsigned char*, int*); CYASSL_API int CyaSSL_X509_LOOKUP_add_dir(CYASSL_X509_LOOKUP*,const char*,long); CYASSL_API int CyaSSL_X509_LOOKUP_load_file(CYASSL_X509_LOOKUP*, const char*, diff --git a/src/internal.c b/src/internal.c index 4344b4723..92194f5de 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1266,6 +1266,7 @@ void InitX509(CYASSL_X509* x509, int dynamicFlag) InitX509Name(&x509->subject, 0); x509->version = 0; x509->pubKey.buffer = NULL; + x509->sig.buffer = NULL; x509->derCert.buffer = NULL; x509->altNames = NULL; x509->altNamesNext = NULL; @@ -1284,6 +1285,7 @@ void FreeX509(CYASSL_X509* x509) if (x509->pubKey.buffer) XFREE(x509->pubKey.buffer, NULL, DYNAMIC_TYPE_PUBLIC_KEY); XFREE(x509->derCert.buffer, NULL, DYNAMIC_TYPE_SUBJECT_CN); + XFREE(x509->sig.buffer, NULL, 0); if (x509->altNames) FreeAltNames(x509->altNames, NULL); if (x509->dynamicMemory) @@ -3121,6 +3123,7 @@ int CopyDecodedToX509(CYASSL_X509* x509, DecodedCert* dCert) x509->pubKey.buffer = (byte*)XMALLOC( dCert->pubKeySize, NULL, DYNAMIC_TYPE_PUBLIC_KEY); if (x509->pubKey.buffer != NULL) { + x509->pubKeyOID = dCert->keyOID; x509->pubKey.length = dCert->pubKeySize; XMEMCPY(x509->pubKey.buffer, dCert->publicKey, dCert->pubKeySize); } @@ -3128,6 +3131,17 @@ int CopyDecodedToX509(CYASSL_X509* x509, DecodedCert* dCert) ret = MEMORY_E; } + x509->sig.buffer = (byte*)XMALLOC(dCert->sigLength, NULL, 0); + if (x509->sig.buffer == NULL) { + ret = MEMORY_E; + } + else { + XMEMCPY(x509->sig.buffer, + &dCert->source[dCert->sigIndex], dCert->sigLength); + x509->sig.length = dCert->sigLength; + x509->sigOID = dCert->signatureOID; + } + /* store cert for potential retrieval */ x509->derCert.buffer = (byte*)XMALLOC(dCert->maxIdx, NULL, DYNAMIC_TYPE_CERT); diff --git a/src/ssl.c b/src/ssl.c index ff71f277c..f17449376 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -7143,13 +7143,42 @@ int CyaSSL_set_compression(CYASSL* ssl) } + int CyaSSL_X509_get_signature_type(CYASSL_X509* x509) + { + int type = 0; + + CYASSL_ENTER("CyaSSL_X509_get_signature_type"); + + if (x509 != NULL) + type = x509->sigOID; + + return type; + } + + + int CyaSSL_X509_get_signature(CYASSL_X509* x509, + unsigned char* buf, int* bufSz) + { + CYASSL_ENTER("CyaSSL_X509_get_signature"); + if (x509 == NULL || bufSz == NULL || *bufSz < (int)x509->sig.length) + return SSL_FATAL_ERROR; + + if (buf != NULL) + XMEMCPY(buf, x509->sig.buffer, x509->sig.length); + *bufSz = x509->sig.length; + + return SSL_SUCCESS; + } + + /* write X509 serial number in unsigned binary to buffer buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases return SSL_SUCCESS on success */ int CyaSSL_X509_get_serial_number(CYASSL_X509* x509, byte* in, int* inOutSz) { CYASSL_ENTER("CyaSSL_X509_get_serial_number"); - if (x509 == NULL || in == NULL || *inOutSz < x509->serialSz) + if (x509 == NULL || in == NULL || + inOutSz == NULL || *inOutSz < x509->serialSz) return BAD_FUNC_ARG; XMEMCPY(in, x509->serial, x509->serialSz); @@ -8289,7 +8318,7 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format) key = (CYASSL_EVP_PKEY*)XMALLOC( sizeof(CYASSL_EVP_PKEY), NULL, DYNAMIC_TYPE_PUBLIC_KEY); if (key != NULL) { - key->type = 0; + key->type = x509->pubKeyOID; key->save_type = 0; key->pkey.ptr = (char*)XMALLOC( x509->pubKey.length, NULL, DYNAMIC_TYPE_PUBLIC_KEY);