X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=src%2Fssl%2Fssl_hs_server.t0;h=a7475af0e1a2eb2621354313625546365797de3c;hp=a31ab6aaeba94934dfa525ec48aac7441b5729ca;hb=ef318ef83a3a58b0a9e036676b84d11261ed7bb4;hpb=44c79c1add4cd4a217b1dd77c8421c1d3a08dcef diff --git a/src/ssl/ssl_hs_server.t0 b/src/ssl/ssl_hs_server.t0 index a31ab6a..a7475af 100644 --- a/src/ssl/ssl_hs_server.t0 +++ b/src/ssl/ssl_hs_server.t0 @@ -169,6 +169,44 @@ do_static_ecdh(br_ssl_server_context *ctx, int prf_id) do_ecdh(ctx, prf_id, cpoint, cpoint_len); } +static size_t +hash_data(br_ssl_server_context *ctx, + void *dst, int hash_id, const void *src, size_t len) +{ + const br_hash_class *hf; + br_hash_compat_context hc; + + if (hash_id == 0) { + unsigned char tmp[36]; + + hf = br_multihash_getimpl(&ctx->eng.mhash, br_md5_ID); + if (hf == NULL) { + return 0; + } + hf->init(&hc.vtable); + hf->update(&hc.vtable, src, len); + hf->out(&hc.vtable, tmp); + hf = br_multihash_getimpl(&ctx->eng.mhash, br_sha1_ID); + if (hf == NULL) { + return 0; + } + hf->init(&hc.vtable); + hf->update(&hc.vtable, src, len); + hf->out(&hc.vtable, tmp + 16); + memcpy(dst, tmp, 36); + return 36; + } else { + hf = br_multihash_getimpl(&ctx->eng.mhash, hash_id); + if (hf == NULL) { + return 0; + } + hf->init(&hc.vtable); + hf->update(&hc.vtable, src, len); + hf->out(&hc.vtable, dst); + return (hf->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; + } +} + /* * Do the ECDHE key exchange (part 1: generation of transient key, and * computing of the point to send to the client). Returned value is the @@ -179,12 +217,10 @@ do_static_ecdh(br_ssl_server_context *ctx, int prf_id) static int do_ecdhe_part1(br_ssl_server_context *ctx, int curve) { - int hash; + unsigned algo_id; unsigned mask; const unsigned char *order; size_t olen, glen; - br_multihash_context mhc; - unsigned char head[4]; size_t hv_len, sig_len; if (!((ctx->eng.iec->supported_curves >> curve) & 1)) { @@ -213,55 +249,33 @@ do_ecdhe_part1(br_ssl_server_context *ctx, int curve) /* * Compute our ECDH point. */ -#if 0 -/* obsolete */ - generator = ctx->eng.iec->generator(curve, &glen); - memcpy(ctx->eng.ecdhe_point, generator, glen); - ctx->eng.ecdhe_point_len = glen; - if (!ctx->eng.iec->mul(ctx->eng.ecdhe_point, glen, - ctx->ecdhe_key, olen, curve)) - { - return -BR_ERR_INVALID_ALGORITHM; - } -#endif glen = ctx->eng.iec->mulgen(ctx->eng.ecdhe_point, ctx->ecdhe_key, olen, curve); ctx->eng.ecdhe_point_len = glen; /* - * Compute the signature. + * Assemble the message to be signed, and possibly hash it. */ - br_multihash_zero(&mhc); - br_multihash_copyimpl(&mhc, &ctx->eng.mhash); - br_multihash_init(&mhc); - br_multihash_update(&mhc, - ctx->eng.client_random, sizeof ctx->eng.client_random); - br_multihash_update(&mhc, - ctx->eng.server_random, sizeof ctx->eng.server_random); - head[0] = 3; - head[1] = 0; - head[2] = curve; - head[3] = ctx->eng.ecdhe_point_len; - br_multihash_update(&mhc, head, sizeof head); - br_multihash_update(&mhc, + memcpy(ctx->eng.pad, ctx->eng.client_random, 32); + memcpy(ctx->eng.pad + 32, ctx->eng.server_random, 32); + ctx->eng.pad[64 + 0] = 0x03; + ctx->eng.pad[64 + 1] = 0x00; + ctx->eng.pad[64 + 2] = curve; + ctx->eng.pad[64 + 3] = ctx->eng.ecdhe_point_len; + memcpy(ctx->eng.pad + 64 + 4, ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len); - hash = ctx->sign_hash_id; - if (hash) { - hv_len = br_multihash_out(&mhc, hash, ctx->eng.pad); + hv_len = 64 + 4 + ctx->eng.ecdhe_point_len; + algo_id = ctx->sign_hash_id; + if (algo_id >= (unsigned)0xFF00) { + hv_len = hash_data(ctx, ctx->eng.pad, algo_id & 0xFF, + ctx->eng.pad, hv_len); if (hv_len == 0) { return -BR_ERR_INVALID_ALGORITHM; } - } else { - if (!br_multihash_out(&mhc, br_md5_ID, ctx->eng.pad) - || !br_multihash_out(&mhc, - br_sha1_ID, ctx->eng.pad + 16)) - { - return -BR_ERR_INVALID_ALGORITHM; - } - hv_len = 36; } + sig_len = (*ctx->policy_vtable)->do_sign(ctx->policy_vtable, - hash, hv_len, ctx->eng.pad, sizeof ctx->eng.pad); + algo_id, ctx->eng.pad, hv_len, sizeof ctx->eng.pad); return sig_len ? (int)sig_len : -BR_ERR_INVALID_ALGORITHM; } @@ -509,7 +523,7 @@ cc: set-max-frag-len ( len -- ) { \ Open extension value. read16 open-elt - read-list-sign-algos addr-hashes set16 + read-list-sign-algos addr-hashes set32 \ Close extension value. close-elt ; @@ -578,7 +592,7 @@ cc: call-policy-handler ( -- bool ) { x = (*CTX->policy_vtable)->choose( CTX->policy_vtable, CTX, &choices); ENG->session.cipher_suite = choices.cipher_suite; - CTX->sign_hash_id = choices.hash_id; + CTX->sign_hash_id = choices.algo_id; ENG->chain = choices.chain; ENG->chain_len = choices.chain_len; T0_PUSHi(-(x != 0)); @@ -714,7 +728,7 @@ cc: save-session ( -- ) { \ -- client is reputed to know RSA and ECDSA, both with SHA-1 \ -- the default elliptic curve is P-256 (secp256r1, id = 23) 0 addr-server_name set8 - 0x404 addr-hashes set16 + 0x0404 addr-hashes set32 0x800000 addr-curves set32 \ Process extensions, if any. @@ -813,8 +827,8 @@ cc: save-session ( -- ) { \ Filter hash function support by what the server also supports. \ If no common hash function remains with RSA and/or ECDSA, then \ the corresponding ECDHE suites are not possible. - supported-hash-functions drop 257 * - addr-hashes get16 and dup addr-hashes set16 + supported-hash-functions drop 257 * 0xFFFF0000 or + addr-hashes get32 and dup addr-hashes set32 \ In 'can-ecdhe', bit 12 is set if ECDHE_RSA is possible, bit 13 is \ set if ECDHE_ECDSA is possible. dup 0xFF and 0<> neg @@ -1008,11 +1022,18 @@ cc: do-ecdhe-part1 ( curve -- len ) { \ If TLS-1.2+, write hash and signature identifiers. tls1.2+ if - \ Hash identifier is in the sign_hash_id field. - addr-sign_hash_id get8 write8 - \ 'use-rsa-ecdhe?' returns -1 for RSA, 0 for ECDSA. - \ The byte on the wire shall be 1 for RSA, 3 for ECDSA. - addr-cipher_suite get16 use-rsa-ecdhe? 1 << 3 + write8 + \ sign_hash_id contains either a hash identifier, + \ or the complete 16-bit value to write. + addr-sign_hash_id get16 + dup 0xFF00 < if + write16 + else + 0xFF and write8 + \ 'use-rsa-ecdhe?' returns -1 for RSA, 0 for + \ ECDSA. The byte on the wire shall be 1 for RSA, + \ 3 for ECDSA. + addr-cipher_suite get16 use-rsa-ecdhe? 1 << 3 + write8 + then then \ Signature.