diff --git a/src/internal.c b/src/internal.c index e90b4a224..d0de1a8aa 100755 --- a/src/internal.c +++ b/src/internal.c @@ -6622,6 +6622,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifdef HAVE_ECC case ECDSAk: { + int curveId; if (ssl->peerEccDsaKey == NULL) { /* alloc/init on demand */ ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key), @@ -6637,8 +6638,10 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, ssl->peerEccDsaKeyPresent = 0; wc_ecc_init_h(ssl->peerEccDsaKey, ssl->heap); } - if (wc_ecc_import_x963(dCert->publicKey, dCert->pubKeySize, - ssl->peerEccDsaKey) != 0) { + + curveId = wc_ecc_get_oid(dCert->keyOID, NULL, NULL); + if (wc_ecc_import_x963_ex(dCert->publicKey, + dCert->pubKeySize, ssl->peerEccDsaKey, curveId) != 0) { ret = PEER_KEY_ERROR; } else { @@ -13194,33 +13197,67 @@ static void PickHashSigAlgo(WOLFSSL* ssl, #ifdef HAVE_ECC - static int CheckCurveId(int oid) + static int CheckCurveId(int tlsCurveId) { - int ret = 0; + int ret = ECC_CURVE_ERROR; - switch (oid) { -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160) - case WOLFSSL_ECC_SECP160R1: -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192) - case WOLFSSL_ECC_SECP192R1: -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224) - case WOLFSSL_ECC_SECP224R1: -#endif -#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256) - case WOLFSSL_ECC_SECP256R1: -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384) - case WOLFSSL_ECC_SECP384R1: -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521) - case WOLFSSL_ECC_SECP521R1: -#endif - break; - - default: - ret = -1; + switch (tlsCurveId) { + #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case WOLFSSL_ECC_SECP160R1: return ECC_SECP160R1_OID; + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_SECPR2 + case WOLFSSL_ECC_SECP160R2: return ECC_SECP160R2_OID; + #endif /* HAVE_ECC_SECPR2 */ + #ifdef HAVE_ECC_KOBLITZ + case WOLFSSL_ECC_SECP160K1: return ECC_SECP160K1_OID; + #endif /* HAVE_ECC_KOBLITZ */ + #endif + #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case WOLFSSL_ECC_SECP192R1: return ECC_SECP192R1_OID; + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_KOBLITZ + case WOLFSSL_ECC_SECP192K1: return ECC_SECP192K1_OID; + #endif /* HAVE_ECC_KOBLITZ */ + #endif + #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case WOLFSSL_ECC_SECP224R1: return ECC_SECP224R1_OID; + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_KOBLITZ + case WOLFSSL_ECC_SECP224K1: return ECC_SECP224K1_OID; + #endif /* HAVE_ECC_KOBLITZ */ + #endif + #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case WOLFSSL_ECC_SECP256R1: return ECC_SECP256R1_OID; + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_KOBLITZ + case WOLFSSL_ECC_SECP256K1: return ECC_SECP256K1_OID; + #endif /* HAVE_ECC_KOBLITZ */ + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP256R1: return ECC_BRAINPOOLP256R1_OID; + #endif /* HAVE_ECC_BRAINPOOL */ + #endif + #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case WOLFSSL_ECC_SECP384R1: return ECC_SECP384R1_OID; + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP384R1: return ECC_BRAINPOOLP384R1_OID; + #endif /* HAVE_ECC_BRAINPOOL */ + #endif + #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP512R1: return ECC_BRAINPOOLP512R1_OID; + #endif /* HAVE_ECC_BRAINPOOL */ + #endif + #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case WOLFSSL_ECC_SECP521R1: return ECC_SECP521R1_OID; + #endif /* !NO_ECC_SECP */ + #endif } return ret; @@ -13397,6 +13434,7 @@ static void PickHashSigAlgo(WOLFSSL* ssl, case ecc_diffie_hellman_kea: { byte b; + int curveId, curveOid; if ((*inOutIdx - begin) + ENUM_LEN + OPAQUE16_LEN + OPAQUE8_LEN > size) { @@ -13412,8 +13450,8 @@ static void PickHashSigAlgo(WOLFSSL* ssl, *inOutIdx += 1; /* curve type, eat leading 0 */ b = input[(*inOutIdx)++]; - if (CheckCurveId(b) != 0) { - return ECC_CURVE_ERROR; + if ((curveOid = CheckCurveId(b)) < 0) { + return curveOid; } length = input[(*inOutIdx)++]; @@ -13437,8 +13475,9 @@ static void PickHashSigAlgo(WOLFSSL* ssl, wc_ecc_init_h(ssl->peerEccKey, ssl->heap); } - if (wc_ecc_import_x963(input + *inOutIdx, length, - ssl->peerEccKey) != 0) { + curveId = wc_ecc_get_oid(curveOid, NULL, NULL); + if (wc_ecc_import_x963_ex(input + *inOutIdx, length, + ssl->peerEccKey, curveId) != 0) { return ECC_PEERKEY_ERROR; } @@ -13560,6 +13599,7 @@ static void PickHashSigAlgo(WOLFSSL* ssl, case ecdhe_psk_kea: { byte b; + int curveOid, curveId; if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { return BUFFER_ERROR; @@ -13593,8 +13633,8 @@ static void PickHashSigAlgo(WOLFSSL* ssl, *inOutIdx += 1; /* curve type, eat leading 0 */ b = input[(*inOutIdx)++]; - if (CheckCurveId(b) != 0) { - return ECC_CURVE_ERROR; + if ((curveOid = CheckCurveId(b)) < 0) { + return curveOid; } length = input[(*inOutIdx)++]; @@ -13618,8 +13658,9 @@ static void PickHashSigAlgo(WOLFSSL* ssl, wc_ecc_init_h(ssl->peerEccKey, ssl->heap); } - if (wc_ecc_import_x963(input + *inOutIdx, length, - ssl->peerEccKey) != 0) { + curveId = wc_ecc_get_oid(curveOid, NULL, NULL); + if (wc_ecc_import_x963_ex(input + *inOutIdx, length, + ssl->peerEccKey, curveId) != 0) { return ECC_PEERKEY_ERROR; } @@ -14995,7 +15036,7 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) } wc_ecc_init_h(&myKey, ssl->heap); - ret = wc_ecc_make_key(ssl->rng, peerKey->dp->size, &myKey); + ret = wc_ecc_make_key_ex(ssl->rng, 0, &myKey, peerKey->dp->id); if (ret != 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -15765,33 +15806,84 @@ int DoSessionTicket(WOLFSSL* ssl, #ifdef HAVE_ECC - static byte SetCurveId(int size) + static byte SetCurveId(ecc_key* key) { - switch(size) { -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160) - case 20: + if (key == NULL || key->dp == NULL) { + WOLFSSL_MSG("SetCurveId: Invalid key!"); + return 0; + } + + switch(key->dp->oidSum) { + #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case ECC_SECP160R1_OID: return WOLFSSL_ECC_SECP160R1; -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192) - case 24: + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_SECPR2 + case ECC_SECP160R2_OID: + return WOLFSSL_ECC_SECP160R2; + #endif /* HAVE_ECC_SECPR2 */ + #ifdef HAVE_ECC_KOBLITZ + case ECC_SECP160K1_OID: + return WOLFSSL_ECC_SECP160K1; + #endif /* HAVE_ECC_KOBLITZ */ + #endif + #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case ECC_SECP192R1_OID: return WOLFSSL_ECC_SECP192R1; -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224) - case 28: + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_KOBLITZ + case ECC_SECP192K1_OID: + return WOLFSSL_ECC_SECP192K1; + #endif /* HAVE_ECC_KOBLITZ */ + #endif + #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case ECC_SECP224R1_OID: return WOLFSSL_ECC_SECP224R1; -#endif -#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256) - case 32: + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_KOBLITZ + case ECC_SECP224K1_OID: + return WOLFSSL_ECC_SECP224K1; + #endif /* HAVE_ECC_KOBLITZ */ + #endif + #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case ECC_SECP256R1_OID: return WOLFSSL_ECC_SECP256R1; -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384) - case 48: + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_KOBLITZ + case ECC_SECP256K1_OID: + return WOLFSSL_ECC_SECP256K1; + #endif /* HAVE_ECC_KOBLITZ */ + #ifdef HAVE_ECC_BRAINPOOL + case ECC_BRAINPOOLP256R1_OID: + return WOLFSSL_ECC_BRAINPOOLP256R1; + #endif /* HAVE_ECC_BRAINPOOL */ + #endif + #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case ECC_SECP384R1_OID: return WOLFSSL_ECC_SECP384R1; -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521) - case 66: + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_BRAINPOOL + case ECC_BRAINPOOLP384R1_OID: + return WOLFSSL_ECC_BRAINPOOLP384R1; + #endif /* HAVE_ECC_BRAINPOOL */ + #endif + #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) + #ifdef HAVE_ECC_BRAINPOOL + case ECC_BRAINPOOLP512R1_OID: + return WOLFSSL_ECC_BRAINPOOLP512R1; + #endif /* HAVE_ECC_BRAINPOOL */ + #endif + #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case ECC_SECP521R1_OID: return WOLFSSL_ECC_SECP521R1; -#endif + #endif /* !NO_ECC_SECP */ + #endif default: return 0; } @@ -16164,7 +16256,7 @@ int DoSessionTicket(WOLFSSL* ssl, /* ECC key exchange data */ output[idx++] = named_curve; output[idx++] = 0x00; /* leading zero */ - output[idx++] = SetCurveId(wc_ecc_size(ssl->eccTempKey)); + output[idx++] = SetCurveId(ssl->eccTempKey); output[idx++] = (byte)exportSz; XMEMCPY(output + idx, exportBuf, exportSz); break; @@ -16303,7 +16395,7 @@ int DoSessionTicket(WOLFSSL* ssl, /* key exchange data */ output[idx++] = named_curve; output[idx++] = 0x00; /* leading zero */ - output[idx++] = SetCurveId(wc_ecc_size(ssl->eccTempKey)); + output[idx++] = SetCurveId(ssl->eccTempKey); output[idx++] = (byte)exportSz; XMEMCPY(output + idx, exportBuf, exportSz); idx += exportSz; @@ -18287,6 +18379,11 @@ int DoSessionTicket(WOLFSSL* ssl, #ifdef HAVE_ECC case ecc_diffie_hellman_kea: { + if (!ssl->specs.static_ecdh && + ssl->eccTempKeyPresent == 0) { + WOLFSSL_MSG("Ecc ephemeral key not made correctly"); + ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); + } break; } #endif /* HAVE_ECC */ @@ -18315,6 +18412,11 @@ int DoSessionTicket(WOLFSSL* ssl, WOLFSSL_MSG("No server PSK callback set"); ERROR_OUT(PSK_KEY_ERROR, exit_dcke); } + + if (ssl->eccTempKeyPresent == 0) { + WOLFSSL_MSG("Ecc ephemeral key not made correctly"); + ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); + } break; } #endif /* HAVE_ECC && !NO_PSK */ @@ -18504,40 +18606,7 @@ int DoSessionTicket(WOLFSSL* ssl, { ecc_key* private_key = ssl->eccTempKey; - if ((idx - begin) + OPAQUE8_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dcke); - } - - length = input[idx++]; - - if ((idx - begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, exit_dcke); - } - - if (ssl->peerEccKey == NULL) { - /* alloc/init on demand */ - ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), - ssl->heap, DYNAMIC_TYPE_ECC); - if (ssl->peerEccKey == NULL) { - WOLFSSL_MSG("PeerEccKey Memory error"); - ERROR_OUT(MEMORY_E, exit_dcke); - } - wc_ecc_init_h(ssl->peerEccKey, ssl->heap); - } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ - wc_ecc_free(ssl->peerEccKey); - ssl->peerEccKeyPresent = 0; - wc_ecc_init_h(ssl->peerEccKey, ssl->heap); - } - - if (wc_ecc_import_x963(input + idx, length, ssl->peerEccKey)) { - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); - } - - idx += length; - ssl->peerEccKeyPresent = 1; - - ssl->sigLen = sizeof(ssl->arrays->preMasterSecret); - + /* handle static private key */ if (ssl->specs.static_ecdh) { word32 i = 0; @@ -18564,10 +18633,43 @@ int DoSessionTicket(WOLFSSL* ssl, } } } - else if (ssl->eccTempKeyPresent == 0) { - WOLFSSL_MSG("Ecc ephemeral key not made correctly"); - ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); + + /* import peer ECC key */ + if ((idx - begin) + OPAQUE8_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dcke); } + + length = input[idx++]; + + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dcke); + } + + if (ssl->peerEccKey == NULL) { + /* alloc/init on demand */ + ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), + ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->peerEccKey == NULL) { + WOLFSSL_MSG("PeerEccKey Memory error"); + ERROR_OUT(MEMORY_E, exit_dcke); + } + wc_ecc_init_h(ssl->peerEccKey, ssl->heap); + } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ + wc_ecc_free(ssl->peerEccKey); + ssl->peerEccKeyPresent = 0; + wc_ecc_init_h(ssl->peerEccKey, ssl->heap); + } + + if (wc_ecc_import_x963_ex(input + idx, length, ssl->peerEccKey, + private_key->dp->id)) { + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); + } + + idx += length; + ssl->peerEccKeyPresent = 1; + + ssl->sigLen = sizeof(ssl->arrays->preMasterSecret); + if (ret != 0) { ERROR_OUT(ECC_SHARED_ERROR, exit_dcke); } @@ -18713,7 +18815,7 @@ int DoSessionTicket(WOLFSSL* ssl, ssl->arrays->client_identity[ min(clientSz, MAX_PSK_ID_LEN-1)] = 0; - /* ECC key */ + /* import peer ECC key */ if ((idx - begin) + OPAQUE8_LEN > size) { ERROR_OUT(BUFFER_ERROR, exit_dcke); } @@ -18738,8 +18840,8 @@ int DoSessionTicket(WOLFSSL* ssl, ssl->peerEccKeyPresent = 0; wc_ecc_init_h(ssl->peerEccKey, ssl->heap); } - if (wc_ecc_import_x963(input + idx, length, - ssl->peerEccKey)) { + if (wc_ecc_import_x963_ex(input + idx, length, + ssl->peerEccKey, ssl->eccTempKey->dp->id)) { ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); } @@ -18749,11 +18851,6 @@ int DoSessionTicket(WOLFSSL* ssl, /* Note sizeof preMasterSecret is ENCRYPT_LEN currently 512 */ ssl->sigLen = sizeof(ssl->arrays->preMasterSecret); - if (ssl->eccTempKeyPresent == 0) { - WOLFSSL_MSG("Ecc ephemeral key not made correctly"); - ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); - } - /* Generate shared secret */ ret = EccSharedSecret(ssl, ssl->eccTempKey, diff --git a/src/ssl.c b/src/ssl.c index 81bd82c7a..3e54b519f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1284,12 +1284,20 @@ int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name) return BAD_FUNC_ARG; switch (name) { + case WOLFSSL_ECC_SECP160K1: case WOLFSSL_ECC_SECP160R1: + case WOLFSSL_ECC_SECP160R2: + case WOLFSSL_ECC_SECP192K1: case WOLFSSL_ECC_SECP192R1: + case WOLFSSL_ECC_SECP224K1: case WOLFSSL_ECC_SECP224R1: + case WOLFSSL_ECC_SECP256K1: case WOLFSSL_ECC_SECP256R1: case WOLFSSL_ECC_SECP384R1: case WOLFSSL_ECC_SECP521R1: + case WOLFSSL_ECC_BRAINPOOLP256R1: + case WOLFSSL_ECC_BRAINPOOLP384R1: + case WOLFSSL_ECC_BRAINPOOLP512R1: break; default: @@ -1306,12 +1314,20 @@ int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name) return BAD_FUNC_ARG; switch (name) { + case WOLFSSL_ECC_SECP160K1: case WOLFSSL_ECC_SECP160R1: + case WOLFSSL_ECC_SECP160R2: + case WOLFSSL_ECC_SECP192K1: case WOLFSSL_ECC_SECP192R1: + case WOLFSSL_ECC_SECP224K1: case WOLFSSL_ECC_SECP224R1: + case WOLFSSL_ECC_SECP256K1: case WOLFSSL_ECC_SECP256R1: case WOLFSSL_ECC_SECP384R1: case WOLFSSL_ECC_SECP521R1: + case WOLFSSL_ECC_BRAINPOOLP256R1: + case WOLFSSL_ECC_BRAINPOOLP384R1: + case WOLFSSL_ECC_BRAINPOOLP512R1: break; default: @@ -15784,7 +15800,7 @@ static int SetECKeyExternal(WOLFSSL_EC_KEY* eckey) key = (ecc_key*)eckey->internal; /* set group (nid and idx) */ - eckey->group->curve_nid = ecc_sets[key->idx].nid; + eckey->group->curve_nid = ecc_sets[key->idx].id; eckey->group->curve_idx = key->idx; if (eckey->pub_key->internal != NULL) { @@ -15955,7 +15971,7 @@ WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid) /* search and set the corresponding internal curve idx */ for (x = 0; ecc_sets[x].size != 0; x++) - if (ecc_sets[x].nid == key->group->curve_nid) { + if (ecc_sets[x].id == key->group->curve_nid) { key->group->curve_idx = x; break; } @@ -16111,8 +16127,8 @@ int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key) return 0; } - if (wc_ecc_make_key(rng, ecc_sets[key->group->curve_idx].size, - (ecc_key*)key->internal) != MP_OKAY) { + if (wc_ecc_make_key_ex(rng, 0, (ecc_key*)key->internal, + key->group->curve_nid) != MP_OKAY) { WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key wc_ecc_make_key failed"); #ifdef WOLFSSL_SMALL_STACK XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -16288,7 +16304,7 @@ WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_new_by_curve_name(int nid) /* search and set the corresponding internal curve idx */ for (x = 0; ecc_sets[x].size != 0; x++) - if (ecc_sets[x].nid == g->curve_nid) { + if (ecc_sets[x].id == g->curve_nid) { g->curve_idx = x; break; } @@ -16325,22 +16341,37 @@ int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group) switch(group->curve_nid) { case NID_secp112r1: + case NID_secp112r2: return 112; case NID_secp128r1: + case NID_secp128r2: return 128; + case NID_secp160k1: case NID_secp160r1: + case NID_secp160r2: + case NID_brainpoolP160r1: return 160; + case NID_secp192k1: + case NID_brainpoolP192r1: case NID_X9_62_prime192v1: return 192; + case NID_secp224k1: case NID_secp224r1: + case NID_brainpoolP224r1: return 224; + case NID_secp256k1: + case NID_brainpoolP256r1: case NID_X9_62_prime256v1: return 256; + case NID_brainpoolP320r1: + return 320; case NID_secp384r1: + case NID_brainpoolP384r1: return 384; case NID_secp521r1: + case NID_brainpoolP512r1: return 521; - default : + default: return SSL_FAILURE; } } diff --git a/src/tls.c b/src/tls.c index 494bcafb5..cce57899d 100644 --- a/src/tls.c +++ b/src/tls.c @@ -2778,26 +2778,64 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) { return 1; /* no suite restriction */ for (curve = extension->data; curve && !(sig && key); curve = curve->next) { - + /* find supported curve */ switch (curve->name) { -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160) - case WOLFSSL_ECC_SECP160R1: oid = ECC_160R1; octets = 20; break; -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192) - case WOLFSSL_ECC_SECP192R1: oid = ECC_192R1; octets = 24; break; -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224) - case WOLFSSL_ECC_SECP224R1: oid = ECC_224R1; octets = 28; break; -#endif -#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256) - case WOLFSSL_ECC_SECP256R1: oid = ECC_256R1; octets = 32; break; -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384) - case WOLFSSL_ECC_SECP384R1: oid = ECC_384R1; octets = 48; break; -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521) - case WOLFSSL_ECC_SECP521R1: oid = ECC_521R1; octets = 66; break; -#endif + #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case WOLFSSL_ECC_SECP160R1: oid = ECC_SECP160R1_OID; octets = 20; break; + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_SECPR2 + case WOLFSSL_ECC_SECP160R2: oid = ECC_SECP160R2_OID; octets = 20; break; + #endif /* HAVE_ECC_SECPR2 */ + #ifdef HAVE_ECC_KOBLITZ + case WOLFSSL_ECC_SECP160K1: oid = ECC_SECP160K1_OID; octets = 20; break; + #endif /* HAVE_ECC_KOBLITZ */ + #endif + #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case WOLFSSL_ECC_SECP192R1: oid = ECC_SECP192R1_OID; octets = 24; break; + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_KOBLITZ + case WOLFSSL_ECC_SECP192K1: oid = ECC_SECP192K1_OID; octets = 24; break; + #endif /* HAVE_ECC_KOBLITZ */ + #endif + #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case WOLFSSL_ECC_SECP224R1: oid = ECC_SECP224R1_OID; octets = 28; break; + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_KOBLITZ + case WOLFSSL_ECC_SECP224K1: oid = ECC_SECP224K1_OID; octets = 28; break; + #endif /* HAVE_ECC_KOBLITZ */ + #endif + #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case WOLFSSL_ECC_SECP256R1: oid = ECC_SECP256R1_OID; octets = 32; break; + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_KOBLITZ + case WOLFSSL_ECC_SECP256K1: oid = ECC_SECP256K1_OID; octets = 32; break; + #endif /* HAVE_ECC_KOBLITZ */ + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP256R1: oid = ECC_BRAINPOOLP256R1_OID; octets = 32; break; + #endif /* HAVE_ECC_BRAINPOOL */ + #endif + #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case WOLFSSL_ECC_SECP384R1: oid = ECC_SECP384R1_OID; octets = 48; break; + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP384R1: oid = ECC_BRAINPOOLP384R1_OID; octets = 48; break; + #endif /* HAVE_ECC_BRAINPOOL */ + #endif + #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP512R1: oid = ECC_BRAINPOOLP512R1_OID; octets = 64; break; + #endif /* HAVE_ECC_BRAINPOOL */ + #endif + #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + case WOLFSSL_ECC_SECP521R1: oid = ECC_SECP521R1_OID; octets = 66; break; + #endif /* !NO_ECC_SECP */ + #endif default: continue; /* unsupported curve */ } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 3cdab5c95..e4ae551a9 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -720,24 +720,7 @@ static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3}; /* curveType */ #ifdef HAVE_ECC - #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192) - static const byte curve192v1Oid[] = {42, 134, 72, 206, 61, 3, 1, 1}; - #endif /* HAVE_ALL_CURVES || HAVE_ECC192 */ - #if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256) - static const byte curve256v1Oid[] = {42, 134, 72, 206, 61, 3, 1, 7}; - #endif /* HAVE_ALL_CURVES || HAVE_ECC256 */ - #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160) - static const byte curve160r1Oid[] = {43, 129, 4, 0, 8}; - #endif /* HAVE_ALL_CURVES || HAVE_ECC160 */ - #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224) - static const byte curve224r1Oid[] = {43, 129, 4, 0, 33}; - #endif /* HAVE_ALL_CURVES || HAVE_ECC224 */ - #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384) - static const byte curve384r1Oid[] = {43, 129, 4, 0, 34}; - #endif /* HAVE_ALL_CURVES || HAVE_ECC384 */ - #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521) - static const byte curve521r1Oid[] = {43, 129, 4, 0, 35}; - #endif /* HAVE_ALL_CURVES || HAVE_ECC521 */ + /* See "ecc_sets" table in ecc.c */ #endif /* HAVE_ECC */ /* blkType */ @@ -909,45 +892,8 @@ static const byte* OidFromId(word32 id, word32 type, word32* oidSz) #ifdef HAVE_ECC case oidCurveType: - switch (id) { - #if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256) - case ECC_256R1: - oid = curve256v1Oid; - *oidSz = sizeof(curve256v1Oid); - break; - #endif /* HAVE_ALL_CURVES || HAVE_ECC256 */ - #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384) - case ECC_384R1: - oid = curve384r1Oid; - *oidSz = sizeof(curve384r1Oid); - break; - #endif /* HAVE_ALL_CURVES || HAVE_ECC384 */ - #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521) - case ECC_521R1: - oid = curve521r1Oid; - *oidSz = sizeof(curve521r1Oid); - break; - #endif /* HAVE_ALL_CURVES || HAVE_ECC521 */ - #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160) - case ECC_160R1: - oid = curve160r1Oid; - *oidSz = sizeof(curve160r1Oid); - break; - #endif /* HAVE_ALL_CURVES || HAVE_ECC160 */ - #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192) - case ECC_192R1: - oid = curve192v1Oid; - *oidSz = sizeof(curve192v1Oid); - break; - #endif /* HAVE_ALL_CURVES || HAVE_ECC192 */ - #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224) - case ECC_224R1: - oid = curve224r1Oid; - *oidSz = sizeof(curve224r1Oid); - break; - #endif /* HAVE_ALL_CURVES || HAVE_ECC224 */ - default: - break; + if (wc_ecc_get_oid(id, &oid, oidSz) < 0) { + WOLFSSL_MSG("ECC OID not found"); } break; #endif /* HAVE_ECC */ @@ -1097,9 +1043,84 @@ static const byte* OidFromId(word32 id, word32 type, word32* oidSz) return oid; } +#ifdef HAVE_OID_ENCODING +int EncodeObjectId(const word32* in, word32 inSz, byte* out, word32* outSz) +{ + int i, x, len; + word32 d, t; -WOLFSSL_LOCAL int GetObjectId(const byte* input, word32* inOutIdx, word32* oid, - word32 oidType, word32 maxIdx) + /* check args */ + if (in == NULL || outSz == NULL) { + return BAD_FUNC_ARG; + } + + /* compute length of encoded OID */ + d = (in[0] * 40) + in[1]; + len = 0; + for (i = 1; i < (int)inSz; i++) { + x = 0; + t = d; + while (t) { + x++; + t >>= 1; + } + len += (x / 7) + ((x % 7) ? 1 : 0) + (d == 0 ? 1 : 0); + + if (i < (int)inSz - 1) { + d = in[i + 1]; + } + } + + if (out) { + /* verify length */ + if ((int)*outSz < len) { + return BUFFER_E; /* buffer provided is not large enough */ + } + + /* calc first byte */ + d = (in[0] * 40) + in[1]; + + /* encode bytes */ + x = 0; + for (i = 1; i < (int)inSz; i++) { + if (d) { + int y = x, z; + byte mask = 0; + while (d) { + out[x++] = (byte)((d & 0x7F) | mask); + d >>= 7; + mask |= 0x80; /* upper bit is set on all but the last byte */ + } + /* now swap bytes y...x-1 */ + z = x - 1; + while (y < z) { + mask = out[y]; + out[y] = out[z]; + out[z] = mask; + ++y; + --z; + } + } + else { + out[x++] = 0x00; /* zero value */ + } + + /* next word */ + if (i < (int)inSz - 1) { + d = in[i + 1]; + } + } + } + + /* return length */ + *outSz = len; + + return 0; +} +#endif + +int GetObjectId(const byte* input, word32* inOutIdx, word32* oid, + word32 oidType, word32 maxIdx) { int length; word32 i = *inOutIdx; @@ -1143,10 +1164,10 @@ WOLFSSL_LOCAL int GetObjectId(const byte* input, word32* inOutIdx, word32* oid, if (oidType != oidIgnoreType) { checkOid = OidFromId(*oid, oidType, &checkOidSz); - if (checkOid != NULL && - (checkOidSz != actualOidSz || - XMEMCMP(actualOid, checkOid, checkOidSz) != 0)) { - + if (checkOid == NULL || + (checkOid != NULL && (checkOidSz != actualOidSz || + XMEMCMP(actualOid, checkOid, checkOidSz) != 0))) + { WOLFSSL_MSG("OID Check Failed"); return ASN_UNKNOWN_OID_E; } @@ -2314,30 +2335,12 @@ static int StoreRsaKey(DecodedCert* cert) static int CheckCurve(word32 oid) { int ret = 0; + word32 oidSz = 0; - switch (oid) { -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160) - case ECC_160R1: -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192) - case ECC_192R1: -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224) - case ECC_224R1: -#endif -#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256) - case ECC_256R1: -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384) - case ECC_384R1: -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521) - case ECC_521R1: -#endif - break; - - default: - ret = ALGO_ID_E; + ret = wc_ecc_get_oid(oid, NULL, &oidSz); + if (ret < 0 || oidSz <= 0) { + WOLFSSL_MSG("CheckCurve not found"); + ret = ALGO_ID_E; } return ret; @@ -3356,91 +3359,38 @@ WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output) static int SetCurve(ecc_key* key, byte* output) { + int ret; + int idx = 0; + word32 oidSz = 0; - /* curve types */ -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192) - static const byte ECC_192v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, - 0x03, 0x01, 0x01}; -#endif -#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256) - static const byte ECC_256v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, - 0x03, 0x01, 0x07}; -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160) - static const byte ECC_160r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, - 0x02}; -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224) - static const byte ECC_224r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, - 0x21}; -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384) - static const byte ECC_384r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, - 0x22}; -#endif -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521) - static const byte ECC_521r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, - 0x23}; -#endif + /* validate key */ + if (key == NULL || key->dp == NULL) { + return BAD_FUNC_ARG; + } - int oidSz = 0; - int idx = 0; - int lenSz = 0; - const byte* oid = 0; +#ifdef HAVE_OID_ENCODING + ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, NULL, &oidSz); + if (ret != 0) { + return ret; + } +#else + oidSz = key->dp->oidSz; +#endif output[0] = ASN_OBJECT_ID; idx++; - switch (key->dp->size) { -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160) - case 20: - oidSz = sizeof(ECC_160r1_AlgoID); - oid = ECC_160r1_AlgoID; - break; -#endif + ret = SetLength(oidSz, output+idx); + idx += ret; -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192) - case 24: - oidSz = sizeof(ECC_192v1_AlgoID); - oid = ECC_192v1_AlgoID; - break; -#endif - -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224) - case 28: - oidSz = sizeof(ECC_224r1_AlgoID); - oid = ECC_224r1_AlgoID; - break; -#endif - -#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256) - case 32: - oidSz = sizeof(ECC_256v1_AlgoID); - oid = ECC_256v1_AlgoID; - break; -#endif - -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384) - case 48: - oidSz = sizeof(ECC_384r1_AlgoID); - oid = ECC_384r1_AlgoID; - break; -#endif - -#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521) - case 66: - oidSz = sizeof(ECC_521r1_AlgoID); - oid = ECC_521r1_AlgoID; - break; -#endif - - default: - return ASN_UNKNOWN_OID_E; +#ifdef HAVE_OID_ENCODING + ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, output+idx, &oidSz); + if (ret != 0) { + return ret; } - lenSz = SetLength(oidSz, output+idx); - idx += lenSz; - - XMEMCPY(output+idx, oid, oidSz); +#else + XMEMCPY(output+idx, key->dp->oid, oidSz); +#endif idx += oidSz; return idx; @@ -4774,6 +4724,7 @@ static int DecodeCertExtensions(DecodedCert* cert) * index. It is works starting with the recorded extensions pointer. */ { + int ret; word32 idx = 0; int sz = cert->extensionsSz; byte* input = cert->extensions; @@ -4809,9 +4760,11 @@ static int DecodeCertExtensions(DecodedCert* cert) } oid = 0; - if (GetObjectId(input, &idx, &oid, oidCertExtType, sz) < 0) { - WOLFSSL_MSG("\tfail: OBJECT ID"); - return ASN_PARSE_E; + if ((ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz)) < 0) { + if (ret != ASN_UNKNOWN_OID_E) { + WOLFSSL_MSG("\tfail: OBJECT ID"); + return ret; + } } /* check for critical flag */ diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 28bb0239a..7f4103e31 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -41,11 +41,21 @@ Possible ECC enable options: * HAVE_COMP_KEY: Enables compressed key default: off * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import default: off * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves. default: off - * Includes the curve "a" variable in calculation + * Includes the curve "a" variable in calculation + * ECC_DUMP_OID: Enables dump of OID encoding and sum default: off */ /* -ECC Curves: +ECC Curve Types: + * NO_ECC_SECP Disables SECP curves default: on + * HAVE_ECC_SECPR2 Enables SECP R2 curves default: off + * HAVE_ECC_SECPR3 Enables SECP R3 curves default: off + * HAVE_ECC_BRAINPOOL Enables Brainpool curves default: off + * HAVE_ECC_KOBLITZ Enables Koblitz curves default: off + */ + +/* +ECC Curve Sizes: * ECC_USER_CURVES: Allows custom combination of key sizes below * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined) * HAVE_ECC112: 112 bit key @@ -53,17 +63,29 @@ ECC Curves: * HAVE_ECC160: 160 bit key * HAVE_ECC192: 192 bit key * HAVE_ECC224: 224 bit key + * HAVE_ECC239: 239 bit key * NO_ECC256: Disables 256 bit key (on by default) + * HAVE_ECC320: 320 bit key * HAVE_ECC384: 384 bit key + * HAVE_ECC512: 512 bit key * HAVE_ECC521: 521 bit key -*/ + */ + #ifdef HAVE_ECC +/* Make sure custom curves is enabled for Brainpool or Koblitz curve types */ +#if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\ + !defined(WOLFSSL_CUSTOM_CURVES) + #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES +#endif + +/* Make sure ASN is enabled for ECC sign/verify */ #if (defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)) && defined(NO_ASN) #error ASN must be enabled for ECC sign/verify #endif + #include #include #include @@ -93,7 +115,7 @@ ECC Curves: ptmul -> mulmod */ -/* p256 curve on by default whether user curves or not */ +/* 256-bit curve on by default whether user curves or not */ #if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES) #define ECC112 #endif @@ -109,12 +131,21 @@ ECC Curves: #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) #define ECC224 #endif +#if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES) + #define ECC239 +#endif #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) #define ECC256 #endif +#if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES) + #define ECC320 +#endif #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) #define ECC384 #endif +#if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) + #define ECC512 +#endif #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) #define ECC521 #endif @@ -126,9 +157,10 @@ ECC Curves: const ecc_set_type ecc_sets[] = { #ifdef ECC112 -{ + #ifndef NO_ECC_SECP + { 14, /* size/bytes */ - NID_secp112r1, /* NID */ + ECC_SECP112R1, /* ID */ "SECP112R1", /* curve name */ "DB7C2ABF62E35E668076BEAD208B", /* prime */ "DB7C2ABF62E35E668076BEAD2088", /* A */ @@ -136,12 +168,41 @@ const ecc_set_type ecc_sets[] = { "DB7C2ABF62E35E7628DFAC6561C5", /* order */ "9487239995A5EE76B55F9C2F098", /* Gx */ "A89CE5AF8724C0A23E0E0FF77500", /* Gy */ -}, -#endif + #ifdef HAVE_OID_ENCODING + {1,3,132,0,6}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x06}, 5, /* oid/oidSz */ + #endif + ECC_SECP112R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_SECPR2 + { + 14, /* size/bytes */ + ECC_SECP112R2, /* ID */ + "SECP112R2", /* curve name */ + "DB7C2ABF62E35E668076BEAD208B", /* prime */ + "6127C24C05F38A0AAAF65C0EF02C", /* A */ + "51DEF1815DB5ED74FCC34C85D709", /* B */ + "36DF0AAFD8B8D7597CA10520D04B", /* order */ + "4BA30AB5E892B4E1649DD0928643", /* Gx */ + "ADCD46F5882E3747DEF36E956E97", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,132,0,7}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x07}, 5, /* oid/oidSz */ + #endif + ECC_SECP112R2_OID, /* oid sum */ + 4, /* cofactor */ + }, + #endif /* HAVE_ECC_SECPR2 */ +#endif /* ECC112 */ #ifdef ECC128 -{ + #ifndef NO_ECC_SECP + { 16, /* size/bytes */ - NID_secp128r1, /* NID */ + ECC_SECP128R1, /* ID */ "SECP128R1", /* curve name */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A */ @@ -149,25 +210,123 @@ const ecc_set_type ecc_sets[] = { "FFFFFFFE0000000075A30D1B9038A115", /* order */ "161FF7528B899B2D0C28607CA52C5B86", /* Gx */ "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy */ -}, -#endif + #ifdef HAVE_OID_ENCODING + {1,3,132,0,28}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x1C}, 5, /* oid/oidSz */ + #endif + ECC_SECP128R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_SECPR2 + { + 16, /* size/bytes */ + ECC_SECP128R2, /* ID */ + "SECP128R2", /* curve name */ + "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ + "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A */ + "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B */ + "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order */ + "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx */ + "27B6916A894D3AEE7106FE805FC34B44", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,132,0,29}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x1D}, 5, /* oid/oidSz */ + #endif + ECC_SECP128R2_OID, /* oid sum */ + 4, /* cofactor */ + }, + #endif /* HAVE_ECC_SECPR2 */ +#endif /* ECC128 */ #ifdef ECC160 -{ + #ifndef NO_ECC_SECP + { 20, /* size/bytes */ - NID_secp160r1, /* NID */ + ECC_SECP160R1, /* ID */ "SECP160R1", /* curve name */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A */ "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B */ - "100000000000000000001F4C8F927AED3CA752257",/* order */ + "100000000000000000001F4C8F927AED3CA752257",/* order */ "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx */ "23A628553168947D59DCC912042351377AC5FB32", /* Gy */ -}, -#endif + #ifdef HAVE_OID_ENCODING + {1,3,132,0,8}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x08}, 5, /* oid/oidSz */ + #endif + ECC_SECP160R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_SECPR2 + { + 20, /* size/bytes */ + ECC_SECP160R2, /* ID */ + "SECP160R2", /* curve name */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A */ + "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B */ + "100000000000000000000351EE786A818F3A1A16B",/* order */ + "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx */ + "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,132,0,30}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x1E}, 5, /* oid/oidSz */ + #endif + ECC_SECP160R2_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_SECPR2 */ + #ifdef HAVE_ECC_KOBLITZ + { + 20, /* size/bytes */ + ECC_SECP160K1, /* ID */ + "SECP160K1", /* curve name */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime */ + "0000000000000000000000000000000000000000", /* A */ + "0000000000000000000000000000000000000007", /* B */ + "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order */ + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx */ + "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,132,0,9}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x09}, 5, /* oid/oidSz */ + #endif + ECC_SECP160K1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_KOBLITZ */ + #ifdef HAVE_ECC_BRAINPOOL + { + 20, /* size/bytes */ + ECC_BRAINPOOLP160R1, /* ID */ + "BRAINPOOLP160R1", /* curve name */ + "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime */ + "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A */ + "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B */ + "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order */ + "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx */ + "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,36,3,3,2,8,1,1,1}, 10, /* oid/oidSz */ + #else + {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}, 9, /* oid/oidSz */ + #endif + ECC_BRAINPOOLP160R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_BRAINPOOL */ +#endif /* ECC160 */ #ifdef ECC192 -{ + #ifndef NO_ECC_SECP + { 24, /* size/bytes */ - NID_X9_62_prime192v1, /* NID */ + ECC_SECP192R1, /* ID */ "SECP192R1", /* curve name */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */ @@ -175,12 +334,101 @@ const ecc_set_type ecc_sets[] = { "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order */ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx */ "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", /* Gy */ -}, -#endif + #ifdef HAVE_OID_ENCODING + {1,2,840,10045,3,1,1}, 7, /* oid/oidSz */ + #else + {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}, 8, /* oid/oidSz */ + #endif + ECC_SECP192R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_SECPR2 + { + 24, /* size/bytes */ + ECC_PRIME192V2, /* ID */ + "PRIME192V2", /* curve name */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */ + "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B */ + "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order */ + "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx */ + "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,2,840,10045,3,1,2}, 7, /* oid/oidSz */ + #else + {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}, 8, /* oid/oidSz */ + #endif + ECC_PRIME192V2_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_SECPR2 */ + #ifdef HAVE_ECC_SECPR3 + { + 24, /* size/bytes */ + ECC_PRIME192V3, /* ID */ + "PRIME192V3", /* curve name */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */ + "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B */ + "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order */ + "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx */ + "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,2,840,10045,3,1,3}, 7, /* oid/oidSz */ + #else + {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}, 8, /* oid/oidSz */ + #endif + ECC_PRIME192V3_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_SECPR3 */ + #ifdef HAVE_ECC_KOBLITZ + { + 24, /* size/bytes */ + ECC_SECP192K1, /* ID */ + "SECP192K1", /* curve name */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime */ + "000000000000000000000000000000000000000000000000", /* A */ + "000000000000000000000000000000000000000000000003", /* B */ + "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order */ + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx */ + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,132,0,31}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x1F}, 5, /* oid/oidSz */ + #endif + ECC_SECP192K1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_KOBLITZ */ + #ifdef HAVE_ECC_BRAINPOOL + { + 24, /* size/bytes */ + ECC_BRAINPOOLP192R1, /* ID */ + "BRAINPOOLP192R1", /* curve name */ + "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime */ + "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A */ + "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B */ + "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order */ + "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx */ + "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,36,3,3,2,8,1,1,3}, 10, /* oid/oidSz */ + #else + {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}, 9, /* oid/oidSz */ + #endif + ECC_BRAINPOOLP192R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_BRAINPOOL */ +#endif /* ECC192 */ #ifdef ECC224 -{ + #ifndef NO_ECC_SECP + { 28, /* size/bytes */ - NID_secp224r1, /* NID */ + ECC_SECP224R1, /* ID */ "SECP224R1", /* curve name */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A */ @@ -188,12 +436,123 @@ const ecc_set_type ecc_sets[] = { "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */ "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */ -}, -#endif + #ifdef HAVE_OID_ENCODING + {1,3,132,0,33}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x21}, 5, /* oid/oidSz */ + #endif + ECC_SECP224R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_KOBLITZ + { + 28, /* size/bytes */ + ECC_SECP224K1, /* ID */ + "SECP224K1", /* curve name */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime */ + "00000000000000000000000000000000000000000000000000000000", /* A */ + "00000000000000000000000000000000000000000000000000000005", /* B */ + "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order */ + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx */ + "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,132,0,32}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x20}, 5, /* oid/oidSz */ + #endif + ECC_SECP224K1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_KOBLITZ */ + #ifdef HAVE_ECC_BRAINPOOL + { + 28, /* size/bytes */ + ECC_BRAINPOOLP224R1, /* ID */ + "BRAINPOOLP224R1", /* curve name */ + "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime */ + "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A */ + "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B */ + "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order */ + "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx */ + "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,36,3,3,2,8,1,1,5}, 10, /* oid/oidSz */ + #else + {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}, 9, /* oid/oidSz */ + #endif + ECC_BRAINPOOLP224R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_BRAINPOOL */ +#endif /* ECC224 */ +#ifdef ECC239 + #ifndef NO_ECC_SECP + { + 30, /* size/bytes */ + ECC_PRIME239V1, /* ID */ + "PRIME239V1", /* curve name */ + "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */ + "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */ + "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B */ + "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order */ + "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx */ + "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,2,840,10045,3,1,4}, 7, /* oid/oidSz */ + #else + {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}, 8, /* oid/oidSz */ + #endif + ECC_PRIME239V1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_SECPR2 + { + 30, /* size/bytes */ + ECC_PRIME239V2, /* ID */ + "PRIME239V2", /* curve name */ + "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */ + "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */ + "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B */ + "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order */ + "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx */ + "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,2,840,10045,3,1,5}, 7, /* oid/oidSz */ + #else + {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}, 8, /* oid/oidSz */ + #endif + ECC_PRIME239V2_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_SECPR2 */ + #ifdef HAVE_ECC_SECPR3 + { + 30, /* size/bytes */ + ECC_PRIME239V3, /* ID */ + "PRIME239V3", /* curve name */ + "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */ + "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */ + "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B */ + "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order */ + "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx */ + "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,2,840,10045,3,1,6}, 7, /* oid/oidSz */ + #else + {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}, 8, /* oid/oidSz */ + #endif + ECC_PRIME239V3_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_SECPR3 */ +#endif /* ECC239 */ #ifdef ECC256 -{ + #ifndef NO_ECC_SECP + { 32, /* size/bytes */ - NID_X9_62_prime256v1, /* NID */ + ECC_SECP256R1, /* ID */ "SECP256R1", /* curve name */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A */ @@ -201,12 +560,83 @@ const ecc_set_type ecc_sets[] = { "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order */ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx */ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy */ -}, -#endif + #ifdef HAVE_OID_ENCODING + {1,2,840,10045,3,1,7}, 7, /* oid/oidSz */ + #else + {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}, 8, /* oid/oidSz */ + #endif + ECC_SECP256R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_KOBLITZ + { + 32, /* size/bytes */ + ECC_SECP256K1, /* ID */ + "SECP256K1", /* curve name */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime */ + "0000000000000000000000000000000000000000000000000000000000000000", /* A */ + "0000000000000000000000000000000000000000000000000000000000000007", /* B */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order */ + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx */ + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,132,0,10}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x0A}, 5, /* oid/oidSz */ + #endif + ECC_SECP256K1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_KOBLITZ */ + #ifdef HAVE_ECC_BRAINPOOL + { + 32, /* size/bytes */ + ECC_BRAINPOOLP256R1, /* ID */ + "BRAINPOOLP256R1", /* curve name */ + "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime */ + "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A */ + "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B */ + "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order */ + "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */ + "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,36,3,3,2,8,1,1,7}, 10, /* oid/oidSz */ + #else + {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}, 9, /* oid/oidSz */ + #endif + ECC_BRAINPOOLP256R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_BRAINPOOL */ +#endif /* ECC256 */ +#ifdef ECC320 + #ifdef HAVE_ECC_BRAINPOOL + { + 40, /* size/bytes */ + ECC_BRAINPOOLP320R1, /* ID */ + "BRAINPOOLP320R1", /* curve name */ + "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime */ + "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A */ + "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B */ + "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order */ + "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx */ + "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,36,3,3,2,8,1,1,9}, 10, /* oid/oidSz */ + #else + {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}, 9, /* oid/oidSz */ + #endif + ECC_BRAINPOOLP320R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_BRAINPOOL */ +#endif /* ECC320 */ #ifdef ECC384 -{ + #ifndef NO_ECC_SECP + { 48, /* size/bytes */ - NID_secp384r1, /* NID */ + ECC_SECP384R1, /* ID */ "SECP384R1", /* curve name */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A */ @@ -214,24 +644,84 @@ const ecc_set_type ecc_sets[] = { "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order */ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx */ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy */ -}, -#endif + #ifdef HAVE_OID_ENCODING + {1,3,132,0,34}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x22}, 5, /* oid/oidSz */ + #endif + ECC_SECP384R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_BRAINPOOL + { + 48, /* size/bytes */ + ECC_BRAINPOOLP384R1, /* ID */ + "BRAINPOOLP384R1", /* curve name */ + "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime */ + "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A */ + "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B */ + "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order */ + "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx */ + "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,36,3,3,2,8,1,1,11}, 10, /* oid/oidSz */ + #else + {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}, 9, /* oid/oidSz */ + #endif + ECC_BRAINPOOLP384R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_BRAINPOOL */ +#endif /* ECC384 */ +#ifdef ECC512 + #ifdef HAVE_ECC_BRAINPOOL + { + 64, /* size/bytes */ + ECC_BRAINPOOLP512R1, /* ID */ + "BRAINPOOLP512R1", /* curve name */ + "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime */ + "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A */ + "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B */ + "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order */ + "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx */ + "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy */ + #ifdef HAVE_OID_ENCODING + {1,3,36,3,3,2,8,1,1,13}, 10, /* oid/oidSz */ + #else + {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}, 9, /* oid/oidSz */ + #endif + ECC_BRAINPOOLP512R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* HAVE_ECC_BRAINPOOL */ +#endif /* ECC512 */ #ifdef ECC521 -{ - 66, /* size/bytes */ - NID_secp521r1, /* NID */ - "SECP521R1", /* curve name */ + #ifndef NO_ECC_SECP + { + 66, /* size/bytes */ + ECC_SECP521R1, /* ID */ + "SECP521R1", /* curve name */ "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A */ "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", /* B */ "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order */ "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", /* Gx */ "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy */ -}, -#endif + #ifdef HAVE_OID_ENCODING + {1,3,132,0,35}, 5, /* oid/oidSz */ + #else + {0x2B,0x81,0x04,0x00,0x23}, 5, /* oid/oidSz */ + #endif + ECC_SECP521R1_OID, /* oid sum */ + 1, /* cofactor */ + }, + #endif /* !NO_ECC_SECP */ +#endif /* ECC521 */ { 0, -1, - NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + {0}, 0, 0, 0 } }; @@ -254,6 +744,43 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret); static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen); #endif + +static int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id) +{ + if (keysize <=0 && curve_id <= 0) { + return BAD_FUNC_ARG; + } + + if (keysize > ECC_MAXSIZE) { + return ECC_BAD_ARG_E; + } + + /* handle custom case */ + if (key->idx != ECC_CUSTOM_IDX) { + int x; + + /* find ecc_set based on curve_id or key size */ + for (x = 0; ecc_sets[x].size != 0; x++) { + if (curve_id > ECC_CURVE_DEF) { + if (curve_id == ecc_sets[x].id) + break; + } + else if (keysize <= ecc_sets[x].size) { + break; + } + } + if (ecc_sets[x].size == 0) { + return ECC_BAD_ARG_E; + } + + key->idx = x; + key->dp = &ecc_sets[x]; + } + + return 0; +} + + /* helper for either lib */ static int get_digit_count(mp_int* a) { @@ -1471,6 +1998,7 @@ int wc_ecc_is_valid_idx(int n) if ((n >= ECC_CUSTOM_IDX) && (n < x)) { return 1; } + return 0; } @@ -1504,12 +2032,14 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, /* Verify domain params supplied */ if (wc_ecc_is_valid_idx(private_key->idx) == 0 || - wc_ecc_is_valid_idx(public_key->idx) == 0) + wc_ecc_is_valid_idx(public_key->idx) == 0) { return ECC_BAD_ARG_E; + } /* Verify curve name matches */ - if (XSTRNCMP(private_key->dp->name, public_key->dp->name, ECC_MAXNAME) != 0) + if (XSTRNCMP(private_key->dp->name, public_key->dp->name, ECC_MAXNAME) != 0) { return ECC_BAD_ARG_E; + } /* make new point */ result = wc_ecc_new_point_h(private_key->heap); @@ -1638,10 +2168,9 @@ int wc_ecc_point_is_at_infinity(ecc_point* p) } -int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, - const ecc_set_type* dp) +int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) { - int err, x; + int err; ecc_point* base = NULL; mp_int prime; mp_int a; @@ -1652,28 +2181,14 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, byte buf[ECC_MAXSIZE_GEN]; #endif - if (key == NULL || rng == NULL || (keysize <= 0 && dp == NULL)) { + if (key == NULL || rng == NULL) { return BAD_FUNC_ARG; } - /* determine curve type/index */ - if (dp == NULL) { - /* find key size */ - for (x = 0; (keysize > ecc_sets[x].size) && - (ecc_sets[x].size != 0); x++); - keysize = ecc_sets[x].size; - - if (keysize > ECC_MAXSIZE || ecc_sets[x].size == 0) { - return BAD_FUNC_ARG; - } - dp = &ecc_sets[x]; + err = wc_ecc_set_curve(key, keysize, curve_id); + if (err != 0) { + return err; } - else { - x = ECC_CUSTOM_IDX; - } - - key->idx = x; - key->dp = dp; #ifdef WOLFSSL_SMALL_STACK buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -1683,7 +2198,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, /*generate 8 extra bytes to mitigate bias from the modulo operation below*/ /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/ - keysize = dp->size + 8; + keysize = key->dp->size + 8; /* make up random string */ err = wc_RNG_GenerateBlock(rng, buf, keysize); @@ -1781,6 +2296,63 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, return err; } +#ifdef ECC_DUMP_OID +/* Optional dump of encoded OID for adding new curves */ +static int mOidDumpDone; +static void wc_ecc_dump_oids(void) +{ + int x; + + if (mOidDumpDone) { + return; + } + + /* find matching OID sum (based on encoded value) */ + for (x = 0; ecc_sets[x].size != 0; x++) { + int i; + byte* oid; + word32 oidSz, sum = 0; + + printf("ECC %s (%d):\n", ecc_sets[x].name, x); + + #ifdef HAVE_OID_ENCODING + byte oidEnc[ECC_MAX_OID_LEN]; + + oid = oidEnc; + oidSz = ECC_MAX_OID_LEN; + + printf("OID: "); + for (i = 0; i < (int)ecc_sets[x].oidSz; i++) { + printf("%d.", ecc_sets[x].oid[i]); + } + printf("\n"); + + EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz); + #else + oid = (byte*)ecc_sets[x].oid; + oidSz = ecc_sets[x].oidSz; + #endif + + printf("OID Encoded: "); + for (i = 0; i < (int)oidSz; i++) { + printf("0x%02X,", oid[i]); + } + printf("\n"); + + for (i = 0; i < (int)oidSz; i++) { + sum += oid[i]; + } + printf("Sum: %d\n", sum); + + /* validate sum */ + if (ecc_sets[x].oidSum != sum) { + printf(" Sum %d Not Valid!\n", ecc_sets[x].oidSum); + } + } + mOidDumpDone = 1; +} +#endif /* ECC_DUMP_OID */ + /** Make a new ECC key rng An active RNG state @@ -1791,13 +2363,22 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, */ int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key) { - return wc_ecc_make_key_ex(rng, keysize, key, NULL); + return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF); } /* Setup dynamic pointers is using normal math for proper freeing */ int wc_ecc_init(ecc_key* key) { - (void)key; + if (key == NULL) { + return BAD_FUNC_ARG; + } + +#ifdef ECC_DUMP_OID + wc_ecc_dump_oids(); +#endif + + key->dp = NULL; + key->idx = 0; #ifndef USE_FAST_MATH key->pubkey.x->dp = NULL; @@ -1833,10 +2414,6 @@ int wc_ecc_init_h(ecc_key* key, void* heap) { int ret; - if (key == NULL) { - return BAD_FUNC_ARG; - } - if ((ret = wc_ecc_init(key)) != MP_OKAY) { return ret; } @@ -1948,7 +2525,8 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, err = RNG_FAILURE_E; break; } - err = wc_ecc_make_key_ex(rng, 0, &pubkey, key->dp); + err = wc_ecc_make_key_ex(rng, key->dp->size, &pubkey, + key->dp->id); if (err != MP_OKAY) break; /* find r = x1 mod n */ @@ -2971,13 +3549,13 @@ int wc_ecc_check_key(ecc_key* key) #ifdef HAVE_ECC_KEY_IMPORT /* import public ECC key in ANSI X9.63 format */ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, - const ecc_set_type* dp) + int curve_id) { - int x, err; + int err; int compressed = 0; if (in == NULL || key == NULL) - return ECC_BAD_ARG_E; + return BAD_FUNC_ARG; /* must be odd */ if ((inLen & 1) == 0) { @@ -3014,31 +3592,15 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, } if (err == MP_OKAY) { + int keysize; + /* adjust inLen if compressed */ if (compressed) - inLen = (inLen-1)*2 + 1; /* used uncompressed len */ - - /* determine the idx */ - if (dp) { - /* set the idx */ - key->idx = ECC_CUSTOM_IDX; - key->dp = dp; - key->type = ECC_PUBLICKEY; - } - else { - for (x = 0; ecc_sets[x].size != 0; x++) { - if ((unsigned)ecc_sets[x].size >= ((inLen-1)>>1)) { - break; - } - } - if (ecc_sets[x].size == 0) { - WOLFSSL_MSG("ecc_set size not found"); - err = ASN_PARSE_E; - } else { - key->idx = x; - key->dp = &ecc_sets[x]; - key->type = ECC_PUBLICKEY; - } - } + inLen = (inLen-1)*2 + 1; /* used uncompressed len */ + + /* determine key size */ + keysize = ((inLen-1)>>1); + err = wc_ecc_set_curve(key, keysize, curve_id); + key->type = ECC_PUBLICKEY; } /* read data */ @@ -3125,7 +3687,7 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key) { - return wc_ecc_import_x963_ex(in, inLen, key, NULL); + return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF); } #endif /* HAVE_ECC_KEY_IMPORT */ @@ -3225,14 +3787,20 @@ int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen) #ifdef HAVE_ECC_KEY_IMPORT static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, - const char* qy, const char* d, int x, const ecc_set_type* dp) + const char* qy, const char* d, int curve_id) { int err; - if (key == NULL || qx == NULL || qy == NULL || d == NULL || dp == NULL) { + if (key == NULL || qx == NULL || qy == NULL || d == NULL) { return BAD_FUNC_ARG; } + /* set curve type and index */ + err = wc_ecc_set_curve(key, 0, curve_id); + if (err != 0) { + return err; + } + /* init key */ #ifdef ALT_ECC_SIZE key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; @@ -3260,14 +3828,6 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, if (err == MP_OKAY) mp_set(key->pubkey.z, 1); - /* read and set the curve */ - if (err == MP_OKAY) { - /* set curve type and index */ - key->idx = x; - key->dp = dp; - key->type = ECC_PUBLICKEY; - } - /* import private key */ if (err == MP_OKAY) { key->type = ECC_PRIVATEKEY; @@ -3299,9 +3859,9 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, return MP_OKAY on success */ int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy, - const char* d, const ecc_set_type* dp) + const char* d, int curve_id) { - return wc_ecc_import_raw_private(key, qx, qy, d, ECC_CUSTOM_IDX, dp); + return wc_ecc_import_raw_private(key, qx, qy, d, curve_id); } @@ -3336,7 +3896,7 @@ int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy, WOLFSSL_MSG("ecc_set curve name not found"); err = ASN_PARSE_E; } else { - return wc_ecc_import_raw_private(key, qx, qy, d, x, &ecc_sets[x]); + return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id); } return err; @@ -5679,7 +6239,7 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen int ret = MP_OKAY; if (key == NULL || out == NULL || outLen == NULL) - return ECC_BAD_ARG_E; + return BAD_FUNC_ARG; if (wc_ecc_is_valid_idx(key->idx) == 0) { return ECC_BAD_ARG_E; @@ -5704,4 +6264,62 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen #endif /* HAVE_COMP_KEY */ + +int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz) +{ + int x; + + if (oidSum == 0) { + return BAD_FUNC_ARG; + } + + /* find matching OID sum (based on encoded value) */ + for (x = 0; ecc_sets[x].size != 0; x++) { + if (ecc_sets[x].oidSum == oidSum) { + int ret = 0; + #ifdef HAVE_OID_ENCODING + static byte oidDec[ECC_MAX_OID_LEN]; + word32 oidSzDec = ECC_MAX_OID_LEN; + ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, + oidDec, &oidSzDec); + if (oidSz) { + *oidSz = oidSzDec; + } + if (oid) { + *oid = oidDec; + } + #else + if (oidSz) { + *oidSz = ecc_sets[x].oidSz; + } + if (oid) { + *oid = ecc_sets[x].oid; + } + #endif + /* on success return curve id */ + if (ret == 0) { + ret = ecc_sets[x].id; + } + return ret; + } + } + + return NOT_COMPILED_IN; +} + +#ifdef WOLFSSL_CUSTOM_CURVES +int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp) +{ + if (key == NULL || dp == NULL) { + return BAD_FUNC_ARG; + } + + key->idx = WOLFSSL_CUSTOM_CURVES; + key->dp = dp; + + return 0; +} +#endif /* WOLFSSL_CUSTOM_CURVES */ + + #endif /* HAVE_ECC */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 279383f83..c48498cf9 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6443,6 +6443,20 @@ static int ecc_test_vector(int keySize) vec.keySize = keySize; switch(keySize) { + +#if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES) + case 14: + return 0; +#endif /* HAVE_ECC112 */ +#if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES) + case 16: + return 0; +#endif /* HAVE_ECC128 */ +#if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) + case 20: + return 0; +#endif /* HAVE_ECC160 */ + #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) case 24: /* first [P-192,SHA-1] vector from FIPS 186-3 NIST vectors */ @@ -6499,6 +6513,11 @@ static int ecc_test_vector(int keySize) break; #endif /* HAVE_ECC224 */ +#if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES) + case 30: + return 0; +#endif /* HAVE_ECC239 */ + #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) case 32: /* first [P-256,SHA-1] vector from FIPS 186-3 NIST vectors */ @@ -6527,6 +6546,11 @@ static int ecc_test_vector(int keySize) break; #endif /* !NO_ECC256 */ +#if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES) + case 40: + return 0; +#endif /* HAVE_ECC320 */ + #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) case 48: /* first [P-384,SHA-1] vector from FIPS 186-3 NIST vectors */ @@ -6555,6 +6579,11 @@ static int ecc_test_vector(int keySize) break; #endif /* HAVE_ECC384 */ +#if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) + case 64: + return 0; +#endif /* HAVE_ECC512 */ + #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) case 66: /* first [P-521,SHA-1] vector from FIPS 186-3 NIST vectors */ @@ -6673,7 +6702,7 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize) } #endif /* WOLFSSL_KEY_GEN */ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, - const ecc_set_type* dp) + int curve_id) { #ifdef BENCH_EMBEDDED byte sharedA[128]; /* Needs to be at least keySize */ @@ -6701,7 +6730,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, wc_ecc_init(&userB); wc_ecc_init(&pubKey); - ret = wc_ecc_make_key_ex(rng, keySize, &userA, dp); + ret = wc_ecc_make_key_ex(rng, keySize, &userA, curve_id); if (ret != 0) ERROR_OUT(-1014, done); @@ -6709,15 +6738,17 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, if (ret != 0) ERROR_OUT(-1023, done); - ret = wc_ecc_make_key_ex(rng, keySize, &userB, dp); + ret = wc_ecc_make_key_ex(rng, keySize, &userB, curve_id); if (ret != 0) ERROR_OUT(-1002, done); #ifdef HAVE_ECC_DHE x = sizeof(sharedA); ret = wc_ecc_shared_secret(&userA, &userB, sharedA, &x); - if (ret != 0) + if (ret != 0) { + printf("wc_ecc_shared_secret %d\n", ret); ERROR_OUT(-1015, done); + } y = sizeof(sharedB); ret = wc_ecc_shared_secret(&userB, &userA, sharedB, &y); @@ -6738,7 +6769,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, ERROR_OUT(-1006, done); #ifdef HAVE_ECC_KEY_IMPORT - ret = wc_ecc_import_x963_ex(exportBuf, x, &pubKey, dp); + ret = wc_ecc_import_x963_ex(exportBuf, x, &pubKey, curve_id); if (ret != 0) ERROR_OUT(-1007, done); @@ -6761,7 +6792,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, wc_ecc_free(&pubKey); wc_ecc_init(&pubKey); - ret = wc_ecc_import_x963_ex(exportBuf, x, &pubKey, dp); + ret = wc_ecc_import_x963_ex(exportBuf, x, &pubKey, curve_id); if (ret != 0) ERROR_OUT(-1011, done); @@ -6847,7 +6878,7 @@ static int ecc_test_curve(WC_RNG* rng, int keySize) { int ret; - ret = ecc_test_curve_size(rng, keySize, ECC_TEST_VERIFY_COUNT, NULL); + ret = ecc_test_curve_size(rng, keySize, ECC_TEST_VERIFY_COUNT, ECC_CURVE_DEF); if (ret < 0) { printf("ecc_test_curve_size %d failed!: %d\n", keySize, ret); return ret; @@ -6881,6 +6912,24 @@ int ecc_test(void) if (ret != 0) return -1001; +#if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES) + ret = ecc_test_curve(&rng, 14); + if (ret < 0) { + goto done; + } +#endif /* HAVE_ECC112 */ +#if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES) + ret = ecc_test_curve(&rng, 16); + if (ret < 0) { + goto done; + } +#endif /* HAVE_ECC128 */ +#if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) + ret = ecc_test_curve(&rng, 20); + if (ret < 0) { + goto done; + } +#endif /* HAVE_ECC160 */ #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) ret = ecc_test_curve(&rng, 24); if (ret < 0) { @@ -6893,18 +6942,36 @@ int ecc_test(void) goto done; } #endif /* HAVE_ECC224 */ +#if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES) + ret = ecc_test_curve(&rng, 30); + if (ret < 0) { + goto done; + } +#endif /* HAVE_ECC239 */ #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) ret = ecc_test_curve(&rng, 32); if (ret < 0) { goto done; } #endif /* !NO_ECC256 */ +#if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES) + ret = ecc_test_curve(&rng, 40); + if (ret < 0) { + goto done; + } +#endif /* HAVE_ECC320 */ #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) ret = ecc_test_curve(&rng, 48); if (ret < 0) { goto done; } #endif /* HAVE_ECC384 */ +#if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) + ret = ecc_test_curve(&rng, 64); + if (ret < 0) { + goto done; + } +#endif /* HAVE_ECC512 */ #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) ret = ecc_test_curve(&rng, 66); if (ret < 0) { @@ -6913,23 +6980,22 @@ int ecc_test(void) #endif /* HAVE_ECC521 */ #if defined(WOLFSSL_CUSTOM_CURVES) - /* Test and demonstrate use of Brainpool256 curve */ - const ecc_set_type ecc_cust_dp = { - 32, /* size/bytes */ - 0, /* NID - not required */ - "BRAINPOOLP256R1", /* curve name */ - "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime */ - "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A */ - "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B */ - "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order */ - "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */ - "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */ - }; - ret = ecc_test_curve_size(&rng, 0, ECC_TEST_VERIFY_COUNT, &ecc_cust_dp); - if (ret < 0) { - printf("ecc_test_curve_size custom failed!: %d\n", ret); - goto done; + #if defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ) + { + int curve_id; + #ifdef HAVE_ECC_BRAINPOOL + curve_id = ECC_BRAINPOOLP256R1; + #else + curve_id = ECC_SECP256K1; + #endif + /* Test and demonstrate use of non-SECP curve */ + ret = ecc_test_curve_size(&rng, 0, ECC_TEST_VERIFY_COUNT, curve_id); + if (ret < 0) { + printf("ecc_test_curve_size: type %d: failed!: %d\n", curve_id, ret); + goto done; + } } + #endif #endif done: diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index e8711d791..27fa7a600 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -5,6 +5,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -13,15 +14,33 @@ extern "C" { /* Map OpenSSL NID value */ enum { POINT_CONVERSION_UNCOMPRESSED = 4, - NID_secp112r1 = 0, - NID_secp128r1 = 1, - NID_secp160r1 = 2, - NID_X9_62_prime192v1 = 3, - NID_secp224r1 = 4, - NID_X9_62_prime256v1 = 5, - NID_secp384r1 = 6, - NID_secp521r1 = 7, - NID_X9_62_prime_field = 100, + +#ifdef HAVE_ECC + /* Use ecc_curve_type enum values for NID */ + NID_X9_62_prime192v1 = ECC_SECP192R1, + NID_X9_62_prime256v1 = ECC_SECP256R1, + NID_secp112r1 = ECC_SECP112R1, + NID_secp112r2 = ECC_SECP112R2, + NID_secp128r1 = ECC_SECP128R1, + NID_secp128r2 = ECC_SECP128R2, + NID_secp160r1 = ECC_SECP160R1, + NID_secp160r2 = ECC_SECP160R2, + NID_secp224r1 = ECC_SECP224R1, + NID_secp384r1 = ECC_SECP384R1, + NID_secp521r1 = ECC_SECP521R1, + NID_secp160k1 = ECC_SECP160K1, + NID_secp192k1 = ECC_SECP192K1, + NID_secp224k1 = ECC_SECP224K1, + NID_secp256k1 = ECC_SECP256K1, + NID_brainpoolP160r1 = ECC_BRAINPOOLP160R1, + NID_brainpoolP192r1 = ECC_BRAINPOOLP192R1, + NID_brainpoolP224r1 = ECC_BRAINPOOLP224R1, + NID_brainpoolP256r1 = ECC_BRAINPOOLP256R1, + NID_brainpoolP320r1 = ECC_BRAINPOOLP320R1, + NID_brainpoolP384r1 = ECC_BRAINPOOLP384R1, + NID_brainpoolP512r1 = ECC_BRAINPOOLP512R1, +#endif + OPENSSL_EC_NAMED_CURVE = 0x001 }; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index b62341269..3c42ea97b 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1573,12 +1573,36 @@ WOLFSSL_API int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx, /* Elliptic Curves */ enum { - WOLFSSL_ECC_SECP160R1 = 0x10, - WOLFSSL_ECC_SECP192R1 = 0x13, - WOLFSSL_ECC_SECP224R1 = 0x15, - WOLFSSL_ECC_SECP256R1 = 0x17, - WOLFSSL_ECC_SECP384R1 = 0x18, - WOLFSSL_ECC_SECP521R1 = 0x19 +#if 0 /* Not Supported */ + WOLFSSL_ECC_SECT163K1 = 1, + WOLFSSL_ECC_SECT163R1 = 2, + WOLFSSL_ECC_SECT163R2 = 3, + WOLFSSL_ECC_SECT193R1 = 4, + WOLFSSL_ECC_SECT193R2 = 5, + WOLFSSL_ECC_SECT233K1 = 6, + WOLFSSL_ECC_SECT233R1 = 7, + WOLFSSL_ECC_SECT239K1 = 8, + WOLFSSL_ECC_SECT283K1 = 9, + WOLFSSL_ECC_SECT283R1 = 10, + WOLFSSL_ECC_SECT409K1 = 11, + WOLFSSL_ECC_SECT409R1 = 12, + WOLFSSL_ECC_SECT571K1 = 13, + WOLFSSL_ECC_SECT571R1 = 14, +#endif + WOLFSSL_ECC_SECP160K1 = 15, + WOLFSSL_ECC_SECP160R1 = 16, + WOLFSSL_ECC_SECP160R2 = 17, + WOLFSSL_ECC_SECP192K1 = 18, + WOLFSSL_ECC_SECP192R1 = 19, + WOLFSSL_ECC_SECP224K1 = 20, + WOLFSSL_ECC_SECP224R1 = 21, + WOLFSSL_ECC_SECP256K1 = 22, + WOLFSSL_ECC_SECP256R1 = 23, + WOLFSSL_ECC_SECP384R1 = 24, + WOLFSSL_ECC_SECP521R1 = 25, + WOLFSSL_ECC_BRAINPOOLP256R1 = 26, + WOLFSSL_ECC_BRAINPOOLP384R1 = 27, + WOLFSSL_ECC_BRAINPOOLP512R1 = 28, }; #ifdef HAVE_SUPPORTED_CURVES diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index ff6253d9c..e8dfa1d8e 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -241,12 +241,33 @@ enum Key_Sum { enum Ecc_Sum { - ECC_256R1 = 526, - ECC_384R1 = 210, - ECC_521R1 = 211, - ECC_160R1 = 184, - ECC_192R1 = 520, - ECC_224R1 = 209 + ECC_SECP112R1_OID = 182, + ECC_SECP112R2_OID = 183, + ECC_SECP128R1_OID = 204, + ECC_SECP128R2_OID = 205, + ECC_SECP160R1_OID = 184, + ECC_SECP160R2_OID = 206, + ECC_SECP160K1_OID = 185, + ECC_BRAINPOOLP160R1_OID = 98, + ECC_SECP192R1_OID = 520, + ECC_PRIME192V2_OID = 521, + ECC_PRIME192V3_OID = 522, + ECC_SECP192K1_OID = 207, + ECC_BRAINPOOLP192R1_OID = 100, + ECC_SECP224R1_OID = 209, + ECC_SECP224K1_OID = 208, + ECC_BRAINPOOLP224R1_OID = 102, + ECC_PRIME239V1_OID = 523, + ECC_PRIME239V2_OID = 524, + ECC_PRIME239V3_OID = 525, + ECC_SECP256R1_OID = 526, + ECC_SECP256K1_OID = 186, + ECC_BRAINPOOLP256R1_OID = 104, + ECC_BRAINPOOLP320R1_OID = 106, + ECC_SECP384R1_OID = 210, + ECC_BRAINPOOLP384R1_OID = 108, + ECC_BRAINPOOLP512R1_OID = 110, + ECC_SECP521R1_OID = 211, }; @@ -628,6 +649,10 @@ WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx, int* version); WOLFSSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, word32 maxIdx); +#ifdef HAVE_OID_ENCODING + WOLFSSL_LOCAL int EncodeObjectId(const word32* in, word32 inSz, + byte* out, word32* outSz); +#endif WOLFSSL_LOCAL int GetObjectId(const byte* input, word32* inOutIdx, word32* oid, word32 oidType, word32 maxIdx); WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid, diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 8daadf768..0df9d3c80 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -43,14 +43,55 @@ enum { ECC_MINSIZE = 20, /* MIN Private Key size */ ECC_MAXSIZE = 66, /* MAX Private Key size */ ECC_MAXSIZE_GEN = 74, /* MAX Buffer size required when generating ECC keys*/ - ECC_MAX_PAD_SZ = 4 /* ECC maximum padding size */ + ECC_MAX_PAD_SZ = 4, /* ECC maximum padding size */ + ECC_MAX_OID_LEN = 16, }; +/* Curve Types */ +typedef enum ecc_curve_id { + ECC_CURVE_DEF, /* NIST or SECP */ -/* ECC set type defined a NIST GF(p) curve */ + /* NIST Prime Curves */ + ECC_SECP192R1, + ECC_PRIME192V2, + ECC_PRIME192V3, + ECC_PRIME239V1, + ECC_PRIME239V2, + ECC_PRIME239V3, + ECC_SECP256R1, + + /* SECP Curves */ + ECC_SECP112R1, + ECC_SECP112R2, + ECC_SECP128R1, + ECC_SECP128R2, + ECC_SECP160R1, + ECC_SECP160R2, + ECC_SECP224R1, + ECC_SECP384R1, + ECC_SECP521R1, + + /* Koblitz */ + ECC_SECP160K1, + ECC_SECP192K1, + ECC_SECP224K1, + ECC_SECP256K1, + + /* Brainpool Curves */ + ECC_BRAINPOOLP160R1, + ECC_BRAINPOOLP192R1, + ECC_BRAINPOOLP224R1, + ECC_BRAINPOOLP256R1, + ECC_BRAINPOOLP320R1, + ECC_BRAINPOOLP384R1, + ECC_BRAINPOOLP512R1, +} ecc_curve_id; + + +/* ECC set type defined a GF(p) curve */ typedef struct { int size; /* The size of the curve in octets */ - int nid; /* id of this curve */ + int id; /* id of this curve */ const char* name; /* name of this curve */ const char* prime; /* prime that defines the field, curve is in (hex) */ const char* Af; /* fields A param (hex) */ @@ -58,16 +99,35 @@ typedef struct { const char* order; /* order of the curve (hex) */ const char* Gx; /* x coordinate of the base point on curve (hex) */ const char* Gy; /* y coordinate of the base point on curve (hex) */ + #ifdef HAVE_OID_ENCODING + const word32 oid[ECC_MAX_OID_LEN]; + #else + const byte oid[ECC_MAX_OID_LEN]; + /* OID encoded with ASN scheme: + first element = (oid[0] * 40) + oid[1] + if any element > 127 then MSB 0x80 indicates additional byte */ + #endif + word32 oidSz; + word32 oidSum; /* sum of encoded OID bytes */ + int cofactor; } ecc_set_type; + +/* Use this as the key->idx if a custom ecc_set is used for key->dp */ #define ECC_CUSTOM_IDX (-1) /* Determine max ECC bits based on enabled curves */ #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) #define MAX_ECC_BITS 521 +#elif defined(HAVE_ECC512) + #define MAX_ECC_BITS 512 #elif defined(HAVE_ECC384) #define MAX_ECC_BITS 384 +#elif defined(HAVE_ECC320) + #define MAX_ECC_BITS 320 +#elif defined(HAVE_ECC239) + #define MAX_ECC_BITS 239 #elif defined(HAVE_ECC224) #define MAX_ECC_BITS 224 #elif !defined(NO_ECC256) @@ -180,7 +240,7 @@ WOLFSSL_API int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key); WOLFSSL_API int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, - const ecc_set_type* dp); + int curve_id); WOLFSSL_API int wc_ecc_check_key(ecc_key* key); @@ -257,7 +317,7 @@ WOLFSSL_API int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key); WOLFSSL_API int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, - const ecc_set_type* dp); + int curve_id); WOLFSSL_API int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub, word32 pubSz, ecc_key* key); @@ -268,7 +328,7 @@ int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy, const char* d, const char* curveName); WOLFSSL_API int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy, - const char* d, const ecc_set_type* dp); + const char* d, int curve_id); #endif /* HAVE_ECC_KEY_IMPORT */ #ifdef HAVE_ECC_KEY_EXPORT @@ -292,6 +352,13 @@ int wc_ecc_size(ecc_key* key); WOLFSSL_API int wc_ecc_sig_size(ecc_key* key); +WOLFSSL_API +int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz); + +#ifdef WOLFSSL_CUSTOM_CURVES + WOLFSSL_API + int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp); +#endif #ifdef HAVE_ECC_ENCRYPT /* ecc encrypt */