From e63fa491aa5884f3914dae8ac648e726221d2fdf Mon Sep 17 00:00:00 2001 From: toddouska Date: Thu, 21 Mar 2013 13:20:23 -0700 Subject: [PATCH] add mcapi ecc with tests --- configure.ac | 5 ++ mcapi/crypto.c | 118 +++++++++++++++++++++++++++++++++++++++ mcapi/crypto.h | 30 ++++++++++ mcapi/test.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 298 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ea4fb0898..1824a089c 100644 --- a/configure.ac +++ b/configure.ac @@ -1179,6 +1179,11 @@ then AC_MSG_ERROR([please enable sha512 if enabling mcapi.]) fi +if test "$ENABLED_MCAPI" = "yes" && test "$ENABLED_ECC" = "no" +then + AC_MSG_ERROR([please enable ecc if enabling mcapi.]) +fi + if test "$ENABLED_MCAPI" = "yes" && test "$ENABLED_LIBZ" = "no" then AC_MSG_ERROR([please use --with-libz if enabling mcapi.]) diff --git a/mcapi/crypto.c b/mcapi/crypto.c index dcb5a3445..11eed51be 100644 --- a/mcapi/crypto.c +++ b/mcapi/crypto.c @@ -36,6 +36,7 @@ #include #include #include +#include /* Initialize MD5 */ @@ -461,5 +462,122 @@ int CRYPT_RSA_EncryptSizeGet(CRYPT_RSA_CTX* rsa) } +/* ECC init */ +int CRYPT_ECC_Initialize(CRYPT_ECC_CTX* ecc) +{ + ecc->holder = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC); + if (ecc->holder == NULL) + return -1; + + ecc_init((ecc_key*)ecc->holder); + + return 0; +} + + +/* ECC free resources */ +int CRYPT_ECC_Free(CRYPT_ECC_CTX* ecc) +{ + ecc_free((ecc_key*)ecc->holder); + XFREE(ecc->holder, NULL, DYNAMIC_TYPE_ECC); + ecc->holder = NULL; + + return 0; +} + + +/* ECC Public x963 Export */ +int CRYPT_ECC_PublicExport(CRYPT_ECC_CTX* ecc, unsigned char* out, + unsigned int outSz, unsigned int* usedSz) +{ + int ret; + unsigned int inOut = outSz; + + ret = ecc_export_x963((ecc_key*)ecc->holder, out, &inOut); + *usedSz = inOut; + + return ret; +} + + +/* ECC Public x963 Import */ +int CRYPT_ECC_PublicImport(CRYPT_ECC_CTX* ecc, const unsigned char* in, + unsigned int inSz) +{ + return ecc_import_x963(in, inSz, (ecc_key*)ecc->holder); +} + + +/* ECC Private x963 Import */ +int CRYPT_ECC_PrivateImport(CRYPT_ECC_CTX* ecc, const unsigned char* priv, + unsigned int privSz, const unsigned char* pub, unsigned int pubSz) +{ + return ecc_import_private_key(priv, privSz, pub, pubSz, + (ecc_key*)ecc->holder); +} + + +/* ECC DHE Make key */ +int CRYPT_ECC_DHE_KeyMake(CRYPT_ECC_CTX* ecc, CRYPT_RNG_CTX* rng, int keySz) +{ + return ecc_make_key((RNG*)rng, keySz, (ecc_key*)ecc->holder); +} + + +/* ECC DHE Make shared secret with our private and peer public */ +int CRYPT_ECC_DHE_SharedSecretMake(CRYPT_ECC_CTX* priv, CRYPT_ECC_CTX* pub, + unsigned char* out, unsigned int outSz, unsigned int* usedSz) +{ + int ret; + unsigned int inOut = outSz; + + ret = ecc_shared_secret((ecc_key*)priv->holder, (ecc_key*)pub->holder, + out, &inOut); + *usedSz = inOut; + + return ret; +} + + +/* ECC DSA Hash Sign */ +int CRYPT_ECC_DSA_HashSign(CRYPT_ECC_CTX* ecc, CRYPT_RNG_CTX* rng, + unsigned char* sig, unsigned int sigSz, + unsigned int* usedSz, const unsigned char* in, + unsigned int inSz) +{ + int ret; + unsigned int inOut = sigSz; + + ret = ecc_sign_hash(in, inSz, sig, &inOut, (RNG*)rng, + (ecc_key*)ecc->holder); + *usedSz = inOut; + + return ret; +} + + +/* ECC DSA Hash Verify */ +int CRYPT_ECC_DSA_HashVerify(CRYPT_ECC_CTX* ecc, const unsigned char* sig, + unsigned int sigSz, unsigned char* hash, + unsigned int hashSz, int* status) +{ + return ecc_verify_hash(sig, sigSz, hash, hashSz, status, + (ecc_key*)ecc->holder); +} + + +/* ECC get key size helper */ +int CRYPT_ECC_KeySizeGet(CRYPT_ECC_CTX* ecc) +{ + return ecc_size((ecc_key*)ecc->holder); +} + + +/* ECC get signature size helper */ +int CRYPT_ECC_SignatureSizeGet(CRYPT_ECC_CTX* ecc) +{ + return ecc_sig_size((ecc_key*)ecc->holder); +} + diff --git a/mcapi/crypto.h b/mcapi/crypto.h index e8d14c86a..e77a6fef4 100644 --- a/mcapi/crypto.h +++ b/mcapi/crypto.h @@ -223,6 +223,36 @@ int CRYPT_RSA_EncryptSizeGet(CRYPT_RSA_CTX*); +/* ECC */ +typedef struct CRYPT_ECC_CTX { + void* holder; +} CRYPT_ECC_CTX; + +/* init/free */ +int CRYPT_ECC_Initialize(CRYPT_ECC_CTX*); +int CRYPT_ECC_Free(CRYPT_ECC_CTX*); + +/* key coders */ +int CRYPT_ECC_PublicExport(CRYPT_ECC_CTX*, unsigned char*, unsigned int, + unsigned int*); +int CRYPT_ECC_PublicImport(CRYPT_ECC_CTX*, const unsigned char*, unsigned int); +int CRYPT_ECC_PrivateImport(CRYPT_ECC_CTX*, const unsigned char*, unsigned int, + const unsigned char*, unsigned int); + +/* dhe */ +int CRYPT_ECC_DHE_KeyMake(CRYPT_ECC_CTX*, CRYPT_RNG_CTX*, int); +int CRYPT_ECC_DHE_SharedSecretMake(CRYPT_ECC_CTX*, CRYPT_ECC_CTX*, + unsigned char*, unsigned int, unsigned int*); + +/* dsa */ +int CRYPT_ECC_DSA_HashSign(CRYPT_ECC_CTX*, CRYPT_RNG_CTX*, unsigned char*, + unsigned int, unsigned int*, const unsigned char*, unsigned int); +int CRYPT_ECC_DSA_HashVerify(CRYPT_ECC_CTX*, const unsigned char*, + unsigned int, unsigned char*, unsigned int, int*); + +/* helpers */ +int CRYPT_ECC_KeySizeGet(CRYPT_ECC_CTX*); +int CRYPT_ECC_SignatureSizeGet(CRYPT_ECC_CTX*); #ifdef __cplusplus diff --git a/mcapi/test.c b/mcapi/test.c index f940aedd7..04093e3b3 100644 --- a/mcapi/test.c +++ b/mcapi/test.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #define USE_CERT_BUFFERS_1024 #include @@ -70,6 +71,7 @@ static int check_aescbc(void); static int check_aesctr(void); static int check_aesdirect(void); static int check_rsa(void); +static int check_ecc(void); int main(int argc, char** argv) @@ -178,7 +180,11 @@ int main(int argc, char** argv) return -1; } - + ret = check_ecc(); + if (ret != 0) { + printf("mcapi check_ecc failed\n"); + return -1; + } XFREE(iv, NULL, DYNAMIC_TYPE_KEY); XFREE(key, NULL, DYNAMIC_TYPE_KEY); @@ -1204,10 +1210,148 @@ static int check_rsa(void) return -1; } + FreeRsaKey(&defRsa); + ret = CRYPT_RSA_Free(&mcRsa); + if (ret != 0) { + printf("mcapi rsa free failed\n"); + return -1; + } + printf("rsa mcapi test passed\n"); return 0; } +/* check mcapi ecc */ +static int check_ecc(void) +{ + CRYPT_ECC_CTX userA; + CRYPT_ECC_CTX userB; + int ret; + byte sharedA[100]; + byte sharedB[100]; + byte sig[100]; + unsigned int aSz = (unsigned int)sizeof(sharedA); + unsigned int bSz = (unsigned int)sizeof(sharedB); + unsigned int sigSz = (unsigned int)sizeof(sig); + unsigned int usedA = 0; + unsigned int usedB = 0; + int verifyStatus = 0; + + /* init */ + ret = CRYPT_ECC_Initialize(&userA); + if (ret != 0) { + printf("mcapi ecc init failed\n"); + return -1; + } + + ret = CRYPT_ECC_Initialize(&userB); + if (ret != 0) { + printf("mcapi ecc init b failed\n"); + return -1; + } + + /* dhe + helpers */ + ret = CRYPT_ECC_DHE_KeyMake(&userA, &mcRng, 32); + if (ret != 0) { + printf("mcapi ecc make key failed\n"); + return -1; + } + + ret = CRYPT_ECC_DHE_KeyMake(&userB, &mcRng, 32); + if (ret != 0) { + printf("mcapi ecc make key b failed\n"); + return -1; + } + + ret = CRYPT_ECC_KeySizeGet(&userA); + if (ret <= 0) { + printf("mcapi ecc key size get failed\n"); + return -1; + } + + ret = CRYPT_ECC_SignatureSizeGet(&userA); + if (ret <= 0) { + printf("mcapi ecc signature size get failed\n"); + return -1; + } + + ret = CRYPT_ECC_DHE_SharedSecretMake(&userA, &userB, sharedA, aSz, &usedA); + if (ret != 0) { + printf("mcapi ecc make shared secret failed\n"); + return -1; + } + + ret = CRYPT_ECC_DHE_SharedSecretMake(&userB, &userA, sharedB, bSz, &usedB); + if (ret != 0) { + printf("mcapi ecc make shared secret failed\n"); + return -1; + } + + if (usedA != usedB || usedA <= 0) { + printf("mcapi ecc make shared secret output size match failed\n"); + return -1; + } + + if (memcmp(sharedA, sharedB, usedA) != 0) { + printf("mcapi ecc make shared secret output match cmp failed\n"); + return -1; + } + + /* dsa */ + ret = CRYPT_ECC_DSA_HashSign(&userA, &mcRng, sig, sigSz, &usedA, ourData, + CRYPT_SHA_DIGEST_SIZE); + if (ret != 0) { + printf("mcapi ecc sign hash failed\n"); + return -1; + } + + sigSz = usedA; + if (sigSz <= 0) { + printf("mcapi ecc sign hash bad sig size\n"); + return -1; + } + + ret = CRYPT_ECC_DSA_HashVerify(&userA, sig, sigSz, ourData, + CRYPT_SHA_DIGEST_SIZE, &verifyStatus); + if (ret != 0) { + printf("mcapi ecc verify hash failed\n"); + return -1; + } + if (verifyStatus != 1) { + printf("mcapi ecc verify hash status failed\n"); + return -1; + } + + /* import / export */ + usedA = 0; + ret = CRYPT_ECC_PublicExport(&userA, sharedA, aSz, &usedA); + if (ret != 0) { + printf("mcapi ecc public export failed\n"); + return -1; + } + + ret = CRYPT_ECC_PublicImport(&userB, sharedA, usedA); + if (ret != 0) { + printf("mcapi ecc public import failed\n"); + return -1; + } + + ret = CRYPT_ECC_Free(&userA); + if (ret != 0) { + printf("mcapi ecc free failed\n"); + return -1; + } + + ret = CRYPT_ECC_Free(&userB); + if (ret != 0) { + printf("mcapi ecc free b failed\n"); + return -1; + } + + printf("ecc mcapi test passed\n"); + + return 0; +}