From: Thomas Pornin Date: Sun, 15 Jan 2017 19:40:24 +0000 (+0100) Subject: Activated Curve25519 support for ECDHE cipher suites. X-Git-Tag: v0.4~18 X-Git-Url: https://bearssl.org/gitweb//home/git/?a=commitdiff_plain;h=3655193439d4e093bb80a2f0d9e02179d424de08;p=BearSSL Activated Curve25519 support for ECDHE cipher suites. --- diff --git a/Makefile b/Makefile index 98fefd5..6f4e496 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ TESTX509 = testx509 TESTMATH = testmath OBJCODEC = $(BUILD)/ccopy.o $(BUILD)/dec16be.o $(BUILD)/dec16le.o $(BUILD)/dec32be.o $(BUILD)/dec32le.o $(BUILD)/dec64be.o $(BUILD)/dec64le.o $(BUILD)/enc16be.o $(BUILD)/enc16le.o $(BUILD)/enc32be.o $(BUILD)/enc32le.o $(BUILD)/enc64be.o $(BUILD)/enc64le.o $(BUILD)/pemdec.o -OBJEC = $(BUILD)/ec_c25519_i15.o $(BUILD)/ec_c25519_m15.o $(BUILD)/ec_curve25519.o $(BUILD)/ec_p256_m15.o $(BUILD)/ec_prime_i15.o $(BUILD)/ec_prime_i31.o $(BUILD)/ec_secp256r1.o $(BUILD)/ec_secp384r1.o $(BUILD)/ec_secp521r1.o $(BUILD)/ecdsa_atr.o $(BUILD)/ecdsa_i15_bits.o $(BUILD)/ecdsa_i15_sign_asn1.o $(BUILD)/ecdsa_i15_sign_raw.o $(BUILD)/ecdsa_i15_vrfy_asn1.o $(BUILD)/ecdsa_i15_vrfy_raw.o $(BUILD)/ecdsa_i31_bits.o $(BUILD)/ecdsa_i31_sign_asn1.o $(BUILD)/ecdsa_i31_sign_raw.o $(BUILD)/ecdsa_i31_vrfy_asn1.o $(BUILD)/ecdsa_i31_vrfy_raw.o $(BUILD)/ecdsa_rta.o +OBJEC = $(BUILD)/ec_all_m15.o $(BUILD)/ec_c25519_i15.o $(BUILD)/ec_c25519_m15.o $(BUILD)/ec_curve25519.o $(BUILD)/ec_p256_m15.o $(BUILD)/ec_prime_i15.o $(BUILD)/ec_prime_i31.o $(BUILD)/ec_secp256r1.o $(BUILD)/ec_secp384r1.o $(BUILD)/ec_secp521r1.o $(BUILD)/ecdsa_atr.o $(BUILD)/ecdsa_i15_bits.o $(BUILD)/ecdsa_i15_sign_asn1.o $(BUILD)/ecdsa_i15_sign_raw.o $(BUILD)/ecdsa_i15_vrfy_asn1.o $(BUILD)/ecdsa_i15_vrfy_raw.o $(BUILD)/ecdsa_i31_bits.o $(BUILD)/ecdsa_i31_sign_asn1.o $(BUILD)/ecdsa_i31_sign_raw.o $(BUILD)/ecdsa_i31_vrfy_asn1.o $(BUILD)/ecdsa_i31_vrfy_raw.o $(BUILD)/ecdsa_rta.o # $(BUILD)/ec_prime_i31_secp256r1.o $(BUILD)/ec_prime_i31_secp384r1.o $(BUILD)/ec_prime_i31_secp521r1.o OBJHASH = $(BUILD)/dig_oid.o $(BUILD)/dig_size.o $(BUILD)/ghash_ctmul.o $(BUILD)/ghash_ctmul32.o $(BUILD)/ghash_ctmul64.o $(BUILD)/md5.o $(BUILD)/md5sha1.o $(BUILD)/multihash.o $(BUILD)/sha1.o $(BUILD)/sha2big.o $(BUILD)/sha2small.o OBJINT15 = $(BUILD)/i15_core.o $(BUILD)/i15_ext1.o $(BUILD)/i15_ext2.o @@ -162,6 +162,9 @@ $(BUILD)/ec_g_secp384r1.o: src/ec/ec_g_secp384r1.c $(HEADERS) $(BUILD)/ec_g_secp521r1.o: src/ec/ec_g_secp521r1.c $(HEADERS) $(CC) $(CFLAGS) -c -o $(BUILD)/ec_g_secp521r1.o src/ec/ec_g_secp521r1.c +$(BUILD)/ec_all_m15.o: src/ec/ec_all_m15.c $(HEADERS) + $(CC) $(CFLAGS) -c -o $(BUILD)/ec_all_m15.o src/ec/ec_all_m15.c + $(BUILD)/ec_c25519_i15.o: src/ec/ec_c25519_i15.c $(HEADERS) $(CC) $(CFLAGS) -c -o $(BUILD)/ec_c25519_i15.o src/ec/ec_c25519_i15.c diff --git a/inc/bearssl_ec.h b/inc/bearssl_ec.h index 1ecb4cd..5769f0a 100644 --- a/inc/bearssl_ec.h +++ b/inc/bearssl_ec.h @@ -65,6 +65,11 @@ * Callback method that returns a pointer to the subgroup order for * that curve. That value uses unsigned big-endian encoding. * + * - `xoff()` + * + * Callback method that returns the offset and length of the X + * coordinate in an encoded point. + * * - `mul()` * * Multiply a curve point with an integer. @@ -294,6 +299,18 @@ typedef struct { */ const unsigned char *(*order)(int curve, size_t *len); + /** + * \brief Get the offset and length for the X coordinate. + * + * This function returns the offset and length (in bytes) of + * the X coordinate in an encoded non-zero point. + * + * \param curve curve identifier. + * \param len receiver for the X coordinate length (in bytes). + * \return the offset for the X coordinate (in bytes). + */ + size_t (*xoff)(int curve, size_t *len); + /** * \brief Multiply a curve point by an integer. * @@ -423,8 +440,13 @@ extern const br_ec_impl br_ec_p256_m15; * \brief EC implementation "i15" (generic code) for Curve25519. * * This implementation uses the generic code for modular integers (with - * 15-bit words) to support Curve25519. The `muladd()` method is not - * implemented. + * 15-bit words) to support Curve25519. Due to the specificities of the + * curve definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). */ extern const br_ec_impl br_ec_c25519_i15; @@ -432,10 +454,27 @@ extern const br_ec_impl br_ec_c25519_i15; * \brief EC implementation "m15" (specialised code) for Curve25519. * * This implementation uses custom code relying on multiplication of - * integers up to 15 bits. The `muladd()` method is not implemented. + * integers up to 15 bits. Due to the specificities of the curve + * definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). */ extern const br_ec_impl br_ec_c25519_m15; +/** + * \brief Aggregate EC implementation "m15". + * + * This implementation is a wrapper for: + * + * - `br_ec_c25519_m15` for Curve25519 + * - `br_ec_p256_m15` for NIST P-256 + * - `br_ec_prime_i15` for other curves (NIST P-384 and NIST-P512) + */ +extern const br_ec_impl br_ec_all_m15; + /** * \brief Convert a signature from "raw" to "asn1". * diff --git a/inc/bearssl_ssl.h b/inc/bearssl_ssl.h index 3ff29f6..cf1d2db 100644 --- a/inc/bearssl_ssl.h +++ b/inc/bearssl_ssl.h @@ -1657,6 +1657,25 @@ br_ssl_engine_set_session_parameters(br_ssl_engine_context *cc, memcpy(&cc->session, pp, sizeof *pp); } +/** + * \brief Get identifier for the curve used for key exchange. + * + * If the cipher suite uses ECDHE, then this function returns the + * identifier for the curve used for transient parameters. This is + * defined during the course of the handshake, when the ServerKeyExchange + * is sent (on the server) or received (on the client). If the + * cipher suite does not use ECDHE (e.g. static ECDH, or RSA key + * exchange), then this value is indeterminate. + * + * @param cc SSL engine context. + * @return the ECDHE curve identifier. + */ +static inline int +br_ssl_engine_get_ecdhe_curve(br_ssl_engine_context *cc) +{ + return cc->ecdhe_curve; +} + /** * \brief Get the current engine state. * @@ -2136,12 +2155,13 @@ struct br_ssl_client_certificate_class_ { * structure was set to -1). * * In that situation, this callback is invoked to compute the - * client-side ECDH: the provided `data` (of length `len` bytes) + * client-side ECDH: the provided `data` (of length `*len` bytes) * is the server's public key point (as decoded from its * certificate), and the client shall multiply that point with * its own private key, and write back the X coordinate of the - * resulting point in the same buffer, starting at offset 1 - * (therefore, writing back the complete encoded point works). + * resulting point in the same buffer, starting at offset 0. + * The `*len` value shall be modified to designate the actual + * length of the X coordinate. * * The callback must uphold the following: * @@ -2158,11 +2178,11 @@ struct br_ssl_client_certificate_class_ { * * \param pctx certificate handler context. * \param data server public key point. - * \param len server public key point length (in bytes). + * \param len public key point length / X coordinate length. * \return 1 on success, 0 on error. */ uint32_t (*do_keyx)(const br_ssl_client_certificate_class **pctx, - unsigned char *data, size_t len); + unsigned char *data, size_t *len); /** * \brief Perform a signature (client authentication). @@ -2791,12 +2811,12 @@ struct br_ssl_server_policy_class_ { * operation for a key exchange that is not ECDHE. This callback * uses the private key. * - * **For RSA key exchange**, the provided `data` (of length `len` + * **For RSA key exchange**, the provided `data` (of length `*len` * bytes) shall be decrypted with the server's private key, and * the 48-byte premaster secret copied back to the first 48 bytes * of `data`. * - * - The caller makes sure that `len` is at least 59 bytes. + * - The caller makes sure that `*len` is at least 59 bytes. * * - This callback MUST check that the provided length matches * that of the key modulus; it shall report an error otherwise. @@ -2813,12 +2833,11 @@ struct br_ssl_server_policy_class_ { * in the first 48 bytes of `data` is unimportant (the caller * will use random bytes instead). * - * **For ECDH key exchange**, the provided `data` (of length `len` + * **For ECDH key exchange**, the provided `data` (of length `*len` * bytes) is the elliptic curve point from the client. The * callback shall multiply it with its private key, and store - * the resulting X coordinate in `data`, starting at offset 1 - * (thus, simply encoding the point in compressed or uncompressed - * format in `data` is fine). + * the resulting X coordinate in `data`, starting at offset 0, + * and set `*len` to the length of the X coordinate. * * - If the input array does not have the proper length for * an encoded curve point, then an error (0) shall be reported. @@ -2837,7 +2856,7 @@ struct br_ssl_server_policy_class_ { * \return 1 on success, 0 on error. */ uint32_t (*do_keyx)(const br_ssl_server_policy_class **pctx, - unsigned char *data, size_t len); + unsigned char *data, size_t *len); /** * \brief Perform a signature (for a ServerKeyExchange message). diff --git a/src/ec/ec_all_m15.c b/src/ec/ec_all_m15.c new file mode 100644 index 0000000..bb550e1 --- /dev/null +++ b/src/ec/ec_all_m15.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + switch (curve) { + case BR_EC_secp256r1: + return br_ec_p256_m15.generator(curve, len); + case BR_EC_curve25519: + return br_ec_c25519_m15.generator(curve, len); + default: + return br_ec_prime_i15.generator(curve, len); + } +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + switch (curve) { + case BR_EC_secp256r1: + return br_ec_p256_m15.order(curve, len); + case BR_EC_curve25519: + return br_ec_c25519_m15.order(curve, len); + default: + return br_ec_prime_i15.order(curve, len); + } +} + +static size_t +api_xoff(int curve, size_t *len) +{ + switch (curve) { + case BR_EC_secp256r1: + return br_ec_p256_m15.xoff(curve, len); + case BR_EC_curve25519: + return br_ec_c25519_m15.xoff(curve, len); + default: + return br_ec_prime_i15.xoff(curve, len); + } +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *kb, size_t kblen, int curve) +{ + switch (curve) { + case BR_EC_secp256r1: + return br_ec_p256_m15.mul(G, Glen, kb, kblen, curve); + case BR_EC_curve25519: + return br_ec_c25519_m15.mul(G, Glen, kb, kblen, curve); + default: + return br_ec_prime_i15.mul(G, Glen, kb, kblen, curve); + } +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + switch (curve) { + case BR_EC_secp256r1: + return br_ec_p256_m15.mulgen(R, x, xlen, curve); + case BR_EC_curve25519: + return br_ec_c25519_m15.mulgen(R, x, xlen, curve); + default: + return br_ec_prime_i15.mulgen(R, x, xlen, curve); + } +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + switch (curve) { + case BR_EC_secp256r1: + return br_ec_p256_m15.muladd(A, B, len, + x, xlen, y, ylen, curve); + case BR_EC_curve25519: + return br_ec_c25519_m15.muladd(A, B, len, + x, xlen, y, ylen, curve); + default: + return br_ec_prime_i15.muladd(A, B, len, + x, xlen, y, ylen, curve); + } +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_all_m15 = { + (uint32_t)0x23800000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; diff --git a/src/ec/ec_c25519_i15.c b/src/ec/ec_c25519_i15.c index 6e4c4f8..d88f19c 100644 --- a/src/ec/ec_c25519_i15.c +++ b/src/ec/ec_c25519_i15.c @@ -82,10 +82,10 @@ static const unsigned char GEN[] = { }; static const unsigned char ORDER[] = { - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6, - 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static const unsigned char * @@ -104,6 +104,14 @@ api_order(int curve, size_t *len) return ORDER; } +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 0; +} + static void cswap(uint16_t *a, uint16_t *b, uint32_t ctl) { @@ -349,6 +357,7 @@ const br_ec_impl br_ec_c25519_i15 = { (uint32_t)0x20000000, &api_generator, &api_order, + &api_xoff, &api_mul, &api_mulgen, &api_muladd diff --git a/src/ec/ec_c25519_m15.c b/src/ec/ec_c25519_m15.c index 5079d5e..3cb98d5 100644 --- a/src/ec/ec_c25519_m15.c +++ b/src/ec/ec_c25519_m15.c @@ -1231,10 +1231,10 @@ static const unsigned char GEN[] = { }; static const unsigned char ORDER[] = { - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6, - 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static const unsigned char * @@ -1253,6 +1253,14 @@ api_order(int curve, size_t *len) return ORDER; } +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 0; +} + static void cswap(uint32_t *a, uint32_t *b, uint32_t ctl) { @@ -1445,6 +1453,7 @@ const br_ec_impl br_ec_c25519_m15 = { (uint32_t)0x20000000, &api_generator, &api_order, + &api_xoff, &api_mul, &api_mulgen, &api_muladd diff --git a/src/ec/ec_p256_m15.c b/src/ec/ec_p256_m15.c index 99c7224..0d40aef 100644 --- a/src/ec/ec_p256_m15.c +++ b/src/ec/ec_p256_m15.c @@ -1987,6 +1987,14 @@ api_order(int curve, size_t *len) return P256_N; } +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 1; +} + static uint32_t api_mul(unsigned char *G, size_t Glen, const unsigned char *x, size_t xlen, int curve) @@ -2079,6 +2087,7 @@ const br_ec_impl br_ec_p256_m15 = { (uint32_t)0x00800000, &api_generator, &api_order, + &api_xoff, &api_mul, &api_mulgen, &api_muladd diff --git a/src/ec/ec_prime_i15.c b/src/ec/ec_prime_i15.c index bf1d002..85affe5 100644 --- a/src/ec/ec_prime_i15.c +++ b/src/ec/ec_prime_i15.c @@ -716,6 +716,14 @@ api_order(int curve, size_t *len) return cd->order; } +static size_t +api_xoff(int curve, size_t *len) +{ + api_generator(curve, len); + *len >>= 1; + return 1; +} + static uint32_t api_mul(unsigned char *G, size_t Glen, const unsigned char *x, size_t xlen, int curve) @@ -805,6 +813,7 @@ const br_ec_impl br_ec_prime_i15 = { (uint32_t)0x03800000, &api_generator, &api_order, + &api_xoff, &api_mul, &api_mulgen, &api_muladd diff --git a/src/ec/ec_prime_i31.c b/src/ec/ec_prime_i31.c index 0f2baa0..ce4d4ab 100644 --- a/src/ec/ec_prime_i31.c +++ b/src/ec/ec_prime_i31.c @@ -717,6 +717,14 @@ api_order(int curve, size_t *len) return cd->order; } +static size_t +api_xoff(int curve, size_t *len) +{ + api_generator(curve, len); + *len >>= 1; + return 1; +} + static uint32_t api_mul(unsigned char *G, size_t Glen, const unsigned char *x, size_t xlen, int curve) @@ -804,6 +812,7 @@ const br_ec_impl br_ec_prime_i31 = { (uint32_t)0x03800000, &api_generator, &api_order, + &api_xoff, &api_mul, &api_mulgen, &api_muladd diff --git a/src/ssl/ssl_ccert_single_ec.c b/src/ssl/ssl_ccert_single_ec.c index 1df19a9..93ebcde 100644 --- a/src/ssl/ssl_ccert_single_ec.c +++ b/src/ssl/ssl_ccert_single_ec.c @@ -89,12 +89,18 @@ cc_choose(const br_ssl_client_certificate_class **pctx, static uint32_t cc_do_keyx(const br_ssl_client_certificate_class **pctx, - unsigned char *data, size_t len) + unsigned char *data, size_t *len) { br_ssl_client_certificate_ec_context *zc; + uint32_t r; + size_t xoff, xlen; zc = (br_ssl_client_certificate_ec_context *)pctx; - return zc->iec->mul(data, len, zc->sk->x, zc->sk->xlen, zc->sk->curve); + r = zc->iec->mul(data, *len, zc->sk->x, zc->sk->xlen, zc->sk->curve); + xoff = zc->iec->xoff(zc->sk->curve, &xlen); + memmove(data, data + xoff, xlen); + *len = xlen; + return r; } static size_t diff --git a/src/ssl/ssl_client_full.c b/src/ssl/ssl_client_full.c index 7480de8..cd49a93 100644 --- a/src/ssl/ssl_client_full.c +++ b/src/ssl/ssl_client_full.c @@ -127,11 +127,11 @@ br_ssl_client_init_full(br_ssl_client_context *cc, (sizeof suites) / (sizeof suites[0])); br_ssl_client_set_rsapub(cc, &br_rsa_i31_public); br_ssl_engine_set_rsavrfy(&cc->eng, &br_rsa_i31_pkcs1_vrfy); - br_ssl_engine_set_ec(&cc->eng, &br_ec_prime_i31); + br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); br_ssl_engine_set_ecdsa(&cc->eng, &br_ecdsa_i31_vrfy_asn1); br_x509_minimal_set_rsa(xc, &br_rsa_i31_pkcs1_vrfy); br_x509_minimal_set_ecdsa(xc, - &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1); + &br_ec_all_m15, &br_ecdsa_i31_vrfy_asn1); /* * Set supported hash functions, for the SSL engine and for the diff --git a/src/ssl/ssl_hs_client.c b/src/ssl/ssl_hs_client.c index 6f5131a..c703f8c 100644 --- a/src/ssl/ssl_hs_client.c +++ b/src/ssl/ssl_hs_client.c @@ -286,7 +286,7 @@ make_pms_ecdh(br_ssl_client_context *ctx, unsigned ecdhe, int prf_id) int curve; unsigned char key[66], point[133]; const unsigned char *order, *point_src; - size_t glen, olen, point_len; + size_t glen, olen, point_len, xoff, xlen; unsigned char mask; if (ecdhe) { @@ -339,7 +339,8 @@ make_pms_ecdh(br_ssl_client_context *ctx, unsigned ecdhe, int prf_id) /* * The pre-master secret is the X coordinate. */ - br_ssl_engine_compute_master(&ctx->eng, prf_id, point + 1, glen >> 1); + xoff = ctx->eng.iec->xoff(curve, &xlen); + br_ssl_engine_compute_master(&ctx->eng, prf_id, point + xoff, xlen); ctx->eng.iec->mulgen(point, key, olen, curve); memcpy(ctx->eng.pad, point, glen); @@ -372,12 +373,12 @@ make_pms_static_ecdh(br_ssl_client_context *ctx, int prf_id) } memcpy(point, pk->key.ec.q, point_len); if (!(*ctx->client_auth_vtable)->do_keyx( - ctx->client_auth_vtable, point, point_len)) + ctx->client_auth_vtable, point, &point_len)) { return -1; } br_ssl_engine_compute_master(&ctx->eng, - prf_id, point + 1, point_len >> 1); + prf_id, point, point_len); return 0; } @@ -710,7 +711,7 @@ static const uint8_t t0_codeblock[] = { 0x8B, 0x8C, 0x2E, 0xD7, 0x8F, 0x2E, 0x26, 0x01, 0x01, 0x0B, 0xD9, 0x8E, 0x44, 0x26, 0x06, 0x0F, 0x5B, 0x38, 0x2C, 0x26, 0xC5, 0x05, 0x02, 0x60, 0x28, 0xD9, 0x44, 0x5C, 0x44, 0x04, 0x6E, 0x5E, 0x01, 0x01, 0xDB, 0x01, - 0x00, 0xDB, 0x02, 0x00, 0x06, 0x81, 0x46, 0x02, 0x00, 0xD9, 0xA2, 0x06, + 0x00, 0xDB, 0x02, 0x00, 0x06, 0x81, 0x5A, 0x02, 0x00, 0xD9, 0xA2, 0x06, 0x0E, 0x01, 0x83, 0xFE, 0x01, 0xD9, 0x87, 0xA2, 0x01, 0x04, 0x09, 0x26, 0xD9, 0x5B, 0xD7, 0xA4, 0x06, 0x16, 0x01, 0x00, 0xD9, 0x89, 0xA4, 0x01, 0x04, 0x09, 0x26, 0xD9, 0x01, 0x02, 0x09, 0x26, 0xD9, 0x01, 0x00, 0xDB, @@ -718,29 +719,31 @@ static const uint8_t t0_codeblock[] = { 0xD9, 0x80, 0x2E, 0x01, 0x08, 0x09, 0xDB, 0xA3, 0x06, 0x19, 0x01, 0x0D, 0xD9, 0xA3, 0x01, 0x04, 0x09, 0x26, 0xD9, 0x01, 0x02, 0x09, 0xD9, 0x42, 0x06, 0x03, 0x01, 0x03, 0xD8, 0x43, 0x06, 0x03, 0x01, 0x01, 0xD8, 0xA5, - 0x26, 0x06, 0x22, 0x01, 0x0A, 0xD9, 0x01, 0x04, 0x09, 0x26, 0xD9, 0x5D, - 0xD9, 0x40, 0x01, 0x00, 0x26, 0x01, 0x20, 0x0A, 0x06, 0x0C, 0x9E, 0x11, - 0x01, 0x01, 0x17, 0x06, 0x02, 0x26, 0xD9, 0x5A, 0x04, 0x6E, 0x5E, 0x04, - 0x01, 0x25, 0xA1, 0x06, 0x0A, 0x01, 0x0B, 0xD9, 0x01, 0x02, 0xD9, 0x01, - 0x82, 0x00, 0xD9, 0x27, 0x26, 0x06, 0x1F, 0x01, 0x10, 0xD9, 0x01, 0x04, - 0x09, 0x26, 0xD9, 0x5D, 0xD9, 0x83, 0x2C, 0x01, 0x00, 0x9E, 0x0F, 0x06, - 0x0A, 0x26, 0x1E, 0x26, 0xDB, 0x82, 0x44, 0xD5, 0x5A, 0x04, 0x72, 0x5E, - 0x04, 0x01, 0x25, 0x02, 0x01, 0x56, 0x05, 0x11, 0x01, 0x15, 0xD9, 0x02, - 0x01, 0x26, 0xD9, 0x26, 0x06, 0x06, 0x5B, 0x01, 0x00, 0xDB, 0x04, 0x77, - 0x25, 0x00, 0x00, 0x01, 0x10, 0xDB, 0x77, 0x2C, 0x26, 0xCA, 0x06, 0x0C, - 0xA9, 0x23, 0x26, 0x5C, 0xDA, 0x26, 0xD9, 0x82, 0x44, 0xD5, 0x04, 0x0D, - 0x26, 0xC8, 0x44, 0xA9, 0x22, 0x26, 0x5A, 0xDA, 0x26, 0xDB, 0x82, 0x44, - 0xD5, 0x00, 0x00, 0x9A, 0x01, 0x14, 0xDB, 0x01, 0x0C, 0xDA, 0x82, 0x01, - 0x0C, 0xD5, 0x00, 0x00, 0x4F, 0x26, 0x01, 0x00, 0x0E, 0x06, 0x02, 0x5E, - 0x00, 0xCB, 0x25, 0x04, 0x73, 0x00, 0x26, 0xD9, 0xD5, 0x00, 0x00, 0x26, - 0xDB, 0xD5, 0x00, 0x01, 0x03, 0x00, 0x41, 0x25, 0x26, 0x01, 0x10, 0x17, - 0x06, 0x06, 0x01, 0x04, 0xDB, 0x02, 0x00, 0xDB, 0x26, 0x01, 0x08, 0x17, - 0x06, 0x06, 0x01, 0x03, 0xDB, 0x02, 0x00, 0xDB, 0x26, 0x01, 0x20, 0x17, - 0x06, 0x06, 0x01, 0x05, 0xDB, 0x02, 0x00, 0xDB, 0x26, 0x01, 0x80, 0x40, - 0x17, 0x06, 0x06, 0x01, 0x06, 0xDB, 0x02, 0x00, 0xDB, 0x01, 0x04, 0x17, - 0x06, 0x06, 0x01, 0x02, 0xDB, 0x02, 0x00, 0xDB, 0x00, 0x00, 0x26, 0x01, - 0x08, 0x4D, 0xDB, 0xDB, 0x00, 0x00, 0x26, 0x01, 0x10, 0x4D, 0xDB, 0xD9, - 0x00, 0x00, 0x26, 0x50, 0x06, 0x02, 0x25, 0x00, 0xCB, 0x25, 0x04, 0x76 + 0x26, 0x06, 0x36, 0x01, 0x0A, 0xD9, 0x01, 0x04, 0x09, 0x26, 0xD9, 0x5D, + 0xD9, 0x40, 0x01, 0x00, 0x26, 0x01, 0x82, 0x80, 0x80, 0x80, 0x00, 0x17, + 0x06, 0x0A, 0x01, 0xFD, 0xFF, 0xFF, 0xFF, 0x7F, 0x17, 0x01, 0x1D, 0xD9, + 0x26, 0x01, 0x20, 0x0A, 0x06, 0x0C, 0x9E, 0x11, 0x01, 0x01, 0x17, 0x06, + 0x02, 0x26, 0xD9, 0x5A, 0x04, 0x6E, 0x5E, 0x04, 0x01, 0x25, 0xA1, 0x06, + 0x0A, 0x01, 0x0B, 0xD9, 0x01, 0x02, 0xD9, 0x01, 0x82, 0x00, 0xD9, 0x27, + 0x26, 0x06, 0x1F, 0x01, 0x10, 0xD9, 0x01, 0x04, 0x09, 0x26, 0xD9, 0x5D, + 0xD9, 0x83, 0x2C, 0x01, 0x00, 0x9E, 0x0F, 0x06, 0x0A, 0x26, 0x1E, 0x26, + 0xDB, 0x82, 0x44, 0xD5, 0x5A, 0x04, 0x72, 0x5E, 0x04, 0x01, 0x25, 0x02, + 0x01, 0x56, 0x05, 0x11, 0x01, 0x15, 0xD9, 0x02, 0x01, 0x26, 0xD9, 0x26, + 0x06, 0x06, 0x5B, 0x01, 0x00, 0xDB, 0x04, 0x77, 0x25, 0x00, 0x00, 0x01, + 0x10, 0xDB, 0x77, 0x2C, 0x26, 0xCA, 0x06, 0x0C, 0xA9, 0x23, 0x26, 0x5C, + 0xDA, 0x26, 0xD9, 0x82, 0x44, 0xD5, 0x04, 0x0D, 0x26, 0xC8, 0x44, 0xA9, + 0x22, 0x26, 0x5A, 0xDA, 0x26, 0xDB, 0x82, 0x44, 0xD5, 0x00, 0x00, 0x9A, + 0x01, 0x14, 0xDB, 0x01, 0x0C, 0xDA, 0x82, 0x01, 0x0C, 0xD5, 0x00, 0x00, + 0x4F, 0x26, 0x01, 0x00, 0x0E, 0x06, 0x02, 0x5E, 0x00, 0xCB, 0x25, 0x04, + 0x73, 0x00, 0x26, 0xD9, 0xD5, 0x00, 0x00, 0x26, 0xDB, 0xD5, 0x00, 0x01, + 0x03, 0x00, 0x41, 0x25, 0x26, 0x01, 0x10, 0x17, 0x06, 0x06, 0x01, 0x04, + 0xDB, 0x02, 0x00, 0xDB, 0x26, 0x01, 0x08, 0x17, 0x06, 0x06, 0x01, 0x03, + 0xDB, 0x02, 0x00, 0xDB, 0x26, 0x01, 0x20, 0x17, 0x06, 0x06, 0x01, 0x05, + 0xDB, 0x02, 0x00, 0xDB, 0x26, 0x01, 0x80, 0x40, 0x17, 0x06, 0x06, 0x01, + 0x06, 0xDB, 0x02, 0x00, 0xDB, 0x01, 0x04, 0x17, 0x06, 0x06, 0x01, 0x02, + 0xDB, 0x02, 0x00, 0xDB, 0x00, 0x00, 0x26, 0x01, 0x08, 0x4D, 0xDB, 0xDB, + 0x00, 0x00, 0x26, 0x01, 0x10, 0x4D, 0xDB, 0xD9, 0x00, 0x00, 0x26, 0x50, + 0x06, 0x02, 0x25, 0x00, 0xCB, 0x25, 0x04, 0x76 }; static const uint16_t t0_caddr[] = { @@ -869,15 +872,15 @@ static const uint16_t t0_caddr[] = { 2541, 2573, 2607, - 2955, - 2991, - 3004, - 3018, - 3023, - 3028, - 3094, - 3102, - 3110 + 2975, + 3011, + 3024, + 3038, + 3043, + 3048, + 3114, + 3122, + 3130 }; #define T0_INTERPRETED 86 diff --git a/src/ssl/ssl_hs_client.t0 b/src/ssl/ssl_hs_client.t0 index 5bc3d3d..89da775 100644 --- a/src/ssl/ssl_hs_client.t0 +++ b/src/ssl/ssl_hs_client.t0 @@ -231,7 +231,7 @@ make_pms_ecdh(br_ssl_client_context *ctx, unsigned ecdhe, int prf_id) int curve; unsigned char key[66], point[133]; const unsigned char *order, *point_src; - size_t glen, olen, point_len; + size_t glen, olen, point_len, xoff, xlen; unsigned char mask; if (ecdhe) { @@ -284,7 +284,8 @@ make_pms_ecdh(br_ssl_client_context *ctx, unsigned ecdhe, int prf_id) /* * The pre-master secret is the X coordinate. */ - br_ssl_engine_compute_master(&ctx->eng, prf_id, point + 1, glen >> 1); + xoff = ctx->eng.iec->xoff(curve, &xlen); + br_ssl_engine_compute_master(&ctx->eng, prf_id, point + xoff, xlen); ctx->eng.iec->mulgen(point, key, olen, curve); memcpy(ctx->eng.pad, point, glen); @@ -317,12 +318,12 @@ make_pms_static_ecdh(br_ssl_client_context *ctx, int prf_id) } memcpy(point, pk->key.ec.q, point_len); if (!(*ctx->client_auth_vtable)->do_keyx( - ctx->client_auth_vtable, point, point_len)) + ctx->client_auth_vtable, point, &point_len)) { return -1; } br_ssl_engine_compute_master(&ctx->eng, - prf_id, point + 1, point_len >> 1); + prf_id, point, point_len); return 0; } @@ -390,10 +391,9 @@ addr-ctx: hash_id \ Length of Signatures extension. : ext-signatures-length ( -- len ) - supported-hash-functions { x } drop - 0 - supports-rsa-sign? if x + then - supports-ecdsa? if x + then + supported-hash-functions { num } drop 0 + supports-rsa-sign? if num + then + supports-ecdsa? if num + then dup if 1 << 6 + then ; \ Write supported hash functions ( sign -- ) @@ -535,13 +535,16 @@ cc: ext-ALPN-length ( -- len ) { supports-rsa-sign? if 1 write-hashes then then \ TODO: add an API to specify preference order for curves. - \ Right now we use increasing id order, which makes P-256 - \ the preferred curve. + \ Right now we send Curve25519 first, then other curves in + \ increasing ID values (hence P-256 in second). ext-supported-curves-length dup if 0x000A write16 \ extension type (10) 4 - dup write16 \ extension length 2- write16 \ list length supported-curves 0 + dup 0x20000000 and if + 0xDFFFFFFF and 29 write16 + then begin dup 32 < while dup2 >> 1 and if dup write16 then 1+ diff --git a/src/ssl/ssl_hs_server.c b/src/ssl/ssl_hs_server.c index 08fc0b4..380fd7b 100644 --- a/src/ssl/ssl_hs_server.c +++ b/src/ssl/ssl_hs_server.c @@ -104,7 +104,7 @@ do_rsa_decrypt(br_ssl_server_context *ctx, int prf_id, /* * Decrypt the PMS. */ - x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, epms, len); + x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, epms, &len); /* * Set the first two bytes to the maximum supported client @@ -140,21 +140,12 @@ do_rsa_decrypt(br_ssl_server_context *ctx, int prf_id, */ static void ecdh_common(br_ssl_server_context *ctx, int prf_id, - unsigned char *cpoint, size_t cpoint_len, uint32_t ctl) + unsigned char *xcoor, size_t xcoor_len, uint32_t ctl) { unsigned char rpms[80]; - size_t pms_len; - /* - * The point length is supposed to be 1+2*Xlen, where Xlen is - * the length (in bytes) of the X coordinate, i.e. the pre-master - * secret. If the provided point is too large, then it is - * obviously incorrect (i.e. everybody can see that it is - * incorrect), so leaking that fact is not a problem. - */ - pms_len = cpoint_len >> 1; - if (pms_len > sizeof rpms) { - pms_len = sizeof rpms; + if (xcoor_len > sizeof rpms) { + xcoor_len = sizeof rpms; ctl = 0; } @@ -163,19 +154,19 @@ ecdh_common(br_ssl_server_context *ctx, int prf_id, * decryption failed. Note that we use a constant-time conditional * copy. */ - br_hmac_drbg_generate(&ctx->eng.rng, rpms, pms_len); - br_ccopy(ctl ^ 1, cpoint + 1, rpms, pms_len); + br_hmac_drbg_generate(&ctx->eng.rng, rpms, xcoor_len); + br_ccopy(ctl ^ 1, xcoor, rpms, xcoor_len); /* * Compute master secret. */ - br_ssl_engine_compute_master(&ctx->eng, prf_id, cpoint + 1, pms_len); + br_ssl_engine_compute_master(&ctx->eng, prf_id, xcoor, xcoor_len); /* * Clear the pre-master secret from RAM: it is normally a buffer * in the context, hence potentially long-lived. */ - memset(cpoint, 0, cpoint_len); + memset(xcoor, 0, xcoor_len); } /* @@ -191,7 +182,7 @@ do_ecdh(br_ssl_server_context *ctx, int prf_id, * Finalise the key exchange. */ x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, - cpoint, cpoint_len); + cpoint, &cpoint_len); ecdh_common(ctx, prf_id, cpoint, cpoint_len, x); } @@ -343,16 +334,18 @@ do_ecdhe_part2(br_ssl_server_context *ctx, int prf_id, unsigned char *cpoint, size_t cpoint_len) { int curve; - uint32_t x; + uint32_t ctl; + size_t xoff, xlen; curve = ctx->eng.ecdhe_curve; /* * Finalise the key exchange. */ - x = ctx->eng.iec->mul(cpoint, cpoint_len, + ctl = ctx->eng.iec->mul(cpoint, cpoint_len, ctx->ecdhe_key, ctx->ecdhe_key_len, curve); - ecdh_common(ctx, prf_id, cpoint, cpoint_len, x); + xoff = ctx->eng.iec->xoff(curve, &xlen); + ecdh_common(ctx, prf_id, cpoint + xoff, xlen, ctl); /* * Clear the ECDHE private key. Forward Secrecy is achieved insofar @@ -543,29 +536,31 @@ static const uint8_t t0_codeblock[] = { 0x01, 0x00, 0x01, 0x03, 0x00, 0x99, 0x2A, 0x61, 0x47, 0x9D, 0x2A, 0x05, 0x04, 0x63, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0F, 0x06, 0x02, 0x9D, 0x00, 0x61, 0x04, 0x6B, 0x00, 0x06, 0x02, 0x68, 0x2B, 0x00, 0x00, 0x2A, 0x89, - 0x47, 0x05, 0x03, 0x01, 0x0C, 0x08, 0x47, 0x76, 0x2E, 0xA5, 0x1C, 0x83, + 0x47, 0x05, 0x03, 0x01, 0x0C, 0x08, 0x47, 0x76, 0x2E, 0xA6, 0x1C, 0x83, 0x01, 0x0C, 0x33, 0x00, 0x00, 0x2A, 0x22, 0x01, 0x08, 0x0C, 0x47, 0x5F, 0x22, 0x08, 0x00, 0x01, 0x03, 0x00, 0x01, 0x00, 0x75, 0x42, 0x2C, 0x19, - 0x38, 0x06, 0x07, 0x02, 0x00, 0xCC, 0x03, 0x00, 0x04, 0x75, 0x01, 0x00, - 0xC4, 0x02, 0x00, 0x2A, 0x19, 0x13, 0x06, 0x02, 0x6F, 0x2B, 0xCC, 0x04, + 0x38, 0x06, 0x07, 0x02, 0x00, 0xCD, 0x03, 0x00, 0x04, 0x75, 0x01, 0x00, + 0xC5, 0x02, 0x00, 0x2A, 0x19, 0x13, 0x06, 0x02, 0x6F, 0x2B, 0xCD, 0x04, 0x76, 0x00, 0x01, 0x00, 0x75, 0x42, 0x01, 0x16, 0x87, 0x42, 0x01, 0x00, - 0x8A, 0x40, 0x36, 0xAE, 0x35, 0x06, 0x02, 0x71, 0x2B, 0x06, 0x0A, 0xD3, - 0x01, 0x00, 0xCF, 0x01, 0x00, 0xAA, 0x04, 0x80, 0x46, 0xD3, 0xD0, 0x29, - 0xD5, 0x4E, 0x06, 0x01, 0xD1, 0xD4, 0x2C, 0x4E, 0x06, 0x31, 0x01, 0x00, - 0xAB, 0x2A, 0x5B, 0x06, 0x0F, 0x01, 0x02, 0xA2, 0x05, 0x02, 0x37, 0x2B, - 0x29, 0xAF, 0xAD, 0x2A, 0xC5, 0x29, 0x04, 0x19, 0x2A, 0x5D, 0x06, 0x0B, - 0x29, 0x01, 0x02, 0xA2, 0x05, 0x02, 0x6E, 0x2B, 0xAF, 0x04, 0x0A, 0xB1, - 0x2A, 0x05, 0x04, 0x29, 0xA8, 0x04, 0x02, 0xB0, 0xAC, 0x04, 0x01, 0xAF, - 0x01, 0x00, 0xAA, 0x01, 0x00, 0xCF, 0x3E, 0x01, 0x01, 0x75, 0x42, 0x01, + 0x8A, 0x40, 0x36, 0xAF, 0x35, 0x06, 0x02, 0x71, 0x2B, 0x06, 0x0A, 0xD4, + 0x01, 0x00, 0xD0, 0x01, 0x00, 0xAB, 0x04, 0x80, 0x46, 0xD4, 0xD1, 0x29, + 0xD6, 0x4E, 0x06, 0x01, 0xD2, 0xD5, 0x2C, 0x4E, 0x06, 0x31, 0x01, 0x00, + 0xAC, 0x2A, 0x5B, 0x06, 0x0F, 0x01, 0x02, 0xA2, 0x05, 0x02, 0x37, 0x2B, + 0x29, 0xB0, 0xAE, 0x2A, 0xC6, 0x29, 0x04, 0x19, 0x2A, 0x5D, 0x06, 0x0B, + 0x29, 0x01, 0x02, 0xA2, 0x05, 0x02, 0x6E, 0x2B, 0xB0, 0x04, 0x0A, 0xB2, + 0x2A, 0x05, 0x04, 0x29, 0xA9, 0x04, 0x02, 0xB1, 0xAD, 0x04, 0x01, 0xB0, + 0x01, 0x00, 0xAB, 0x01, 0x00, 0xD0, 0x3E, 0x01, 0x01, 0x75, 0x42, 0x01, 0x17, 0x87, 0x42, 0x00, 0x00, 0x3A, 0x3A, 0x00, 0x01, 0x03, 0x00, 0x2C, - 0x19, 0x38, 0x06, 0x04, 0xCB, 0x29, 0x04, 0x78, 0x01, 0x02, 0x02, 0x00, - 0xC3, 0x19, 0x38, 0x06, 0x04, 0xCB, 0x29, 0x04, 0x78, 0x02, 0x00, 0x01, + 0x19, 0x38, 0x06, 0x04, 0xCC, 0x29, 0x04, 0x78, 0x01, 0x02, 0x02, 0x00, + 0xC4, 0x19, 0x38, 0x06, 0x04, 0xCC, 0x29, 0x04, 0x78, 0x02, 0x00, 0x01, 0x84, 0x00, 0x08, 0x2B, 0x00, 0x00, 0x7F, 0x2F, 0x47, 0x12, 0x01, 0x01, - 0x13, 0x37, 0x00, 0x00, 0x01, 0x7F, 0x9F, 0xCB, 0x2A, 0x01, 0x07, 0x13, + 0x13, 0x37, 0x00, 0x00, 0x2A, 0x05, 0x04, 0x29, 0x01, 0x7F, 0x00, 0x01, + 0x00, 0xA0, 0x12, 0x01, 0x01, 0x13, 0x5D, 0x06, 0x03, 0x5F, 0x04, 0x75, + 0x47, 0x29, 0x00, 0x00, 0x01, 0x7F, 0x9F, 0xCC, 0x2A, 0x01, 0x07, 0x13, 0x01, 0x00, 0x3A, 0x0F, 0x06, 0x09, 0x29, 0x01, 0x10, 0x13, 0x06, 0x01, - 0xC2, 0x04, 0x2A, 0x01, 0x01, 0x3A, 0x0F, 0x06, 0x21, 0x29, 0x29, 0x88, + 0xC3, 0x04, 0x2A, 0x01, 0x01, 0x3A, 0x0F, 0x06, 0x21, 0x29, 0x29, 0x88, 0x30, 0x01, 0x01, 0x0F, 0x01, 0x01, 0xA2, 0x39, 0x06, 0x0F, 0x2C, 0x19, - 0x38, 0x06, 0x04, 0xCB, 0x29, 0x04, 0x78, 0x01, 0x80, 0x64, 0xC4, 0x04, + 0x38, 0x06, 0x04, 0xCC, 0x29, 0x04, 0x78, 0x01, 0x80, 0x64, 0xC5, 0x04, 0x03, 0x01, 0x00, 0x9F, 0x04, 0x03, 0x71, 0x2B, 0x29, 0x04, 0x40, 0x01, 0x2A, 0x03, 0x00, 0x09, 0x2A, 0x5B, 0x06, 0x02, 0x68, 0x2B, 0x02, 0x00, 0x00, 0x00, 0x9A, 0x01, 0x0F, 0x13, 0x00, 0x00, 0x74, 0x30, 0x01, 0x00, @@ -574,57 +569,57 @@ static const uint8_t t0_codeblock[] = { 0x06, 0x14, 0x29, 0x01, 0x00, 0x74, 0x42, 0x2A, 0x01, 0x80, 0x64, 0x0F, 0x06, 0x05, 0x01, 0x82, 0x00, 0x08, 0x2B, 0x5D, 0x04, 0x07, 0x29, 0x01, 0x82, 0x00, 0x08, 0x2B, 0x29, 0x00, 0x00, 0x01, 0x00, 0x31, 0x06, 0x05, - 0x3D, 0xA6, 0x39, 0x04, 0x78, 0x2A, 0x06, 0x04, 0x01, 0x01, 0x8F, 0x42, + 0x3D, 0xA7, 0x39, 0x04, 0x78, 0x2A, 0x06, 0x04, 0x01, 0x01, 0x8F, 0x42, 0x00, 0x00, 0x01, 0x1F, 0x13, 0x01, 0x12, 0x0F, 0x05, 0x02, 0x72, 0x2B, - 0x76, 0x2E, 0x2A, 0xC7, 0x05, 0x02, 0x71, 0x2B, 0xA5, 0x28, 0x00, 0x02, - 0x85, 0x2E, 0x05, 0x02, 0xB9, 0x00, 0xBD, 0xA4, 0xBD, 0xA4, 0x01, 0x7E, - 0x03, 0x00, 0x2A, 0x06, 0x17, 0xBF, 0x2A, 0x03, 0x01, 0x83, 0x47, 0xB3, + 0x76, 0x2E, 0x2A, 0xC8, 0x05, 0x02, 0x71, 0x2B, 0xA6, 0x28, 0x00, 0x02, + 0x85, 0x2E, 0x05, 0x02, 0xBA, 0x00, 0xBE, 0xA5, 0xBE, 0xA5, 0x01, 0x7E, + 0x03, 0x00, 0x2A, 0x06, 0x17, 0xC0, 0x2A, 0x03, 0x01, 0x83, 0x47, 0xB4, 0x02, 0x01, 0x4F, 0x2A, 0x02, 0x00, 0x51, 0x06, 0x04, 0x03, 0x00, 0x04, 0x01, 0x29, 0x04, 0x66, 0x9B, 0x9B, 0x02, 0x00, 0x5F, 0x8A, 0x40, 0x00, 0x00, 0x31, 0x06, 0x0B, 0x86, 0x30, 0x01, 0x14, 0x0E, 0x06, 0x02, 0x71, - 0x2B, 0x04, 0x11, 0xCB, 0x01, 0x07, 0x13, 0x2A, 0x01, 0x02, 0x0E, 0x06, - 0x06, 0x06, 0x02, 0x71, 0x2B, 0x04, 0x70, 0x29, 0xC0, 0x01, 0x01, 0x0E, - 0x35, 0x39, 0x06, 0x02, 0x64, 0x2B, 0x2A, 0x01, 0x01, 0xC6, 0x38, 0xB2, - 0x00, 0x01, 0xB7, 0x01, 0x0B, 0x0F, 0x05, 0x02, 0x71, 0x2B, 0x2A, 0x01, - 0x03, 0x0F, 0x06, 0x08, 0xBE, 0x06, 0x02, 0x68, 0x2B, 0x47, 0x29, 0x00, - 0x47, 0x5A, 0xBE, 0xA4, 0x2A, 0x06, 0x23, 0xBE, 0xA4, 0x2A, 0x59, 0x2A, + 0x2B, 0x04, 0x11, 0xCC, 0x01, 0x07, 0x13, 0x2A, 0x01, 0x02, 0x0E, 0x06, + 0x06, 0x06, 0x02, 0x71, 0x2B, 0x04, 0x70, 0x29, 0xC1, 0x01, 0x01, 0x0E, + 0x35, 0x39, 0x06, 0x02, 0x64, 0x2B, 0x2A, 0x01, 0x01, 0xC7, 0x38, 0xB3, + 0x00, 0x01, 0xB8, 0x01, 0x0B, 0x0F, 0x05, 0x02, 0x71, 0x2B, 0x2A, 0x01, + 0x03, 0x0F, 0x06, 0x08, 0xBF, 0x06, 0x02, 0x68, 0x2B, 0x47, 0x29, 0x00, + 0x47, 0x5A, 0xBF, 0xA5, 0x2A, 0x06, 0x23, 0xBF, 0xA5, 0x2A, 0x59, 0x2A, 0x06, 0x18, 0x2A, 0x01, 0x82, 0x00, 0x10, 0x06, 0x05, 0x01, 0x82, 0x00, - 0x04, 0x01, 0x2A, 0x03, 0x00, 0x83, 0x02, 0x00, 0xB3, 0x02, 0x00, 0x56, + 0x04, 0x01, 0x2A, 0x03, 0x00, 0x83, 0x02, 0x00, 0xB4, 0x02, 0x00, 0x56, 0x04, 0x65, 0x9B, 0x57, 0x04, 0x5A, 0x9B, 0x9B, 0x58, 0x2A, 0x06, 0x02, 0x37, 0x00, 0x29, 0x2D, 0x00, 0x02, 0x2A, 0x01, 0x20, 0x13, 0x05, 0x02, - 0x72, 0x2B, 0x01, 0x0F, 0x13, 0x03, 0x00, 0xAD, 0x93, 0x2E, 0x01, 0x86, - 0x03, 0x11, 0x06, 0x23, 0xBD, 0x2A, 0x01, 0x81, 0x7F, 0x13, 0x5F, 0x01, + 0x72, 0x2B, 0x01, 0x0F, 0x13, 0x03, 0x00, 0xAE, 0x93, 0x2E, 0x01, 0x86, + 0x03, 0x11, 0x06, 0x23, 0xBE, 0x2A, 0x01, 0x81, 0x7F, 0x13, 0x5F, 0x01, 0x01, 0x12, 0x02, 0x00, 0x0F, 0x05, 0x02, 0x6A, 0x2B, 0x01, 0x08, 0x12, 0x2A, 0x01, 0x02, 0x0B, 0x3A, 0x01, 0x06, 0x10, 0x39, 0x06, 0x02, 0x6C, 0x2B, 0x04, 0x0D, 0x02, 0x00, 0x01, 0x01, 0x0F, 0x06, 0x04, 0x01, 0x00, - 0x04, 0x02, 0x01, 0x02, 0x20, 0x05, 0x02, 0x6C, 0x2B, 0xBD, 0x2A, 0x03, + 0x04, 0x02, 0x01, 0x02, 0x20, 0x05, 0x02, 0x6C, 0x2B, 0xBE, 0x2A, 0x03, 0x01, 0x2A, 0x01, 0x84, 0x00, 0x10, 0x06, 0x02, 0x6D, 0x2B, 0x83, 0x47, - 0xB3, 0x02, 0x01, 0x53, 0x2A, 0x06, 0x01, 0x2B, 0x29, 0x9B, 0x00, 0x00, - 0x1D, 0xB7, 0x01, 0x0F, 0x0F, 0x05, 0x02, 0x71, 0x2B, 0x00, 0x0A, 0xB7, - 0x01, 0x01, 0x0F, 0x05, 0x02, 0x71, 0x2B, 0xBD, 0x2A, 0x03, 0x00, 0x77, - 0x40, 0x78, 0x01, 0x20, 0xB3, 0xBF, 0x2A, 0x01, 0x20, 0x10, 0x06, 0x02, - 0x70, 0x2B, 0x2A, 0x8E, 0x42, 0x8D, 0x47, 0xB3, 0x1A, 0x03, 0x01, 0xBD, - 0xA4, 0x01, 0x00, 0x03, 0x02, 0x01, 0x00, 0x03, 0x03, 0x81, 0xA0, 0x17, - 0x3A, 0x08, 0x03, 0x04, 0x03, 0x05, 0x2A, 0x06, 0x80, 0x6D, 0xBD, 0x2A, + 0xB4, 0x02, 0x01, 0x53, 0x2A, 0x06, 0x01, 0x2B, 0x29, 0x9B, 0x00, 0x00, + 0x1D, 0xB8, 0x01, 0x0F, 0x0F, 0x05, 0x02, 0x71, 0x2B, 0x00, 0x0A, 0xB8, + 0x01, 0x01, 0x0F, 0x05, 0x02, 0x71, 0x2B, 0xBE, 0x2A, 0x03, 0x00, 0x77, + 0x40, 0x78, 0x01, 0x20, 0xB4, 0xC0, 0x2A, 0x01, 0x20, 0x10, 0x06, 0x02, + 0x70, 0x2B, 0x2A, 0x8E, 0x42, 0x8D, 0x47, 0xB4, 0x1A, 0x03, 0x01, 0xBE, + 0xA5, 0x01, 0x00, 0x03, 0x02, 0x01, 0x00, 0x03, 0x03, 0x81, 0xA0, 0x17, + 0x3A, 0x08, 0x03, 0x04, 0x03, 0x05, 0x2A, 0x06, 0x80, 0x6D, 0xBE, 0x2A, 0x03, 0x06, 0x02, 0x01, 0x06, 0x0A, 0x2A, 0x76, 0x2E, 0x0F, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x03, 0x2A, 0x01, 0x81, 0x7F, 0x0F, 0x06, 0x0A, 0x88, 0x30, 0x06, 0x02, 0x69, 0x2B, 0x01, 0x7F, 0x03, 0x02, 0x2A, 0x01, 0x81, 0xAC, 0x00, 0x0F, 0x06, 0x11, 0x02, 0x00, 0x96, 0x2E, 0x11, 0x02, 0x00, - 0x95, 0x2E, 0x0B, 0x13, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x00, 0xC1, 0x2A, + 0x95, 0x2E, 0x0B, 0x13, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x00, 0xC2, 0x2A, 0x5B, 0x06, 0x03, 0x29, 0x04, 0x26, 0x01, 0x00, 0xA2, 0x06, 0x0B, 0x01, 0x02, 0x0C, 0x79, 0x08, 0x02, 0x06, 0x47, 0x40, 0x04, 0x16, 0x29, 0x02, 0x05, 0x02, 0x04, 0x11, 0x06, 0x02, 0x67, 0x2B, 0x02, 0x06, 0x02, 0x05, 0x40, 0x02, 0x05, 0x01, 0x04, 0x08, 0x03, 0x05, 0x04, 0xFF, 0x0F, 0x29, - 0x01, 0x00, 0x03, 0x07, 0xBF, 0xA4, 0x2A, 0x06, 0x09, 0xBF, 0x05, 0x04, + 0x01, 0x00, 0x03, 0x07, 0xC0, 0xA5, 0x2A, 0x06, 0x09, 0xC0, 0x05, 0x04, 0x01, 0x7F, 0x03, 0x07, 0x04, 0x74, 0x9B, 0x01, 0x00, 0x8B, 0x42, 0x01, 0x88, 0x04, 0x80, 0x41, 0x01, 0x84, 0x80, 0x80, 0x00, 0x7C, 0x41, 0x2A, - 0x06, 0x80, 0x4E, 0xBD, 0xA4, 0x2A, 0x06, 0x80, 0x47, 0xBD, 0x01, 0x00, - 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xB6, 0x04, 0x39, 0x01, 0x01, 0x3A, 0x0F, - 0x06, 0x04, 0x29, 0xB4, 0x04, 0x2F, 0x01, 0x83, 0xFE, 0x01, 0x3A, 0x0F, - 0x06, 0x04, 0x29, 0xB5, 0x04, 0x23, 0x01, 0x0D, 0x3A, 0x0F, 0x06, 0x04, - 0x29, 0xBB, 0x04, 0x19, 0x01, 0x0A, 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xBC, - 0x04, 0x0F, 0x01, 0x10, 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xA9, 0x04, 0x05, - 0x29, 0xB9, 0x01, 0x00, 0x29, 0x04, 0xFF, 0x35, 0x9B, 0x9B, 0x02, 0x01, + 0x06, 0x80, 0x4E, 0xBE, 0xA5, 0x2A, 0x06, 0x80, 0x47, 0xBE, 0x01, 0x00, + 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xB7, 0x04, 0x39, 0x01, 0x01, 0x3A, 0x0F, + 0x06, 0x04, 0x29, 0xB5, 0x04, 0x2F, 0x01, 0x83, 0xFE, 0x01, 0x3A, 0x0F, + 0x06, 0x04, 0x29, 0xB6, 0x04, 0x23, 0x01, 0x0D, 0x3A, 0x0F, 0x06, 0x04, + 0x29, 0xBC, 0x04, 0x19, 0x01, 0x0A, 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xBD, + 0x04, 0x0F, 0x01, 0x10, 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xAA, 0x04, 0x05, + 0x29, 0xBA, 0x01, 0x00, 0x29, 0x04, 0xFF, 0x35, 0x9B, 0x9B, 0x02, 0x01, 0x02, 0x03, 0x13, 0x03, 0x01, 0x02, 0x00, 0x5B, 0x06, 0x08, 0x77, 0x2E, 0x97, 0x40, 0x01, 0x80, 0x56, 0xA1, 0x95, 0x2E, 0x2A, 0x02, 0x00, 0x10, 0x06, 0x03, 0x29, 0x02, 0x00, 0x2A, 0x01, 0x86, 0x00, 0x0B, 0x06, 0x02, @@ -649,56 +644,56 @@ static const uint8_t t0_codeblock[] = { 0x79, 0x09, 0x01, 0x02, 0x12, 0x2A, 0x05, 0x03, 0x01, 0x28, 0xA1, 0x7A, 0x42, 0x8A, 0x2E, 0x01, 0x83, 0xFF, 0x7F, 0x0F, 0x06, 0x0D, 0x01, 0x03, 0xA2, 0x06, 0x04, 0x01, 0x80, 0x78, 0xA1, 0x01, 0x00, 0x8A, 0x40, 0x18, - 0x05, 0x03, 0x01, 0x28, 0xA1, 0x01, 0x00, 0x00, 0x00, 0xB1, 0xB0, 0x00, - 0x04, 0x76, 0x2E, 0xCA, 0x06, 0x16, 0xBD, 0x2A, 0x01, 0x84, 0x00, 0x10, - 0x06, 0x02, 0x6D, 0x2B, 0x2A, 0x03, 0x00, 0x83, 0x47, 0xB3, 0x02, 0x00, - 0x76, 0x2E, 0xA5, 0x27, 0x76, 0x2E, 0x2A, 0xC8, 0x47, 0xC7, 0x03, 0x01, - 0x03, 0x02, 0x02, 0x01, 0x02, 0x02, 0x39, 0x06, 0x14, 0xBF, 0x2A, 0x03, - 0x03, 0x83, 0x47, 0xB3, 0x02, 0x03, 0x76, 0x2E, 0xA5, 0x02, 0x02, 0x06, - 0x03, 0x26, 0x04, 0x01, 0x24, 0x9B, 0x00, 0x00, 0xB7, 0x01, 0x10, 0x0F, - 0x05, 0x02, 0x71, 0x2B, 0x00, 0x00, 0x9C, 0xB7, 0x01, 0x14, 0x0E, 0x06, - 0x02, 0x71, 0x2B, 0x83, 0x01, 0x0C, 0x08, 0x01, 0x0C, 0xB3, 0x9B, 0x83, + 0x05, 0x03, 0x01, 0x28, 0xA1, 0x01, 0x00, 0x00, 0x00, 0xB2, 0xB1, 0x00, + 0x04, 0x76, 0x2E, 0xCB, 0x06, 0x16, 0xBE, 0x2A, 0x01, 0x84, 0x00, 0x10, + 0x06, 0x02, 0x6D, 0x2B, 0x2A, 0x03, 0x00, 0x83, 0x47, 0xB4, 0x02, 0x00, + 0x76, 0x2E, 0xA6, 0x27, 0x76, 0x2E, 0x2A, 0xC9, 0x47, 0xC8, 0x03, 0x01, + 0x03, 0x02, 0x02, 0x01, 0x02, 0x02, 0x39, 0x06, 0x14, 0xC0, 0x2A, 0x03, + 0x03, 0x83, 0x47, 0xB4, 0x02, 0x03, 0x76, 0x2E, 0xA6, 0x02, 0x02, 0x06, + 0x03, 0x26, 0x04, 0x01, 0x24, 0x9B, 0x00, 0x00, 0xB8, 0x01, 0x10, 0x0F, + 0x05, 0x02, 0x71, 0x2B, 0x00, 0x00, 0x9C, 0xB8, 0x01, 0x14, 0x0E, 0x06, + 0x02, 0x71, 0x2B, 0x83, 0x01, 0x0C, 0x08, 0x01, 0x0C, 0xB4, 0x9B, 0x83, 0x2A, 0x01, 0x0C, 0x08, 0x01, 0x0C, 0x32, 0x05, 0x02, 0x65, 0x2B, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x98, 0x02, 0x01, 0x02, 0x00, - 0x3C, 0x2A, 0x01, 0x00, 0x0F, 0x06, 0x02, 0x63, 0x00, 0xCD, 0x04, 0x74, - 0x00, 0xBD, 0x01, 0x01, 0x0E, 0x06, 0x02, 0x66, 0x2B, 0xBF, 0x2A, 0x2A, + 0x3C, 0x2A, 0x01, 0x00, 0x0F, 0x06, 0x02, 0x63, 0x00, 0xCE, 0x04, 0x74, + 0x00, 0xBE, 0x01, 0x01, 0x0E, 0x06, 0x02, 0x66, 0x2B, 0xC0, 0x2A, 0x2A, 0x5D, 0x47, 0x01, 0x05, 0x11, 0x39, 0x06, 0x02, 0x66, 0x2B, 0x01, 0x08, 0x08, 0x2A, 0x82, 0x30, 0x0B, 0x06, 0x0D, 0x2A, 0x01, 0x01, 0x47, 0x0C, - 0x3F, 0x2A, 0x82, 0x42, 0x84, 0x42, 0x04, 0x01, 0x29, 0x00, 0x00, 0xBD, + 0x3F, 0x2A, 0x82, 0x42, 0x84, 0x42, 0x04, 0x01, 0x29, 0x00, 0x00, 0xBE, 0x88, 0x30, 0x01, 0x00, 0x3A, 0x0F, 0x06, 0x13, 0x29, 0x01, 0x01, 0x0F, - 0x05, 0x02, 0x69, 0x2B, 0xBF, 0x06, 0x02, 0x69, 0x2B, 0x01, 0x02, 0x88, + 0x05, 0x02, 0x69, 0x2B, 0xC0, 0x06, 0x02, 0x69, 0x2B, 0x01, 0x02, 0x88, 0x42, 0x04, 0x28, 0x01, 0x02, 0x3A, 0x0F, 0x06, 0x1F, 0x29, 0x01, 0x0D, - 0x0F, 0x05, 0x02, 0x69, 0x2B, 0xBF, 0x01, 0x0C, 0x0F, 0x05, 0x02, 0x69, - 0x2B, 0x83, 0x01, 0x0C, 0xB3, 0x89, 0x83, 0x01, 0x0C, 0x32, 0x05, 0x02, - 0x69, 0x2B, 0x04, 0x03, 0x69, 0x2B, 0x29, 0x00, 0x00, 0xBD, 0xA4, 0xBD, - 0xA4, 0x2A, 0x06, 0x1D, 0xBF, 0x06, 0x03, 0xB9, 0x04, 0x15, 0xBD, 0x2A, + 0x0F, 0x05, 0x02, 0x69, 0x2B, 0xC0, 0x01, 0x0C, 0x0F, 0x05, 0x02, 0x69, + 0x2B, 0x83, 0x01, 0x0C, 0xB4, 0x89, 0x83, 0x01, 0x0C, 0x32, 0x05, 0x02, + 0x69, 0x2B, 0x04, 0x03, 0x69, 0x2B, 0x29, 0x00, 0x00, 0xBE, 0xA5, 0xBE, + 0xA5, 0x2A, 0x06, 0x1D, 0xC0, 0x06, 0x03, 0xBA, 0x04, 0x15, 0xBE, 0x2A, 0x01, 0x81, 0x7F, 0x0D, 0x06, 0x0C, 0x2A, 0x8B, 0x08, 0x01, 0x00, 0x47, - 0x42, 0x8B, 0x47, 0xB3, 0x04, 0x01, 0xC5, 0x04, 0x60, 0x9B, 0x9B, 0x00, - 0x00, 0xB8, 0x2A, 0x5D, 0x06, 0x07, 0x29, 0x06, 0x02, 0x67, 0x2B, 0x04, - 0x74, 0x00, 0x00, 0xC0, 0x01, 0x03, 0xBE, 0x47, 0x29, 0x47, 0x00, 0x00, - 0xBD, 0xC5, 0x00, 0x03, 0x01, 0x00, 0x03, 0x00, 0xBD, 0xA4, 0x2A, 0x06, - 0x80, 0x50, 0xBF, 0x03, 0x01, 0xBF, 0x03, 0x02, 0x02, 0x01, 0x01, 0x08, + 0x42, 0x8B, 0x47, 0xB4, 0x04, 0x01, 0xC6, 0x04, 0x60, 0x9B, 0x9B, 0x00, + 0x00, 0xB9, 0x2A, 0x5D, 0x06, 0x07, 0x29, 0x06, 0x02, 0x67, 0x2B, 0x04, + 0x74, 0x00, 0x00, 0xC1, 0x01, 0x03, 0xBF, 0x47, 0x29, 0x47, 0x00, 0x00, + 0xBE, 0xC6, 0x00, 0x03, 0x01, 0x00, 0x03, 0x00, 0xBE, 0xA5, 0x2A, 0x06, + 0x80, 0x50, 0xC0, 0x03, 0x01, 0xC0, 0x03, 0x02, 0x02, 0x01, 0x01, 0x08, 0x0F, 0x06, 0x16, 0x02, 0x02, 0x01, 0x0F, 0x0D, 0x06, 0x0D, 0x01, 0x01, 0x02, 0x02, 0x01, 0x10, 0x08, 0x0C, 0x02, 0x00, 0x39, 0x03, 0x00, 0x04, 0x2A, 0x02, 0x01, 0x01, 0x02, 0x11, 0x02, 0x01, 0x01, 0x06, 0x0D, 0x13, 0x02, 0x02, 0x01, 0x01, 0x0F, 0x02, 0x02, 0x01, 0x03, 0x0F, 0x39, 0x13, 0x06, 0x11, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x60, 0x01, 0x02, 0x0C, 0x02, 0x01, 0x08, 0x0C, 0x39, 0x03, 0x00, 0x04, 0xFF, 0x2C, 0x9B, 0x02, - 0x00, 0x00, 0x00, 0xBD, 0xA4, 0xBA, 0x80, 0x41, 0x9B, 0x00, 0x00, 0xBD, - 0xA4, 0xBD, 0xA4, 0x01, 0x00, 0x7C, 0x41, 0x2A, 0x06, 0x15, 0xBD, 0x2A, + 0x00, 0x00, 0x00, 0xBE, 0xA5, 0xBB, 0x80, 0x41, 0x9B, 0x00, 0x00, 0xBE, + 0xA5, 0xBE, 0xA5, 0x01, 0x00, 0x7C, 0x41, 0x2A, 0x06, 0x15, 0xBE, 0x2A, 0x01, 0x20, 0x0B, 0x06, 0x0B, 0x01, 0x01, 0x47, 0x0C, 0x7C, 0x2F, 0x39, 0x7C, 0x41, 0x04, 0x01, 0x29, 0x04, 0x68, 0x9B, 0x9B, 0x00, 0x00, 0x01, - 0x02, 0x98, 0xC0, 0x01, 0x08, 0x0C, 0xC0, 0x08, 0x00, 0x00, 0x01, 0x03, - 0x98, 0xC0, 0x01, 0x08, 0x0C, 0xC0, 0x08, 0x01, 0x08, 0x0C, 0xC0, 0x08, - 0x00, 0x00, 0x01, 0x01, 0x98, 0xC0, 0x00, 0x00, 0x3D, 0x2A, 0x5B, 0x05, - 0x01, 0x00, 0x29, 0xCD, 0x04, 0x76, 0x02, 0x03, 0x00, 0x92, 0x30, 0x03, + 0x02, 0x98, 0xC1, 0x01, 0x08, 0x0C, 0xC1, 0x08, 0x00, 0x00, 0x01, 0x03, + 0x98, 0xC1, 0x01, 0x08, 0x0C, 0xC1, 0x08, 0x01, 0x08, 0x0C, 0xC1, 0x08, + 0x00, 0x00, 0x01, 0x01, 0x98, 0xC1, 0x00, 0x00, 0x3D, 0x2A, 0x5B, 0x05, + 0x01, 0x00, 0x29, 0xCE, 0x04, 0x76, 0x02, 0x03, 0x00, 0x92, 0x30, 0x03, 0x01, 0x01, 0x00, 0x2A, 0x02, 0x01, 0x0B, 0x06, 0x10, 0x2A, 0x01, 0x01, 0x0C, 0x91, 0x08, 0x2E, 0x02, 0x00, 0x0F, 0x06, 0x01, 0x00, 0x5F, 0x04, - 0x6A, 0x29, 0x01, 0x7F, 0x00, 0x00, 0x2C, 0x19, 0x38, 0x06, 0x04, 0xCB, - 0x29, 0x04, 0x78, 0x01, 0x16, 0x87, 0x42, 0x01, 0x00, 0xDE, 0x01, 0x00, - 0xDD, 0x2C, 0x01, 0x17, 0x87, 0x42, 0x00, 0x00, 0x01, 0x15, 0x87, 0x42, - 0x47, 0x55, 0x29, 0x55, 0x29, 0x2C, 0x00, 0x00, 0x01, 0x01, 0x47, 0xC3, - 0x00, 0x00, 0x47, 0x3A, 0x98, 0x47, 0x2A, 0x06, 0x05, 0xC0, 0x29, 0x60, + 0x6A, 0x29, 0x01, 0x7F, 0x00, 0x00, 0x2C, 0x19, 0x38, 0x06, 0x04, 0xCC, + 0x29, 0x04, 0x78, 0x01, 0x16, 0x87, 0x42, 0x01, 0x00, 0xDF, 0x01, 0x00, + 0xDE, 0x2C, 0x01, 0x17, 0x87, 0x42, 0x00, 0x00, 0x01, 0x15, 0x87, 0x42, + 0x47, 0x55, 0x29, 0x55, 0x29, 0x2C, 0x00, 0x00, 0x01, 0x01, 0x47, 0xC4, + 0x00, 0x00, 0x47, 0x3A, 0x98, 0x47, 0x2A, 0x06, 0x05, 0xC1, 0x29, 0x60, 0x04, 0x78, 0x29, 0x00, 0x02, 0x03, 0x00, 0x76, 0x2E, 0x9A, 0x03, 0x01, 0x02, 0x01, 0x01, 0x0F, 0x13, 0x02, 0x01, 0x01, 0x04, 0x12, 0x01, 0x0F, 0x13, 0x02, 0x01, 0x01, 0x08, 0x12, 0x01, 0x0F, 0x13, 0x01, 0x00, 0x3A, @@ -721,66 +716,68 @@ static const uint8_t t0_codeblock[] = { 0x06, 0x03, 0x01, 0x10, 0x39, 0x04, 0x01, 0x29, 0x04, 0x01, 0x29, 0x7B, 0x30, 0x05, 0x33, 0x31, 0x06, 0x30, 0x86, 0x30, 0x01, 0x14, 0x3A, 0x0F, 0x06, 0x06, 0x29, 0x01, 0x02, 0x39, 0x04, 0x22, 0x01, 0x15, 0x3A, 0x0F, - 0x06, 0x09, 0x29, 0xA7, 0x06, 0x03, 0x01, 0x7F, 0x9E, 0x04, 0x13, 0x01, + 0x06, 0x09, 0x29, 0xA8, 0x06, 0x03, 0x01, 0x7F, 0x9E, 0x04, 0x13, 0x01, 0x16, 0x3A, 0x0F, 0x06, 0x06, 0x29, 0x01, 0x01, 0x39, 0x04, 0x07, 0x29, 0x01, 0x04, 0x39, 0x01, 0x00, 0x29, 0x19, 0x06, 0x03, 0x01, 0x08, 0x39, 0x00, 0x00, 0x1B, 0x2A, 0x05, 0x0F, 0x31, 0x06, 0x0C, 0x86, 0x30, 0x01, - 0x15, 0x0F, 0x06, 0x04, 0x29, 0xA7, 0x04, 0x01, 0x23, 0x00, 0x00, 0xCB, + 0x15, 0x0F, 0x06, 0x04, 0x29, 0xA8, 0x04, 0x01, 0x23, 0x00, 0x00, 0xCC, 0x01, 0x07, 0x13, 0x01, 0x01, 0x10, 0x06, 0x02, 0x71, 0x2B, 0x00, 0x01, - 0x03, 0x00, 0x2C, 0x19, 0x06, 0x05, 0x02, 0x00, 0x87, 0x42, 0x00, 0xCB, - 0x29, 0x04, 0x74, 0x00, 0x01, 0x14, 0xCE, 0x01, 0x01, 0xDE, 0x2C, 0x2A, - 0x01, 0x00, 0xC6, 0x01, 0x16, 0xCE, 0xD2, 0x2C, 0x00, 0x00, 0x01, 0x0B, - 0xDE, 0x50, 0x2A, 0x2A, 0x01, 0x03, 0x08, 0xDD, 0xDD, 0x14, 0x2A, 0x5B, - 0x06, 0x02, 0x29, 0x00, 0xDD, 0x1E, 0x2A, 0x06, 0x05, 0x83, 0x47, 0xD6, - 0x04, 0x77, 0x29, 0x04, 0x6C, 0x00, 0x01, 0x00, 0xD8, 0x93, 0x2E, 0x01, - 0x86, 0x03, 0x11, 0x06, 0x05, 0x61, 0x01, 0x00, 0xD9, 0x08, 0x4E, 0x08, - 0x01, 0x03, 0x08, 0x01, 0x0D, 0xDE, 0xDD, 0x01, 0x00, 0xD8, 0xDE, 0x01, - 0x01, 0xD8, 0x29, 0x93, 0x2E, 0x01, 0x86, 0x03, 0x11, 0x06, 0x08, 0x01, - 0x00, 0xD9, 0xDC, 0x01, 0x01, 0xD9, 0x29, 0x4E, 0xDC, 0x16, 0x15, 0x2A, - 0x5B, 0x06, 0x02, 0x29, 0x00, 0xDC, 0x1F, 0x2A, 0x06, 0x05, 0x83, 0x47, - 0xD6, 0x04, 0x77, 0x29, 0x04, 0x6C, 0x00, 0x9C, 0x01, 0x14, 0xDE, 0x01, - 0x0C, 0xDD, 0x83, 0x01, 0x0C, 0xD6, 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, - 0xDE, 0x01, 0x80, 0x46, 0x88, 0x30, 0x01, 0x02, 0x0F, 0x06, 0x0C, 0x02, + 0x03, 0x00, 0x2C, 0x19, 0x06, 0x05, 0x02, 0x00, 0x87, 0x42, 0x00, 0xCC, + 0x29, 0x04, 0x74, 0x00, 0x01, 0x14, 0xCF, 0x01, 0x01, 0xDF, 0x2C, 0x2A, + 0x01, 0x00, 0xC7, 0x01, 0x16, 0xCF, 0xD3, 0x2C, 0x00, 0x00, 0x01, 0x0B, + 0xDF, 0x50, 0x2A, 0x2A, 0x01, 0x03, 0x08, 0xDE, 0xDE, 0x14, 0x2A, 0x5B, + 0x06, 0x02, 0x29, 0x00, 0xDE, 0x1E, 0x2A, 0x06, 0x05, 0x83, 0x47, 0xD7, + 0x04, 0x77, 0x29, 0x04, 0x6C, 0x00, 0x01, 0x00, 0xD9, 0x93, 0x2E, 0x01, + 0x86, 0x03, 0x11, 0x06, 0x05, 0x61, 0x01, 0x00, 0xDA, 0x08, 0x4E, 0x08, + 0x01, 0x03, 0x08, 0x01, 0x0D, 0xDF, 0xDE, 0x01, 0x00, 0xD9, 0xDF, 0x01, + 0x01, 0xD9, 0x29, 0x93, 0x2E, 0x01, 0x86, 0x03, 0x11, 0x06, 0x08, 0x01, + 0x00, 0xDA, 0xDD, 0x01, 0x01, 0xDA, 0x29, 0x4E, 0xDD, 0x16, 0x15, 0x2A, + 0x5B, 0x06, 0x02, 0x29, 0x00, 0xDD, 0x1F, 0x2A, 0x06, 0x05, 0x83, 0x47, + 0xD7, 0x04, 0x77, 0x29, 0x04, 0x6C, 0x00, 0x9C, 0x01, 0x14, 0xDF, 0x01, + 0x0C, 0xDE, 0x83, 0x01, 0x0C, 0xD7, 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, + 0xDF, 0x01, 0x80, 0x46, 0x88, 0x30, 0x01, 0x02, 0x0F, 0x06, 0x0C, 0x02, 0x00, 0x06, 0x04, 0x01, 0x05, 0x04, 0x02, 0x01, 0x1D, 0x04, 0x02, 0x01, 0x00, 0x03, 0x01, 0x84, 0x30, 0x06, 0x04, 0x01, 0x05, 0x04, 0x02, 0x01, 0x00, 0x03, 0x02, 0x8A, 0x2E, 0x2A, 0x06, 0x05, 0x60, 0x21, 0x01, 0x07, 0x08, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x02, 0x03, 0x08, 0x2A, - 0x06, 0x03, 0x01, 0x02, 0x08, 0x08, 0xDD, 0x93, 0x2E, 0xDC, 0x8C, 0x01, + 0x06, 0x03, 0x01, 0x02, 0x08, 0x08, 0xDE, 0x93, 0x2E, 0xDD, 0x8C, 0x01, 0x04, 0x17, 0x8C, 0x01, 0x04, 0x08, 0x01, 0x1C, 0x34, 0x8C, 0x01, 0x20, - 0xD6, 0x01, 0x20, 0xDE, 0x8D, 0x01, 0x20, 0xD6, 0x76, 0x2E, 0xDC, 0x01, - 0x00, 0xDE, 0x02, 0x01, 0x02, 0x02, 0x08, 0x02, 0x03, 0x08, 0x2A, 0x06, - 0x80, 0x40, 0xDC, 0x02, 0x01, 0x2A, 0x06, 0x10, 0x01, 0x83, 0xFE, 0x01, - 0xDC, 0x01, 0x04, 0x09, 0x2A, 0xDC, 0x60, 0x89, 0x47, 0xD7, 0x04, 0x01, - 0x29, 0x02, 0x02, 0x06, 0x0C, 0x01, 0x01, 0xDC, 0x01, 0x01, 0xDC, 0x84, - 0x30, 0x01, 0x08, 0x09, 0xDE, 0x02, 0x03, 0x2A, 0x06, 0x11, 0x01, 0x10, - 0xDC, 0x01, 0x04, 0x09, 0x2A, 0xDC, 0x62, 0x2A, 0xDC, 0x60, 0x83, 0x47, - 0xD7, 0x04, 0x01, 0x29, 0x04, 0x01, 0x29, 0x00, 0x00, 0x01, 0x0E, 0xDE, - 0x01, 0x00, 0xDD, 0x00, 0x03, 0x76, 0x2E, 0xC8, 0x05, 0x01, 0x00, 0x7C, - 0x2F, 0x01, 0x00, 0xA0, 0x12, 0x01, 0x01, 0x13, 0x5D, 0x06, 0x03, 0x5F, - 0x04, 0x75, 0x03, 0x00, 0x29, 0x02, 0x00, 0x25, 0x2A, 0x5B, 0x06, 0x02, - 0x37, 0x2B, 0x03, 0x01, 0x93, 0x2E, 0x01, 0x86, 0x03, 0x11, 0x03, 0x02, - 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x7E, 0x30, 0x08, 0x02, 0x02, 0x01, 0x02, - 0x13, 0x08, 0x01, 0x06, 0x08, 0xDD, 0x01, 0x03, 0xDE, 0x02, 0x00, 0xDC, - 0x7D, 0x7E, 0x30, 0xD7, 0x02, 0x02, 0x06, 0x1C, 0x90, 0x2E, 0x2A, 0x01, - 0x83, 0xFE, 0x00, 0x0B, 0x06, 0x03, 0xDC, 0x04, 0x0F, 0x01, 0x81, 0x7F, - 0x13, 0xDE, 0x76, 0x2E, 0xC9, 0x01, 0x01, 0x0C, 0x01, 0x03, 0x08, 0xDE, - 0x02, 0x01, 0xDC, 0x83, 0x02, 0x01, 0xD6, 0x00, 0x00, 0x54, 0x2A, 0x01, - 0x00, 0x0F, 0x06, 0x02, 0x63, 0x00, 0xCB, 0x29, 0x04, 0x73, 0x00, 0x2A, - 0xDE, 0xD6, 0x00, 0x00, 0x01, 0x00, 0x76, 0x2E, 0xC7, 0x06, 0x0C, 0x61, - 0x3A, 0x06, 0x08, 0x01, 0x80, 0x41, 0xDE, 0x01, 0x80, 0x42, 0xDE, 0x46, - 0x06, 0x07, 0x5F, 0x3A, 0x06, 0x03, 0x01, 0x01, 0xDE, 0x45, 0x06, 0x08, - 0x5F, 0x3A, 0x06, 0x04, 0x01, 0x80, 0x40, 0xDE, 0x47, 0x29, 0x00, 0x01, - 0x01, 0x00, 0x03, 0x00, 0x46, 0x45, 0x39, 0x05, 0x14, 0x01, 0x01, 0x01, - 0x80, 0x7C, 0xDA, 0x03, 0x00, 0x01, 0x03, 0x01, 0x80, 0x7C, 0xDA, 0x02, - 0x00, 0x08, 0x47, 0x29, 0x00, 0x46, 0x06, 0x07, 0x01, 0x01, 0x44, 0x29, - 0xDA, 0x03, 0x00, 0x45, 0x06, 0x0A, 0x01, 0x03, 0x44, 0x29, 0xDA, 0x02, - 0x00, 0x08, 0x03, 0x00, 0x29, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, - 0x04, 0xDB, 0x01, 0x05, 0xDB, 0x01, 0x06, 0xDB, 0x01, 0x03, 0xDB, 0x01, - 0x02, 0xDB, 0x0A, 0x63, 0x00, 0x01, 0x03, 0x00, 0x3A, 0x01, 0x01, 0x02, - 0x00, 0x0C, 0x13, 0x05, 0x01, 0x00, 0x61, 0x01, 0x03, 0x3B, 0x06, 0x07, - 0x02, 0x00, 0xDE, 0x01, 0x02, 0x3B, 0xDE, 0x00, 0x00, 0x2A, 0x01, 0x08, - 0x52, 0xDE, 0xDE, 0x00, 0x00, 0x2A, 0x01, 0x10, 0x52, 0xDE, 0xDC, 0x00, - 0x00, 0x2A, 0x55, 0x06, 0x02, 0x29, 0x00, 0xCB, 0x29, 0x04, 0x76 + 0xD7, 0x01, 0x20, 0xDF, 0x8D, 0x01, 0x20, 0xD7, 0x76, 0x2E, 0xDD, 0x01, + 0x00, 0xDF, 0x02, 0x01, 0x02, 0x02, 0x08, 0x02, 0x03, 0x08, 0x2A, 0x06, + 0x80, 0x40, 0xDD, 0x02, 0x01, 0x2A, 0x06, 0x10, 0x01, 0x83, 0xFE, 0x01, + 0xDD, 0x01, 0x04, 0x09, 0x2A, 0xDD, 0x60, 0x89, 0x47, 0xD8, 0x04, 0x01, + 0x29, 0x02, 0x02, 0x06, 0x0C, 0x01, 0x01, 0xDD, 0x01, 0x01, 0xDD, 0x84, + 0x30, 0x01, 0x08, 0x09, 0xDF, 0x02, 0x03, 0x2A, 0x06, 0x11, 0x01, 0x10, + 0xDD, 0x01, 0x04, 0x09, 0x2A, 0xDD, 0x62, 0x2A, 0xDD, 0x60, 0x83, 0x47, + 0xD8, 0x04, 0x01, 0x29, 0x04, 0x01, 0x29, 0x00, 0x00, 0x01, 0x0E, 0xDF, + 0x01, 0x00, 0xDE, 0x00, 0x03, 0x76, 0x2E, 0xC9, 0x05, 0x01, 0x00, 0x7C, + 0x2F, 0x2A, 0x01, 0x82, 0x80, 0x80, 0x80, 0x00, 0x13, 0x06, 0x05, 0x29, + 0x01, 0x1D, 0x04, 0x0E, 0x2A, 0x01, 0x83, 0xC0, 0x80, 0x80, 0x00, 0x13, + 0x2A, 0x06, 0x01, 0x47, 0x29, 0xA3, 0x03, 0x00, 0x02, 0x00, 0x25, 0x2A, + 0x5B, 0x06, 0x02, 0x37, 0x2B, 0x03, 0x01, 0x93, 0x2E, 0x01, 0x86, 0x03, + 0x11, 0x03, 0x02, 0x01, 0x0C, 0xDF, 0x02, 0x01, 0x7E, 0x30, 0x08, 0x02, + 0x02, 0x01, 0x02, 0x13, 0x08, 0x01, 0x06, 0x08, 0xDE, 0x01, 0x03, 0xDF, + 0x02, 0x00, 0xDD, 0x7D, 0x7E, 0x30, 0xD8, 0x02, 0x02, 0x06, 0x1C, 0x90, + 0x2E, 0x2A, 0x01, 0x83, 0xFE, 0x00, 0x0B, 0x06, 0x03, 0xDD, 0x04, 0x0F, + 0x01, 0x81, 0x7F, 0x13, 0xDF, 0x76, 0x2E, 0xCA, 0x01, 0x01, 0x0C, 0x01, + 0x03, 0x08, 0xDF, 0x02, 0x01, 0xDD, 0x83, 0x02, 0x01, 0xD7, 0x00, 0x00, + 0x54, 0x2A, 0x01, 0x00, 0x0F, 0x06, 0x02, 0x63, 0x00, 0xCC, 0x29, 0x04, + 0x73, 0x00, 0x2A, 0xDF, 0xD7, 0x00, 0x00, 0x01, 0x00, 0x76, 0x2E, 0xC8, + 0x06, 0x0C, 0x61, 0x3A, 0x06, 0x08, 0x01, 0x80, 0x41, 0xDF, 0x01, 0x80, + 0x42, 0xDF, 0x46, 0x06, 0x07, 0x5F, 0x3A, 0x06, 0x03, 0x01, 0x01, 0xDF, + 0x45, 0x06, 0x08, 0x5F, 0x3A, 0x06, 0x04, 0x01, 0x80, 0x40, 0xDF, 0x47, + 0x29, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x46, 0x45, 0x39, 0x05, 0x14, + 0x01, 0x01, 0x01, 0x80, 0x7C, 0xDB, 0x03, 0x00, 0x01, 0x03, 0x01, 0x80, + 0x7C, 0xDB, 0x02, 0x00, 0x08, 0x47, 0x29, 0x00, 0x46, 0x06, 0x07, 0x01, + 0x01, 0x44, 0x29, 0xDB, 0x03, 0x00, 0x45, 0x06, 0x0A, 0x01, 0x03, 0x44, + 0x29, 0xDB, 0x02, 0x00, 0x08, 0x03, 0x00, 0x29, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x04, 0xDC, 0x01, 0x05, 0xDC, 0x01, 0x06, 0xDC, 0x01, + 0x03, 0xDC, 0x01, 0x02, 0xDC, 0x0A, 0x63, 0x00, 0x01, 0x03, 0x00, 0x3A, + 0x01, 0x01, 0x02, 0x00, 0x0C, 0x13, 0x05, 0x01, 0x00, 0x61, 0x01, 0x03, + 0x3B, 0x06, 0x07, 0x02, 0x00, 0xDF, 0x01, 0x02, 0x3B, 0xDF, 0x00, 0x00, + 0x2A, 0x01, 0x08, 0x52, 0xDF, 0xDF, 0x00, 0x00, 0x2A, 0x01, 0x10, 0x52, + 0xDF, 0xDD, 0x00, 0x00, 0x2A, 0x55, 0x06, 0x02, 0x29, 0x00, 0xCC, 0x29, + 0x04, 0x76 }; static const uint16_t t0_caddr[] = { @@ -857,65 +854,66 @@ static const uint16_t t0_caddr[] = { 513, 546, 556, - 624, - 638, - 644, - 703, - 722, - 744, - 793, - 842, - 918, - 1020, - 1031, - 1617, - 1621, - 1688, - 1698, - 1729, + 580, + 648, + 662, + 668, + 727, + 746, + 768, + 817, + 866, + 942, + 1044, + 1055, + 1641, + 1645, + 1712, + 1722, 1753, - 1799, - 1869, - 1909, - 1923, - 1932, - 1936, - 2031, - 2039, - 2075, - 2086, - 2102, - 2108, - 2119, - 2154, - 2180, - 2192, - 2198, - 2213, - 2369, - 2378, - 2391, - 2400, - 2407, - 2510, - 2531, - 2544, - 2560, - 2578, - 2610, - 2683, - 2696, - 2877, - 2885, - 2997, - 3011, - 3016, - 3060, - 3117, - 3138, - 3165, - 3173, - 3181 + 1777, + 1823, + 1893, + 1933, + 1947, + 1956, + 1960, + 2055, + 2063, + 2099, + 2110, + 2126, + 2132, + 2143, + 2178, + 2204, + 2216, + 2222, + 2237, + 2393, + 2402, + 2415, + 2424, + 2431, + 2534, + 2555, + 2568, + 2584, + 2602, + 2634, + 2707, + 2720, + 2901, + 2909, + 3036, + 3050, + 3055, + 3099, + 3156, + 3177, + 3204, + 3212, + 3220 }; #define T0_INTERPRETED 91 @@ -939,7 +937,7 @@ name(void *ctx) \ T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ } -T0_DEFENTRY(br_ssl_hs_server_init_main, 163) +T0_DEFENTRY(br_ssl_hs_server_init_main, 164) #define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) diff --git a/src/ssl/ssl_hs_server.t0 b/src/ssl/ssl_hs_server.t0 index a7475af..cb0579c 100644 --- a/src/ssl/ssl_hs_server.t0 +++ b/src/ssl/ssl_hs_server.t0 @@ -49,7 +49,7 @@ do_rsa_decrypt(br_ssl_server_context *ctx, int prf_id, /* * Decrypt the PMS. */ - x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, epms, len); + x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, epms, &len); /* * Set the first two bytes to the maximum supported client @@ -85,21 +85,12 @@ do_rsa_decrypt(br_ssl_server_context *ctx, int prf_id, */ static void ecdh_common(br_ssl_server_context *ctx, int prf_id, - unsigned char *cpoint, size_t cpoint_len, uint32_t ctl) + unsigned char *xcoor, size_t xcoor_len, uint32_t ctl) { unsigned char rpms[80]; - size_t pms_len; - /* - * The point length is supposed to be 1+2*Xlen, where Xlen is - * the length (in bytes) of the X coordinate, i.e. the pre-master - * secret. If the provided point is too large, then it is - * obviously incorrect (i.e. everybody can see that it is - * incorrect), so leaking that fact is not a problem. - */ - pms_len = cpoint_len >> 1; - if (pms_len > sizeof rpms) { - pms_len = sizeof rpms; + if (xcoor_len > sizeof rpms) { + xcoor_len = sizeof rpms; ctl = 0; } @@ -108,19 +99,19 @@ ecdh_common(br_ssl_server_context *ctx, int prf_id, * decryption failed. Note that we use a constant-time conditional * copy. */ - br_hmac_drbg_generate(&ctx->eng.rng, rpms, pms_len); - br_ccopy(ctl ^ 1, cpoint + 1, rpms, pms_len); + br_hmac_drbg_generate(&ctx->eng.rng, rpms, xcoor_len); + br_ccopy(ctl ^ 1, xcoor, rpms, xcoor_len); /* * Compute master secret. */ - br_ssl_engine_compute_master(&ctx->eng, prf_id, cpoint + 1, pms_len); + br_ssl_engine_compute_master(&ctx->eng, prf_id, xcoor, xcoor_len); /* * Clear the pre-master secret from RAM: it is normally a buffer * in the context, hence potentially long-lived. */ - memset(cpoint, 0, cpoint_len); + memset(xcoor, 0, xcoor_len); } /* @@ -136,7 +127,7 @@ do_ecdh(br_ssl_server_context *ctx, int prf_id, * Finalise the key exchange. */ x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, - cpoint, cpoint_len); + cpoint, &cpoint_len); ecdh_common(ctx, prf_id, cpoint, cpoint_len, x); } @@ -288,16 +279,18 @@ do_ecdhe_part2(br_ssl_server_context *ctx, int prf_id, unsigned char *cpoint, size_t cpoint_len) { int curve; - uint32_t x; + uint32_t ctl; + size_t xoff, xlen; curve = ctx->eng.ecdhe_curve; /* * Finalise the key exchange. */ - x = ctx->eng.iec->mul(cpoint, cpoint_len, + ctl = ctx->eng.iec->mul(cpoint, cpoint_len, ctx->ecdhe_key, ctx->ecdhe_key_len, curve); - ecdh_common(ctx, prf_id, cpoint, cpoint_len, x); + xoff = ctx->eng.iec->xoff(curve, &xlen); + ecdh_common(ctx, prf_id, cpoint + xoff, xlen, ctl); /* * Clear the ECDHE private key. Forward Secrecy is achieved insofar @@ -988,21 +981,33 @@ cc: do-ecdhe-part1 ( curve -- len ) { T0_PUSHi(do_ecdhe_part1(CTX, curve)); } +\ Get index of first bit set to 1 (in low to high order). +: lowest-1 ( bits -- n ) + dup ifnot drop -1 ret then + 0 begin dup2 >> 1 and 0= while 1+ repeat + swap drop ; + \ Write the Server Key Exchange message (if applicable). : write-ServerKeyExchange ( -- ) addr-cipher_suite get16 use-ecdhe? ifnot ret then \ We must select an appropriate curve among the curves that - \ are supported both by us and the peer. Right now we use - \ the one with the smallest ID, which in practice means P-256. + \ are supported both by us and the peer. Right now, we apply + \ a fixed preference order: Curve25519, P-256, P-384, P-521, + \ then the common curve with the lowest ID. \ (TODO: add some option to make that behaviour configurable.) \ \ This loop always terminates because previous processing made \ sure that ECDHE suites are not selectable if there is no common \ curve. - addr-curves get32 0 - begin dup2 >> 1 and 0= while 1+ repeat - { curve-id } drop + addr-curves get32 + dup 0x20000000 and if + drop 29 + else + dup 0x38000000 and dup if swap then + drop lowest-1 + then + { curve-id } \ Compute the signed curve point to send. curve-id do-ecdhe-part1 dup 0< if neg fail then { sig-len } diff --git a/src/ssl/ssl_scert_single_ec.c b/src/ssl/ssl_scert_single_ec.c index 7b0c328..ce8d753 100644 --- a/src/ssl/ssl_scert_single_ec.c +++ b/src/ssl/ssl_scert_single_ec.c @@ -79,12 +79,18 @@ se_choose(const br_ssl_server_policy_class **pctx, static uint32_t se_do_keyx(const br_ssl_server_policy_class **pctx, - unsigned char *data, size_t len) + unsigned char *data, size_t *len) { br_ssl_server_policy_ec_context *pc; + uint32_t r; + size_t xoff, xlen; pc = (br_ssl_server_policy_ec_context *)pctx; - return pc->iec->mul(data, len, pc->sk->x, pc->sk->xlen, pc->sk->curve); + r = pc->iec->mul(data, *len, pc->sk->x, pc->sk->xlen, pc->sk->curve); + xoff = pc->iec->xoff(pc->sk->curve, &xlen); + memmove(data, data + xoff, xlen); + *len = xlen; + return r; } static size_t diff --git a/src/ssl/ssl_scert_single_rsa.c b/src/ssl/ssl_scert_single_rsa.c index b5f0e69..879a84c 100644 --- a/src/ssl/ssl_scert_single_rsa.c +++ b/src/ssl/ssl_scert_single_rsa.c @@ -69,12 +69,12 @@ sr_choose(const br_ssl_server_policy_class **pctx, static uint32_t sr_do_keyx(const br_ssl_server_policy_class **pctx, - unsigned char *data, size_t len) + unsigned char *data, size_t *len) { br_ssl_server_policy_rsa_context *pc; pc = (br_ssl_server_policy_rsa_context *)pctx; - return br_rsa_ssl_decrypt(pc->irsacore, pc->sk, data, len); + return br_rsa_ssl_decrypt(pc->irsacore, pc->sk, data, *len); } /* diff --git a/src/ssl/ssl_server_full_ec.c b/src/ssl/ssl_server_full_ec.c index 824ee13..dbe215d 100644 --- a/src/ssl/ssl_server_full_ec.c +++ b/src/ssl/ssl_server_full_ec.c @@ -99,7 +99,7 @@ br_ssl_server_init_full_ec(br_ssl_server_context *cc, */ br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); - br_ssl_engine_set_ec(&cc->eng, &br_ec_prime_i31); + br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); /* * Set the "server policy": handler for the certificate chain @@ -108,7 +108,7 @@ br_ssl_server_init_full_ec(br_ssl_server_context *cc, br_ssl_server_set_single_ec(cc, chain, chain_len, sk, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, cert_issuer_key_type, - &br_ec_prime_i31, br_ecdsa_i31_sign_asn1); + &br_ec_all_m15, br_ecdsa_i31_sign_asn1); /* * Set supported hash functions. diff --git a/src/ssl/ssl_server_full_rsa.c b/src/ssl/ssl_server_full_rsa.c index 6b0f59a..ffec9be 100644 --- a/src/ssl/ssl_server_full_rsa.c +++ b/src/ssl/ssl_server_full_rsa.c @@ -89,7 +89,7 @@ br_ssl_server_init_full_rsa(br_ssl_server_context *cc, */ br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); - br_ssl_engine_set_ec(&cc->eng, &br_ec_prime_i31); + br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); /* * Set the "server policy": handler for the certificate chain diff --git a/src/ssl/ssl_server_mine2c.c b/src/ssl/ssl_server_mine2c.c index 396d921..7c53e29 100644 --- a/src/ssl/ssl_server_mine2c.c +++ b/src/ssl/ssl_server_mine2c.c @@ -45,7 +45,7 @@ br_ssl_server_init_mine2c(br_ssl_server_context *cc, */ br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); - br_ssl_engine_set_ec(&cc->eng, &br_ec_prime_i31); + br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); /* * Set the "server policy": handler for the certificate chain diff --git a/src/ssl/ssl_server_mine2g.c b/src/ssl/ssl_server_mine2g.c index 5de566e..f5a1e7d 100644 --- a/src/ssl/ssl_server_mine2g.c +++ b/src/ssl/ssl_server_mine2g.c @@ -45,7 +45,7 @@ br_ssl_server_init_mine2g(br_ssl_server_context *cc, */ br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); - br_ssl_engine_set_ec(&cc->eng, &br_ec_prime_i31); + br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); /* * Set the "server policy": handler for the certificate chain diff --git a/src/ssl/ssl_server_minf2c.c b/src/ssl/ssl_server_minf2c.c index 3a23084..7ded293 100644 --- a/src/ssl/ssl_server_minf2c.c +++ b/src/ssl/ssl_server_minf2c.c @@ -45,14 +45,14 @@ br_ssl_server_init_minf2c(br_ssl_server_context *cc, */ br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); - br_ssl_engine_set_ec(&cc->eng, &br_ec_prime_i31); + br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); /* * Set the "server policy": handler for the certificate chain * and private key operations. */ br_ssl_server_set_single_ec(cc, chain, chain_len, sk, - BR_KEYTYPE_SIGN, 0, &br_ec_prime_i31, br_ecdsa_i31_sign_asn1); + BR_KEYTYPE_SIGN, 0, &br_ec_all_m15, br_ecdsa_i31_sign_asn1); /* * Set supported hash functions. diff --git a/src/ssl/ssl_server_minf2g.c b/src/ssl/ssl_server_minf2g.c index 257aff2..94f9dfb 100644 --- a/src/ssl/ssl_server_minf2g.c +++ b/src/ssl/ssl_server_minf2g.c @@ -45,14 +45,14 @@ br_ssl_server_init_minf2g(br_ssl_server_context *cc, */ br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); - br_ssl_engine_set_ec(&cc->eng, &br_ec_prime_i31); + br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); /* * Set the "server policy": handler for the certificate chain * and private key operations. */ br_ssl_server_set_single_ec(cc, chain, chain_len, sk, - BR_KEYTYPE_SIGN, 0, &br_ec_prime_i31, br_ecdsa_i31_sign_asn1); + BR_KEYTYPE_SIGN, 0, &br_ec_all_m15, br_ecdsa_i31_sign_asn1); /* * Set supported hash functions. diff --git a/src/ssl/ssl_server_minu2g.c b/src/ssl/ssl_server_minu2g.c index e4b31ed..cbf1fe4 100644 --- a/src/ssl/ssl_server_minu2g.c +++ b/src/ssl/ssl_server_minu2g.c @@ -51,7 +51,7 @@ br_ssl_server_init_minu2g(br_ssl_server_context *cc, * and private key operations. */ br_ssl_server_set_single_ec(cc, chain, chain_len, sk, - BR_KEYTYPE_KEYX, BR_KEYTYPE_RSA, &br_ec_prime_i31, 0); + BR_KEYTYPE_KEYX, BR_KEYTYPE_RSA, &br_ec_all_m15, 0); /* * Set supported hash functions. diff --git a/src/ssl/ssl_server_minv2g.c b/src/ssl/ssl_server_minv2g.c index cd29b8e..714a399 100644 --- a/src/ssl/ssl_server_minv2g.c +++ b/src/ssl/ssl_server_minv2g.c @@ -51,7 +51,7 @@ br_ssl_server_init_minv2g(br_ssl_server_context *cc, * and private key operations. */ br_ssl_server_set_single_ec(cc, chain, chain_len, sk, - BR_KEYTYPE_KEYX, BR_KEYTYPE_EC, &br_ec_prime_i31, 0); + BR_KEYTYPE_KEYX, BR_KEYTYPE_EC, &br_ec_all_m15, 0); /* * Set supported hash functions. diff --git a/tools/brssl.h b/tools/brssl.h index cf1cea3..d889b08 100644 --- a/tools/brssl.h +++ b/tools/brssl.h @@ -211,6 +211,23 @@ extern const hash_function hash_functions[]; */ unsigned parse_hash_functions(const char *arg); +/* + * Get a curve name (by ID). If the curve ID is not known, this returns + * NULL. + */ +const char *get_curve_name(int id); + +/* + * Get a curve name (by ID). The name is written in the provided buffer + * (zero-terminated). If the curve ID is not known, the name is + * "unknown (***)" where "***" is the decimal value of the identifier. + * If the name does not fit in the provided buffer, then dst[0] is set + * to 0 (unless len is 0, in which case nothing is written), and -1 is + * returned. Otherwise, the name is written in dst[] (with a terminating + * 0), and this function returns 0. + */ +int get_curve_name_ext(int id, char *dst, size_t len); + /* * Type for a known cipher suite. */ @@ -270,6 +287,11 @@ const char *get_suite_name(unsigned suite); */ int get_suite_name_ext(unsigned suite, char *dst, size_t len); +/* + * Tell whether a cipher suite uses ECDHE key exchange. + */ +int uses_ecdhe(unsigned suite); + /* * Print out all known names (for protocol versions, cipher suites...). */ diff --git a/tools/client.c b/tools/client.c index 200cb16..ce3c6d6 100644 --- a/tools/client.c +++ b/tools/client.c @@ -319,13 +319,19 @@ cc_choose(const br_ssl_client_certificate_class **pctx, static uint32_t cc_do_keyx(const br_ssl_client_certificate_class **pctx, - unsigned char *data, size_t len) + unsigned char *data, size_t *len) { ccert_context *zc; + size_t xoff, xlen; + uint32_t r; zc = (ccert_context *)pctx; - return br_ec_prime_i31.mul(data, len, zc->sk->key.ec.x, + r = br_ec_all_m15.mul(data, *len, zc->sk->key.ec.x, zc->sk->key.ec.xlen, zc->sk->key.ec.curve); + xoff = br_ec_all_m15.xoff(zc->sk->key.ec.curve, &xlen); + memmove(data, data + xoff, xlen); + *len = xlen; + return r; } static size_t @@ -392,7 +398,7 @@ cc_do_sign(const br_ssl_client_certificate_class **pctx, } return 0; } - sig_len = br_ecdsa_i31_sign_asn1(&br_ec_prime_i31, + sig_len = br_ecdsa_i31_sign_asn1(&br_ec_all_m15, hc, hv, &zc->sk->key.ec, data); if (sig_len == 0) { if (zc->verbose) { @@ -957,17 +963,17 @@ do_client(int argc, char *argv[]) br_ssl_client_set_rsapub(&cc, &br_rsa_i31_public); } if ((req & REQ_ECDHE_RSA) != 0) { - br_ssl_engine_set_ec(&cc.eng, &br_ec_prime_i31); + br_ssl_engine_set_ec(&cc.eng, &br_ec_all_m15); br_ssl_engine_set_rsavrfy(&cc.eng, &br_rsa_i31_pkcs1_vrfy); } if ((req & REQ_ECDHE_ECDSA) != 0) { - br_ssl_engine_set_ec(&cc.eng, &br_ec_prime_i31); + br_ssl_engine_set_ec(&cc.eng, &br_ec_all_m15); br_ssl_engine_set_ecdsa(&cc.eng, &br_ecdsa_i31_vrfy_asn1); } if ((req & REQ_ECDH) != 0) { - br_ssl_engine_set_ec(&cc.eng, &br_ec_prime_i31); + br_ssl_engine_set_ec(&cc.eng, &br_ec_all_m15); } } if (fallback) { @@ -1001,7 +1007,7 @@ do_client(int argc, char *argv[]) } br_x509_minimal_set_rsa(&xc, &br_rsa_i31_pkcs1_vrfy); br_x509_minimal_set_ecdsa(&xc, - &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1); + &br_ec_all_m15, &br_ecdsa_i31_vrfy_asn1); /* * If there is no provided trust anchor, then certificate validation diff --git a/tools/names.c b/tools/names.c index e7d2403..438f41a 100644 --- a/tools/names.c +++ b/tools/names.c @@ -271,6 +271,111 @@ const cipher_suite cipher_suites[] = { { NULL, 0, 0, NULL } }; +static struct { + int id; + const char *name; +} curves[] = { + { BR_EC_sect163k1, + "sect163k1" }, + { BR_EC_sect163r1, + "sect163r1" }, + { BR_EC_sect163r2, + "sect163r2" }, + { BR_EC_sect193r1, + "sect193r1" }, + { BR_EC_sect193r2, + "sect193r2" }, + { BR_EC_sect233k1, + "sect233k1" }, + { BR_EC_sect233r1, + "sect233r1" }, + { BR_EC_sect239k1, + "sect239k1" }, + { BR_EC_sect283k1, + "sect283k1" }, + { BR_EC_sect283r1, + "sect283r1" }, + { BR_EC_sect409k1, + "sect409k1" }, + { BR_EC_sect409r1, + "sect409r1" }, + { BR_EC_sect571k1, + "sect571k1" }, + { BR_EC_sect571r1, + "sect571r1" }, + { BR_EC_secp160k1, + "secp160k1" }, + { BR_EC_secp160r1, + "secp160r1" }, + { BR_EC_secp160r2, + "secp160r2" }, + { BR_EC_secp192k1, + "secp192k1" }, + { BR_EC_secp192r1, + "secp192r1" }, + { BR_EC_secp224k1, + "secp224k1" }, + { BR_EC_secp224r1, + "secp224r1" }, + { BR_EC_secp256k1, + "secp256k1" }, + { BR_EC_secp256r1, + "secp256r1 (P-256)" }, + { BR_EC_secp384r1, + "secp384r1 (P-384)" }, + { BR_EC_secp521r1, + "secp521r1 (P-521)" }, + { BR_EC_brainpoolP256r1, + "brainpoolP256r1" }, + { BR_EC_brainpoolP384r1, + "brainpoolP384r1" }, + { BR_EC_brainpoolP512r1, + "brainpoolP512r1" }, + { BR_EC_curve25519, + "Curve25519" }, + { BR_EC_curve448, + "Curve448" }, + { 0, 0 } +}; + +/* see brssl.h */ +const char * +get_curve_name(int id) +{ + size_t u; + + for (u = 0; curves[u].name; u ++) { + if (curves[u].id == id) { + return curves[u].name; + } + } + return NULL; +} + +/* see brssl.h */ +int +get_curve_name_ext(int id, char *dst, size_t len) +{ + const char *name; + char tmp[30]; + size_t n; + + name = get_curve_name(id); + if (name == NULL) { + sprintf(tmp, "unknown (%d)", id); + name = tmp; + } + n = 1 + strlen(name); + if (n > len) { + if (len > 0) { + dst[0] = 0; + } + return -1; + } + memcpy(dst, name, n); + return 0; +} + /* see brssl.h */ const char * get_suite_name(unsigned suite) @@ -309,6 +414,21 @@ get_suite_name_ext(unsigned suite, char *dst, size_t len) return 0; } +/* see brssl.h */ +int +uses_ecdhe(unsigned suite) +{ + size_t u; + + for (u = 0; cipher_suites[u].name; u ++) { + if (cipher_suites[u].suite == suite) { + return (cipher_suites[u].req + & (REQ_ECDHE_RSA | REQ_ECDHE_ECDSA)) != 0; + } + } + return 0; +} + /* see brssl.h */ void list_names(void) diff --git a/tools/server.c b/tools/server.c index 7d24d6b..a62302f 100644 --- a/tools/server.c +++ b/tools/server.c @@ -440,19 +440,25 @@ choose_ok: static uint32_t sp_do_keyx(const br_ssl_server_policy_class **pctx, - unsigned char *data, size_t len) + unsigned char *data, size_t *len) { policy_context *pc; + uint32_t r; + size_t xoff, xlen; pc = (policy_context *)pctx; switch (pc->sk->key_type) { case BR_KEYTYPE_RSA: return br_rsa_ssl_decrypt( &br_rsa_i31_private, &pc->sk->key.rsa, - data, len); + data, *len); case BR_KEYTYPE_EC: - return br_ec_prime_i31.mul(data, len, pc->sk->key.ec.x, + r = br_ec_all_m15.mul(data, *len, pc->sk->key.ec.x, pc->sk->key.ec.xlen, pc->sk->key.ec.curve); + xoff = br_ec_all_m15.xoff(pc->sk->key.ec.curve, &xlen); + memmove(data, data + xoff, xlen); + *len = xlen; + return r; default: fprintf(stderr, "ERROR: unknown private key type (%d)\n", (int)pc->sk->key_type); @@ -551,7 +557,7 @@ sp_do_sign(const br_ssl_server_policy_class **pctx, } return 0; } - sig_len = br_ecdsa_i31_sign_asn1(&br_ec_prime_i31, + sig_len = br_ecdsa_i31_sign_asn1(&br_ec_all_m15, hc, hv, &pc->sk->key.ec, data); if (sig_len == 0) { if (pc->verbose) { @@ -923,7 +929,7 @@ do_server(int argc, char *argv[]) break; case BR_KEYTYPE_EC: curve = sk->key.ec.curve; - supp = br_ec_prime_i31.supported_curves; + supp = br_ec_all_m15.supported_curves; if (curve > 31 || !((supp >> curve) & 1)) { fprintf(stderr, "ERROR: private key curve (%d)" " is not supported\n", curve); @@ -1047,7 +1053,7 @@ do_server(int argc, char *argv[]) &br_sslrec_out_cbc_vtable); } if ((req & (REQ_ECDHE_RSA | REQ_ECDHE_ECDSA)) != 0) { - br_ssl_engine_set_ec(&cc.eng, &br_ec_prime_i31); + br_ssl_engine_set_ec(&cc.eng, &br_ec_all_m15); } } br_ssl_engine_set_suites(&cc.eng, suite_ids, num_suites); @@ -1120,11 +1126,11 @@ do_server(int argc, char *argv[]) } } br_ssl_engine_set_rsavrfy(&cc.eng, &br_rsa_i31_pkcs1_vrfy); - br_ssl_engine_set_ec(&cc.eng, &br_ec_prime_i31); + br_ssl_engine_set_ec(&cc.eng, &br_ec_all_m15); br_ssl_engine_set_ecdsa(&cc.eng, &br_ecdsa_i31_vrfy_asn1); br_x509_minimal_set_rsa(&xc, &br_rsa_i31_pkcs1_vrfy); br_x509_minimal_set_ecdsa(&xc, - &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1); + &br_ec_all_m15, &br_ecdsa_i31_vrfy_asn1); br_ssl_engine_set_x509(&cc.eng, &xc.vtable); br_ssl_server_set_trust_anchor_names_alt(&cc, &VEC_ELT(anchors, 0), VEC_LEN(anchors)); diff --git a/tools/sslio.c b/tools/sslio.c index e2a6d56..14a3138 100644 --- a/tools/sslio.c +++ b/tools/sslio.c @@ -239,6 +239,13 @@ run_ssl_engine(br_ssl_engine_context *cc, int fd, unsigned flags) get_suite_name_ext( cc->session.cipher_suite, csn, sizeof csn); fprintf(stderr, " cipher suite: %s\n", csn); + if (uses_ecdhe(cc->session.cipher_suite)) { + get_curve_name_ext( + br_ssl_engine_get_ecdhe_curve(cc), + csn, sizeof csn); + fprintf(stderr, + " ECDHE curve: %s\n", csn); + } fprintf(stderr, " secure renegotiation: %s\n", cc->reneg == 1 ? "no" : "yes"); pname = br_ssl_engine_get_selected_protocol(cc);