diff --git a/mongoose.c b/mongoose.c index 8e357adc..c1a8c566 100644 --- a/mongoose.c +++ b/mongoose.c @@ -16356,6 +16356,7 @@ static int mg_tls_verify_cert_signature(const struct mg_tls_cert *cert, MG_ERROR(("cert verification error")); return 0; } +#if MG_UECC_SUPPORTS_secp256r1 if (issuer->pubkey.len == 64) { const uint32_t N = 32; if (a.len > N) a.value += (a.len - N), a.len = N; @@ -16365,10 +16366,21 @@ static int mg_tls_verify_cert_signature(const struct mg_tls_cert *cert, return mg_uecc_verify((uint8_t *) issuer->pubkey.buf, cert->tbshash, (unsigned) cert->tbshashsz, sig, mg_uecc_secp256r1()); - } else if (issuer->pubkey.len == 96) { - MG_ERROR(("reject secp384 for now")); - return 0; - } else { + } else +#endif +#if MG_UECC_SUPPORTS_secp384r1 + if (issuer->pubkey.len == 96) { + const uint32_t N = 48; + if (a.len > N) a.value += (a.len - N), a.len = N; + if (b.len > N) b.value += (b.len - N), b.len = N; + memmove(sig, a.value, N); + memmove(sig + N, b.value, N); + return mg_uecc_verify((uint8_t *) issuer->pubkey.buf, cert->tbshash, + (unsigned) cert->tbshashsz, sig, + mg_uecc_secp384r1()); + } else +#endif + { MG_ERROR(("unsupported public key length: %d", issuer->pubkey.len)); return 0; } @@ -16419,7 +16431,7 @@ static int tls_bundle_find(struct tls_data *tls, struct mg_der_tlv *name, if (mg_tls_parse_cert_der(p->buf, p->len, cert) < 0 || !mg_der_find_oid(&cert->subj, (uint8_t *) "\x55\x04\x03", 3, &v)) { MG_ERROR(("failed to parse certificate #%u in bundle", i + 1)); - return -1; + continue; // skip this certificate but don't halt the process } subj = mg_str_n((const char *) v.value, v.len); MG_VERBOSE(("#%u: %.*s (%.*s)", i + 1, subj.len, subj.buf, tgt.len, tgt.buf)); @@ -16510,10 +16522,6 @@ static int mg_tls_recv_cert(struct mg_connection *c, bool is_client) { mg_error(c, "failed to verify hostname"); return -1; } - if (ci->pubkey.len > sizeof(tls->pubkey)) { - mg_error(c, "invalid certificate length"); - return -1; - } if (ci->pubkey.len > sizeof(tls->pubkey)) { mg_error(c, "peer public key too large"); return -1; @@ -16528,8 +16536,9 @@ static int mg_tls_recv_cert(struct mg_connection *c, bool is_client) { } if (tls->ca_bundle_len > 0) { // bundle, find subject and compare keys + int r; MG_VERBOSE(("Search current cert in bundle")); - int r = tls_bundle_find(tls, &ci->subj, &ca); // find current cert ci + r = tls_bundle_find(tls, &ci->subj, &ca); // find current cert ci if (r < 0) { mg_error(c, "failed to parse CA bundle"); return -1; @@ -16548,8 +16557,9 @@ static int mg_tls_recv_cert(struct mg_connection *c, bool is_client) { } if (!found_ca && certnum > 0 && tls->ca_bundle_len > 0) { // bundle + int r; MG_VERBOSE(("Search bundle for issuer of last cert in chain")); - int r = tls_bundle_find(tls, &certs[certnum - 1].issuer, &ca); + r = tls_bundle_find(tls, &certs[certnum - 1].issuer, &ca); if (r <= 0) { mg_error(c, r < 0 ? "failed to parse CA bundle" : "failed to find issuing CA in bundle"); @@ -17395,6 +17405,12 @@ void mg_tls_free(struct mg_connection *c) { } else { mg_free((void *) tls->cert_der.buf); } + if (tls->ca_bundle_der != NULL) { + for (i = 0; i < tls->ca_bundle_len; i++) { + mg_free((void *) tls->ca_bundle_der[i].buf); + } + mg_free(tls->ca_bundle_der); + } mg_free((void *) tls->ca_der.buf); mg_free((void *) tls->rsa_key_der.buf); } @@ -20502,6 +20518,10 @@ done: #undef MG_UECC_MAX_WORDS #define MG_UECC_MAX_WORDS 32 #endif +#if MG_UECC_SUPPORTS_secp384r1 +#undef MG_UECC_MAX_WORDS +#define MG_UECC_MAX_WORDS 48 +#endif #elif (MG_UECC_WORD_SIZE == 4) #if MG_UECC_SUPPORTS_secp160r1 #define MG_UECC_MAX_WORDS 6 /* Due to the size of curve_n. */ @@ -20518,6 +20538,10 @@ done: #undef MG_UECC_MAX_WORDS #define MG_UECC_MAX_WORDS 8 #endif +#if MG_UECC_SUPPORTS_secp384r1 +#undef MG_UECC_MAX_WORDS +#define MG_UECC_MAX_WORDS 12 +#endif #elif (MG_UECC_WORD_SIZE == 8) #if MG_UECC_SUPPORTS_secp160r1 #define MG_UECC_MAX_WORDS 3 @@ -20534,6 +20558,10 @@ done: #undef MG_UECC_MAX_WORDS #define MG_UECC_MAX_WORDS 4 #endif +#if MG_UECC_SUPPORTS_secp384r1 +#undef MG_UECC_MAX_WORDS +#define MG_UECC_MAX_WORDS 6 +#endif #endif /* MG_UECC_WORD_SIZE */ #define BITS_TO_WORDS(num_bits) \ @@ -21179,6 +21207,7 @@ MG_UECC_VLI_API void mg_uecc_vli_modInv(mg_uecc_word_t *result, #define num_bytes_secp224r1 28 #define num_bytes_secp256r1 32 #define num_bytes_secp256k1 32 +#define num_bytes_secp384r1 48 #if (MG_UECC_WORD_SIZE == 1) @@ -21187,6 +21216,7 @@ MG_UECC_VLI_API void mg_uecc_vli_modInv(mg_uecc_word_t *result, #define num_words_secp224r1 28 #define num_words_secp256r1 32 #define num_words_secp256k1 32 +#define num_words_secp384r1 48 #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) \ 0x##a, 0x##b, 0x##c, 0x##d, 0x##e, 0x##f, 0x##g, 0x##h @@ -21199,6 +21229,7 @@ MG_UECC_VLI_API void mg_uecc_vli_modInv(mg_uecc_word_t *result, #define num_words_secp224r1 7 #define num_words_secp256r1 8 #define num_words_secp256k1 8 +#define num_words_secp384r1 12 #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##d##c##b##a, 0x##h##g##f##e #define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a @@ -21210,6 +21241,7 @@ MG_UECC_VLI_API void mg_uecc_vli_modInv(mg_uecc_word_t *result, #define num_words_secp224r1 4 #define num_words_secp256r1 4 #define num_words_secp256k1 4 +#define num_words_secp384r1 6 #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##h##g##f##e##d##c##b##a##U #define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a##U @@ -21217,7 +21249,8 @@ MG_UECC_VLI_API void mg_uecc_vli_modInv(mg_uecc_word_t *result, #endif /* MG_UECC_WORD_SIZE */ #if MG_UECC_SUPPORTS_secp160r1 || MG_UECC_SUPPORTS_secp192r1 || \ - MG_UECC_SUPPORTS_secp224r1 || MG_UECC_SUPPORTS_secp256r1 + MG_UECC_SUPPORTS_secp224r1 || MG_UECC_SUPPORTS_secp256r1 || \ + MG_UECC_SUPPORTS_secp384r1 static void double_jacobian_default(mg_uecc_word_t *X1, mg_uecc_word_t *Y1, mg_uecc_word_t *Z1, MG_UECC_Curve curve) { /* t1 = X, t2 = Y, t3 = Z */ @@ -21282,7 +21315,8 @@ static void x_side_default(mg_uecc_word_t *result, const mg_uecc_word_t *x, #if MG_UECC_SUPPORT_COMPRESSED_POINT #if MG_UECC_SUPPORTS_secp160r1 || MG_UECC_SUPPORTS_secp192r1 || \ - MG_UECC_SUPPORTS_secp256r1 || MG_UECC_SUPPORTS_secp256k1 + MG_UECC_SUPPORTS_secp256r1 || MG_UECC_SUPPORTS_secp256k1 || \ + MG_UECC_SUPPORTS_secp384r1 /* Compute a = sqrt(a) (mod curve_p). */ static void mod_sqrt_default(mg_uecc_word_t *a, MG_UECC_Curve curve) { bitcount_t i; @@ -22688,6 +22722,75 @@ static void omega_mult_secp256k1(uint64_t *result, const uint64_t *right) { #endif /* MG_UECC_SUPPORTS_secp256k1 */ +#if MG_UECC_SUPPORTS_secp384r1 + +#if (MG_UECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp384r1(mg_uecc_word_t *result, + mg_uecc_word_t *product); +#endif + +static const struct MG_UECC_Curve_t curve_secp384r1 = { + num_words_secp384r1, + num_bytes_secp384r1, + 384, /* num_n_bits */ + /* p */ + {BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF)}, + /* n */ + {BYTES_TO_WORDS_8(73, 29, C5, CC, 6A, 19, EC, EC), + BYTES_TO_WORDS_8(7A, A7, B0, 48, B2, 0D, 1A, 58), + BYTES_TO_WORDS_8(DF, 2D, 37, F4, 81, 4D, 63, C7), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF)}, + /* G = (Gx || Gy) little-endian */ + {BYTES_TO_WORDS_8(B7, 0A, 76, 72, 38, 5E, 54, 3A), + BYTES_TO_WORDS_8(6C, 29, 55, BF, 5D, F2, 02, 55), + BYTES_TO_WORDS_8(38, 2A, 54, 82, E0, 41, F7, 59), + BYTES_TO_WORDS_8(98, 9B, A7, 8B, 62, 3B, 1D, 6E), + BYTES_TO_WORDS_8(74, AD, 20, F3, 1E, C7, B1, 8E), + BYTES_TO_WORDS_8(37, 05, 8B, BE, 22, CA, 87, AA), + + BYTES_TO_WORDS_8(5F, 0E, EA, 90, 7C, 1D, 43, 7A), + BYTES_TO_WORDS_8(9D, 81, 7E, 1D, CE, B1, 60, 0A), + BYTES_TO_WORDS_8(C0, B8, F0, B5, 13, 31, DA, E9), + BYTES_TO_WORDS_8(7C, 14, 9A, 28, BD, 1D, F4, F8), + BYTES_TO_WORDS_8(29, DC, 92, 92, BF, 98, 9E, 5D), + BYTES_TO_WORDS_8(6F, 2C, 26, 96, 4A, DE, 17, 36)}, + /* b */ + {BYTES_TO_WORDS_8(EF, 2A, EC, D3, ED, C8, 85, 2A), + BYTES_TO_WORDS_8(9D, D1, 2E, 8A, 8D, 39, 56, C6), + BYTES_TO_WORDS_8(5A, 87, 13, 50, 8F, 08, 14, 03), + BYTES_TO_WORDS_8(12, 41, 81, FE, 6E, 9C, 1D, 18), + BYTES_TO_WORDS_8(19, 2D, F8, E3, 6B, 05, 8E, 98), + BYTES_TO_WORDS_8(E4, E7, 3E, E2, A7, 2F, 31, B3)}, + &double_jacobian_default, +#if MG_UECC_SUPPORT_COMPRESSED_POINT + &mod_sqrt_default, +#endif + &x_side_default, +#if (MG_UECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp384r1 +#endif +}; + +MG_UECC_Curve mg_uecc_secp384r1(void) { + return &curve_secp384r1; +} + +#if (MG_UECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp384r1(mg_uecc_word_t *result, + mg_uecc_word_t *product) { + mg_uecc_vli_mmod(result, product, curve_secp384r1.p, num_words_secp384r1); +} +#endif + +#endif /* MG_UECC_SUPPORTS_secp384r1 */ + #endif /* _UECC_CURVE_SPECIFIC_H_ */ /* Returns 1 if 'point' is the point at infinity, 0 otherwise. */ diff --git a/mongoose.h b/mongoose.h index 3b804e89..55b59af5 100644 --- a/mongoose.h +++ b/mongoose.h @@ -1995,7 +1995,6 @@ int mg_aes_gcm_decrypt(unsigned char *output, const unsigned char *input, -#define MG_UECC_SUPPORTS_secp256r1 1 /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ #ifndef _UECC_H_ @@ -2066,6 +2065,9 @@ endianness. */ #ifndef MG_UECC_SUPPORTS_secp256k1 #define MG_UECC_SUPPORTS_secp256k1 0 #endif +#ifndef MG_UECC_SUPPORTS_secp384r1 +#define MG_UECC_SUPPORTS_secp384r1 1 +#endif /* Specifies whether compressed point format is supported. Set to 0 to disable point compression/decompression functions. */ @@ -2095,6 +2097,9 @@ MG_UECC_Curve mg_uecc_secp256r1(void); #if MG_UECC_SUPPORTS_secp256k1 MG_UECC_Curve mg_uecc_secp256k1(void); #endif +#if MG_UECC_SUPPORTS_secp384r1 +MG_UECC_Curve mg_uecc_secp384r1(void); +#endif /* MG_UECC_RNG_Function type The RNG function should fill 'size' random bytes into 'dest'. It should return 1 diff --git a/src/tls_builtin.c b/src/tls_builtin.c index 4372bfa7..6d107286 100644 --- a/src/tls_builtin.c +++ b/src/tls_builtin.c @@ -1583,6 +1583,7 @@ static int mg_tls_verify_cert_signature(const struct mg_tls_cert *cert, MG_ERROR(("cert verification error")); return 0; } +#if MG_UECC_SUPPORTS_secp256r1 if (issuer->pubkey.len == 64) { const uint32_t N = 32; if (a.len > N) a.value += (a.len - N), a.len = N; @@ -1592,10 +1593,21 @@ static int mg_tls_verify_cert_signature(const struct mg_tls_cert *cert, return mg_uecc_verify((uint8_t *) issuer->pubkey.buf, cert->tbshash, (unsigned) cert->tbshashsz, sig, mg_uecc_secp256r1()); - } else if (issuer->pubkey.len == 96) { - MG_ERROR(("reject secp384 for now")); - return 0; - } else { + } else +#endif +#if MG_UECC_SUPPORTS_secp384r1 + if (issuer->pubkey.len == 96) { + const uint32_t N = 48; + if (a.len > N) a.value += (a.len - N), a.len = N; + if (b.len > N) b.value += (b.len - N), b.len = N; + memmove(sig, a.value, N); + memmove(sig + N, b.value, N); + return mg_uecc_verify((uint8_t *) issuer->pubkey.buf, cert->tbshash, + (unsigned) cert->tbshashsz, sig, + mg_uecc_secp384r1()); + } else +#endif + { MG_ERROR(("unsupported public key length: %d", issuer->pubkey.len)); return 0; } @@ -1646,7 +1658,7 @@ static int tls_bundle_find(struct tls_data *tls, struct mg_der_tlv *name, if (mg_tls_parse_cert_der(p->buf, p->len, cert) < 0 || !mg_der_find_oid(&cert->subj, (uint8_t *) "\x55\x04\x03", 3, &v)) { MG_ERROR(("failed to parse certificate #%u in bundle", i + 1)); - return -1; + continue; // skip this certificate but don't halt the process } subj = mg_str_n((const char *) v.value, v.len); MG_VERBOSE(("#%u: %.*s (%.*s)", i + 1, subj.len, subj.buf, tgt.len, tgt.buf)); @@ -1737,10 +1749,6 @@ static int mg_tls_recv_cert(struct mg_connection *c, bool is_client) { mg_error(c, "failed to verify hostname"); return -1; } - if (ci->pubkey.len > sizeof(tls->pubkey)) { - mg_error(c, "invalid certificate length"); - return -1; - } if (ci->pubkey.len > sizeof(tls->pubkey)) { mg_error(c, "peer public key too large"); return -1; @@ -1755,8 +1763,9 @@ static int mg_tls_recv_cert(struct mg_connection *c, bool is_client) { } if (tls->ca_bundle_len > 0) { // bundle, find subject and compare keys + int r; MG_VERBOSE(("Search current cert in bundle")); - int r = tls_bundle_find(tls, &ci->subj, &ca); // find current cert ci + r = tls_bundle_find(tls, &ci->subj, &ca); // find current cert ci if (r < 0) { mg_error(c, "failed to parse CA bundle"); return -1; @@ -1775,8 +1784,9 @@ static int mg_tls_recv_cert(struct mg_connection *c, bool is_client) { } if (!found_ca && certnum > 0 && tls->ca_bundle_len > 0) { // bundle + int r; MG_VERBOSE(("Search bundle for issuer of last cert in chain")); - int r = tls_bundle_find(tls, &certs[certnum - 1].issuer, &ca); + r = tls_bundle_find(tls, &certs[certnum - 1].issuer, &ca); if (r <= 0) { mg_error(c, r < 0 ? "failed to parse CA bundle" : "failed to find issuing CA in bundle"); @@ -2622,6 +2632,12 @@ void mg_tls_free(struct mg_connection *c) { } else { mg_free((void *) tls->cert_der.buf); } + if (tls->ca_bundle_der != NULL) { + for (i = 0; i < tls->ca_bundle_len; i++) { + mg_free((void *) tls->ca_bundle_der[i].buf); + } + mg_free(tls->ca_bundle_der); + } mg_free((void *) tls->ca_der.buf); mg_free((void *) tls->rsa_key_der.buf); } diff --git a/src/tls_uecc.c b/src/tls_uecc.c index a8fea996..8a56e8a8 100644 --- a/src/tls_uecc.c +++ b/src/tls_uecc.c @@ -106,6 +106,10 @@ #undef MG_UECC_MAX_WORDS #define MG_UECC_MAX_WORDS 32 #endif +#if MG_UECC_SUPPORTS_secp384r1 +#undef MG_UECC_MAX_WORDS +#define MG_UECC_MAX_WORDS 48 +#endif #elif (MG_UECC_WORD_SIZE == 4) #if MG_UECC_SUPPORTS_secp160r1 #define MG_UECC_MAX_WORDS 6 /* Due to the size of curve_n. */ @@ -122,6 +126,10 @@ #undef MG_UECC_MAX_WORDS #define MG_UECC_MAX_WORDS 8 #endif +#if MG_UECC_SUPPORTS_secp384r1 +#undef MG_UECC_MAX_WORDS +#define MG_UECC_MAX_WORDS 12 +#endif #elif (MG_UECC_WORD_SIZE == 8) #if MG_UECC_SUPPORTS_secp160r1 #define MG_UECC_MAX_WORDS 3 @@ -138,6 +146,10 @@ #undef MG_UECC_MAX_WORDS #define MG_UECC_MAX_WORDS 4 #endif +#if MG_UECC_SUPPORTS_secp384r1 +#undef MG_UECC_MAX_WORDS +#define MG_UECC_MAX_WORDS 6 +#endif #endif /* MG_UECC_WORD_SIZE */ #define BITS_TO_WORDS(num_bits) \ @@ -783,6 +795,7 @@ MG_UECC_VLI_API void mg_uecc_vli_modInv(mg_uecc_word_t *result, #define num_bytes_secp224r1 28 #define num_bytes_secp256r1 32 #define num_bytes_secp256k1 32 +#define num_bytes_secp384r1 48 #if (MG_UECC_WORD_SIZE == 1) @@ -791,6 +804,7 @@ MG_UECC_VLI_API void mg_uecc_vli_modInv(mg_uecc_word_t *result, #define num_words_secp224r1 28 #define num_words_secp256r1 32 #define num_words_secp256k1 32 +#define num_words_secp384r1 48 #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) \ 0x##a, 0x##b, 0x##c, 0x##d, 0x##e, 0x##f, 0x##g, 0x##h @@ -803,6 +817,7 @@ MG_UECC_VLI_API void mg_uecc_vli_modInv(mg_uecc_word_t *result, #define num_words_secp224r1 7 #define num_words_secp256r1 8 #define num_words_secp256k1 8 +#define num_words_secp384r1 12 #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##d##c##b##a, 0x##h##g##f##e #define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a @@ -814,6 +829,7 @@ MG_UECC_VLI_API void mg_uecc_vli_modInv(mg_uecc_word_t *result, #define num_words_secp224r1 4 #define num_words_secp256r1 4 #define num_words_secp256k1 4 +#define num_words_secp384r1 6 #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##h##g##f##e##d##c##b##a##U #define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a##U @@ -821,7 +837,8 @@ MG_UECC_VLI_API void mg_uecc_vli_modInv(mg_uecc_word_t *result, #endif /* MG_UECC_WORD_SIZE */ #if MG_UECC_SUPPORTS_secp160r1 || MG_UECC_SUPPORTS_secp192r1 || \ - MG_UECC_SUPPORTS_secp224r1 || MG_UECC_SUPPORTS_secp256r1 + MG_UECC_SUPPORTS_secp224r1 || MG_UECC_SUPPORTS_secp256r1 || \ + MG_UECC_SUPPORTS_secp384r1 static void double_jacobian_default(mg_uecc_word_t *X1, mg_uecc_word_t *Y1, mg_uecc_word_t *Z1, MG_UECC_Curve curve) { /* t1 = X, t2 = Y, t3 = Z */ @@ -886,7 +903,8 @@ static void x_side_default(mg_uecc_word_t *result, const mg_uecc_word_t *x, #if MG_UECC_SUPPORT_COMPRESSED_POINT #if MG_UECC_SUPPORTS_secp160r1 || MG_UECC_SUPPORTS_secp192r1 || \ - MG_UECC_SUPPORTS_secp256r1 || MG_UECC_SUPPORTS_secp256k1 + MG_UECC_SUPPORTS_secp256r1 || MG_UECC_SUPPORTS_secp256k1 || \ + MG_UECC_SUPPORTS_secp384r1 /* Compute a = sqrt(a) (mod curve_p). */ static void mod_sqrt_default(mg_uecc_word_t *a, MG_UECC_Curve curve) { bitcount_t i; @@ -2292,6 +2310,75 @@ static void omega_mult_secp256k1(uint64_t *result, const uint64_t *right) { #endif /* MG_UECC_SUPPORTS_secp256k1 */ +#if MG_UECC_SUPPORTS_secp384r1 + +#if (MG_UECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp384r1(mg_uecc_word_t *result, + mg_uecc_word_t *product); +#endif + +static const struct MG_UECC_Curve_t curve_secp384r1 = { + num_words_secp384r1, + num_bytes_secp384r1, + 384, /* num_n_bits */ + /* p */ + {BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF)}, + /* n */ + {BYTES_TO_WORDS_8(73, 29, C5, CC, 6A, 19, EC, EC), + BYTES_TO_WORDS_8(7A, A7, B0, 48, B2, 0D, 1A, 58), + BYTES_TO_WORDS_8(DF, 2D, 37, F4, 81, 4D, 63, C7), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF)}, + /* G = (Gx || Gy) little-endian */ + {BYTES_TO_WORDS_8(B7, 0A, 76, 72, 38, 5E, 54, 3A), + BYTES_TO_WORDS_8(6C, 29, 55, BF, 5D, F2, 02, 55), + BYTES_TO_WORDS_8(38, 2A, 54, 82, E0, 41, F7, 59), + BYTES_TO_WORDS_8(98, 9B, A7, 8B, 62, 3B, 1D, 6E), + BYTES_TO_WORDS_8(74, AD, 20, F3, 1E, C7, B1, 8E), + BYTES_TO_WORDS_8(37, 05, 8B, BE, 22, CA, 87, AA), + + BYTES_TO_WORDS_8(5F, 0E, EA, 90, 7C, 1D, 43, 7A), + BYTES_TO_WORDS_8(9D, 81, 7E, 1D, CE, B1, 60, 0A), + BYTES_TO_WORDS_8(C0, B8, F0, B5, 13, 31, DA, E9), + BYTES_TO_WORDS_8(7C, 14, 9A, 28, BD, 1D, F4, F8), + BYTES_TO_WORDS_8(29, DC, 92, 92, BF, 98, 9E, 5D), + BYTES_TO_WORDS_8(6F, 2C, 26, 96, 4A, DE, 17, 36)}, + /* b */ + {BYTES_TO_WORDS_8(EF, 2A, EC, D3, ED, C8, 85, 2A), + BYTES_TO_WORDS_8(9D, D1, 2E, 8A, 8D, 39, 56, C6), + BYTES_TO_WORDS_8(5A, 87, 13, 50, 8F, 08, 14, 03), + BYTES_TO_WORDS_8(12, 41, 81, FE, 6E, 9C, 1D, 18), + BYTES_TO_WORDS_8(19, 2D, F8, E3, 6B, 05, 8E, 98), + BYTES_TO_WORDS_8(E4, E7, 3E, E2, A7, 2F, 31, B3)}, + &double_jacobian_default, +#if MG_UECC_SUPPORT_COMPRESSED_POINT + &mod_sqrt_default, +#endif + &x_side_default, +#if (MG_UECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp384r1 +#endif +}; + +MG_UECC_Curve mg_uecc_secp384r1(void) { + return &curve_secp384r1; +} + +#if (MG_UECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp384r1(mg_uecc_word_t *result, + mg_uecc_word_t *product) { + mg_uecc_vli_mmod(result, product, curve_secp384r1.p, num_words_secp384r1); +} +#endif + +#endif /* MG_UECC_SUPPORTS_secp384r1 */ + #endif /* _UECC_CURVE_SPECIFIC_H_ */ /* Returns 1 if 'point' is the point at infinity, 0 otherwise. */ diff --git a/src/tls_uecc.h b/src/tls_uecc.h index b172d915..46cb9e46 100644 --- a/src/tls_uecc.h +++ b/src/tls_uecc.h @@ -1,7 +1,6 @@ #pragma once #include "arch.h" -#define MG_UECC_SUPPORTS_secp256r1 1 /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ #ifndef _UECC_H_ @@ -72,6 +71,9 @@ endianness. */ #ifndef MG_UECC_SUPPORTS_secp256k1 #define MG_UECC_SUPPORTS_secp256k1 0 #endif +#ifndef MG_UECC_SUPPORTS_secp384r1 +#define MG_UECC_SUPPORTS_secp384r1 1 +#endif /* Specifies whether compressed point format is supported. Set to 0 to disable point compression/decompression functions. */ @@ -101,6 +103,9 @@ MG_UECC_Curve mg_uecc_secp256r1(void); #if MG_UECC_SUPPORTS_secp256k1 MG_UECC_Curve mg_uecc_secp256k1(void); #endif +#if MG_UECC_SUPPORTS_secp384r1 +MG_UECC_Curve mg_uecc_secp384r1(void); +#endif /* MG_UECC_RNG_Function type The RNG function should fill 'size' random bytes into 'dest'. It should return 1 diff --git a/test/unit_test.c b/test/unit_test.c index 96f84841..a4b4eb09 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -1572,13 +1572,9 @@ static void test_http_client(void) { ASSERT(ok == 301 || ok == 200); mg_mgr_poll(&mgr, 0); ok = 0; -#if MG_TLS && MG_TLS != MG_TLS_BUILTIN +#if MG_TLS url = "https://cesanta.com"; opts.name = mg_url_host(url); -#if MG_TLS == MG_TLS_BUILTIN - // our TLS does not search for the proper CA in a bundle - opts.ca = mg_file_read(&mg_fs_posix, "data/e8.crt"); -#endif c = mg_http_connect(&mgr, url, f3, &ok); ASSERT(c != NULL); mg_tls_init(c, &opts); @@ -1608,9 +1604,6 @@ static void test_http_client(void) { ASSERT(ok == 200); mg_mgr_poll(&mgr, 1); opts.name = mg_url_host(url); -#if MG_TLS == MG_TLS_BUILTIN - mg_free((void *) opts.ca.buf); -#endif // Test empty CA // Disable mbedTLS: https://github.com/Mbed-TLS/mbedtls/issues/7075 @@ -4863,13 +4856,9 @@ int main(void) { test_sntp(); DASHBOARD("sntp"); -#if MG_TLS != MG_TLS_BUILTIN s_error = false; test_mqtt(); // sorry, MQTT_LOCALHOST is also skipped DASHBOARD("mqtt"); -#else - (void) test_mqtt; -#endif s_error = false; test_http_client();