From d0637e901d6a1dbf8e66453da4abbdf1963926a7 Mon Sep 17 00:00:00 2001 From: Steven Valdez Date: Wed, 3 Jun 2020 15:43:49 -0400 Subject: [PATCH] Remove TRUST_TOKEN_experiment_v0. Update-Note: This gets rid of TRUST_TOKEN_experiment_v0. Existing callers should be updated to call TRUST_TOKEN_experiment_v1. Change-Id: I8ec9b808cbd35546425690d1548db671ff033e14 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/41524 Reviewed-by: David Benjamin Commit-Queue: Steven Valdez --- crypto/ec_extra/hash_to_curve.c | 64 +--- crypto/ec_extra/internal.h | 22 -- crypto/fipsmodule/ec/ec_test.cc | 97 ----- crypto/trust_token/internal.h | 29 -- crypto/trust_token/pmbtoken.c | 479 ++++++------------------- crypto/trust_token/trust_token.c | 52 +-- crypto/trust_token/trust_token_test.cc | 139 +++---- include/openssl/trust_token.h | 11 +- tool/speed.cc | 30 -- 9 files changed, 178 insertions(+), 745 deletions(-) diff --git a/crypto/ec_extra/hash_to_curve.c b/crypto/ec_extra/hash_to_curve.c index 6f8b5995d..9c824544a 100644 --- a/crypto/ec_extra/hash_to_curve.c +++ b/crypto/ec_extra/hash_to_curve.c @@ -50,12 +50,10 @@ // expand_message_xmd implements the operation described in section 5.3.1 of // draft-irtf-cfrg-hash-to-curve-07. It returns one on success and zero on -// allocation failure or if |out_len| was too large. If |is_draft06| is one, it -// implements the operation from draft-irtf-cfrg-hash-to-curve-06 instead. +// allocation failure or if |out_len| was too large. static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len, const uint8_t *msg, size_t msg_len, - const uint8_t *dst, size_t dst_len, - int is_draft06) { + const uint8_t *dst, size_t dst_len) { int ret = 0; const size_t block_size = EVP_MD_block_size(md); const size_t md_size = EVP_MD_size(md); @@ -88,9 +86,8 @@ static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len, !EVP_DigestUpdate(&ctx, kZeros, block_size) || !EVP_DigestUpdate(&ctx, msg, msg_len) || !EVP_DigestUpdate(&ctx, l_i_b_str_zero, sizeof(l_i_b_str_zero)) || - (is_draft06 && !EVP_DigestUpdate(&ctx, &dst_len_u8, 1)) || !EVP_DigestUpdate(&ctx, dst, dst_len) || - (!is_draft06 && !EVP_DigestUpdate(&ctx, &dst_len_u8, 1)) || + !EVP_DigestUpdate(&ctx, &dst_len_u8, 1) || !EVP_DigestFinal_ex(&ctx, b_0, NULL)) { goto err; } @@ -114,9 +111,8 @@ static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len, if (!EVP_DigestInit_ex(&ctx, md, NULL) || !EVP_DigestUpdate(&ctx, b_i, md_size) || !EVP_DigestUpdate(&ctx, &i, 1) || - (is_draft06 && !EVP_DigestUpdate(&ctx, &dst_len_u8, 1)) || !EVP_DigestUpdate(&ctx, dst, dst_len) || - (!is_draft06 && !EVP_DigestUpdate(&ctx, &dst_len_u8, 1)) || + !EVP_DigestUpdate(&ctx, &dst_len_u8, 1) || !EVP_DigestFinal_ex(&ctx, b_i, NULL)) { goto err; } @@ -175,12 +171,11 @@ static void big_endian_to_words(BN_ULONG *out, size_t num_words, static int hash_to_field2(const EC_GROUP *group, const EVP_MD *md, EC_FELEM *out1, EC_FELEM *out2, const uint8_t *dst, size_t dst_len, unsigned k, const uint8_t *msg, - size_t msg_len, int is_draft06) { + size_t msg_len) { size_t L; uint8_t buf[4 * EC_MAX_BYTES]; if (!num_bytes_to_derive(&L, &group->field, k) || - !expand_message_xmd(md, buf, 2 * L, msg, msg_len, dst, dst_len, - is_draft06)) { + !expand_message_xmd(md, buf, 2 * L, msg, msg_len, dst, dst_len)) { return 0; } BN_ULONG words[2 * EC_MAX_WORDS]; @@ -196,12 +191,11 @@ static int hash_to_field2(const EC_GROUP *group, const EVP_MD *md, // group order rather than a field element. |k| is the security factor. static int hash_to_scalar(const EC_GROUP *group, const EVP_MD *md, EC_SCALAR *out, const uint8_t *dst, size_t dst_len, - unsigned k, const uint8_t *msg, size_t msg_len, - int is_draft06) { + unsigned k, const uint8_t *msg, size_t msg_len) { size_t L; uint8_t buf[EC_MAX_BYTES * 2]; if (!num_bytes_to_derive(&L, &group->order, k) || - !expand_message_xmd(md, buf, L, msg, msg_len, dst, dst_len, is_draft06)) { + !expand_message_xmd(md, buf, L, msg, msg_len, dst, dst_len)) { return 0; } @@ -310,10 +304,9 @@ static int map_to_curve_simple_swu(const EC_GROUP *group, const EC_FELEM *Z, static int hash_to_curve(const EC_GROUP *group, const EVP_MD *md, const EC_FELEM *Z, const EC_FELEM *c2, unsigned k, EC_RAW_POINT *out, const uint8_t *dst, size_t dst_len, - const uint8_t *msg, size_t msg_len, int is_draft06) { + const uint8_t *msg, size_t msg_len) { EC_FELEM u0, u1; - if (!hash_to_field2(group, md, &u0, &u1, dst, dst_len, k, msg, msg_len, - is_draft06)) { + if (!hash_to_field2(group, md, &u0, &u1, dst, dst_len, k, msg, msg_len)) { return 0; } @@ -376,7 +369,7 @@ int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( ec_felem_neg(group, &Z, &Z); return hash_to_curve(group, EVP_sha512(), &Z, &c2, /*k=*/192, out, dst, - dst_len, msg, msg_len, /*is_draft06=*/0); + dst_len, msg, msg_len); } int ec_hash_to_scalar_p384_xmd_sha512_draft07( @@ -388,38 +381,5 @@ int ec_hash_to_scalar_p384_xmd_sha512_draft07( } return hash_to_scalar(group, EVP_sha512(), out, dst, dst_len, /*k=*/192, msg, - msg_len, /*is_draft06=*/0); -} - -int ec_hash_to_curve_p521_xmd_sha512_sswu_draft06( - const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst, - size_t dst_len, const uint8_t *msg, size_t msg_len) { - // See section 8.3 of draft-irtf-cfrg-hash-to-curve-06. - if (EC_GROUP_get_curve_name(group) != NID_secp521r1) { - OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); - return 0; - } - - // Z = -4, c2 = 8. - EC_FELEM Z, c2; - if (!felem_from_u8(group, &Z, 4) || - !felem_from_u8(group, &c2, 8)) { - return 0; - } - ec_felem_neg(group, &Z, &Z); - - return hash_to_curve(group, EVP_sha512(), &Z, &c2, /*k=*/256, out, dst, - dst_len, msg, msg_len, /*is_draft06=*/1); -} - -int ec_hash_to_scalar_p521_xmd_sha512_draft06( - const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len, - const uint8_t *msg, size_t msg_len) { - if (EC_GROUP_get_curve_name(group) != NID_secp521r1) { - OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); - return 0; - } - - return hash_to_scalar(group, EVP_sha512(), out, dst, dst_len, /*k=*/256, msg, - msg_len, /*is_draft06=*/1); + msg_len); } diff --git a/crypto/ec_extra/internal.h b/crypto/ec_extra/internal.h index 940a414d3..55314ac73 100644 --- a/crypto/ec_extra/internal.h +++ b/crypto/ec_extra/internal.h @@ -48,28 +48,6 @@ OPENSSL_EXPORT int ec_hash_to_scalar_p384_xmd_sha512_draft07( const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len, const uint8_t *msg, size_t msg_len); -// ec_hash_to_curve_p521_xmd_sha512_sswu_draft06 hashes |msg| to a point on -// |group| and writes the result to |out|, implementing the -// P521_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-06. It -// returns one on success and zero on error. -// -// This function implements an older version of the draft and should not be used -// in new code. -OPENSSL_EXPORT int ec_hash_to_curve_p521_xmd_sha512_sswu_draft06( - const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst, - size_t dst_len, const uint8_t *msg, size_t msg_len); - -// ec_hash_to_scalar_p521_xmd_sha512_draft06 hashes |msg| to a scalar on |group| -// and writes the result to |out|, using the hash_to_field operation from the -// P521_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-06, but -// generating a value modulo the group order rather than a field element. -// -// This function implements an older version of the draft and should not be used -// in new code. -OPENSSL_EXPORT int ec_hash_to_scalar_p521_xmd_sha512_draft06( - const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len, - const uint8_t *msg, size_t msg_len); - #if defined(__cplusplus) } // extern C diff --git a/crypto/fipsmodule/ec/ec_test.cc b/crypto/fipsmodule/ec/ec_test.cc index 59d55b58a..edcfeaac0 100644 --- a/crypto/fipsmodule/ec/ec_test.cc +++ b/crypto/fipsmodule/ec/ec_test.cc @@ -1170,74 +1170,6 @@ TEST(ECTest, HashToCurve) { "37f2913224287b9dfb64742851f760eb14ca115ff9", "1510e764f1be968d661b7aaecb26a6d38c98e5205ca150f0ae426d" "2c3983c68e3a9ffb283c6ae4891d891b5705500475"}, - - // Note these tests do not match the tests vectors - // draft-irtf-cfrg-hash-to-curve-06 due to a - // spec issue. See - // https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/pull/238 for - // corrected test vectors. - {&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1, - "P521_XMD:SHA-512_SSWU_RO_TESTGEN", "", - "00758617b5e40aa8b30fcfd3c7453ad1abeff158de5697d6f1ccb8" - "4690aaa8bb6692986200d16206e85e4f39f1d2829fee1a5904a089" - "b4fab3b76873429877c58f99", - "016edf324d95fcbe4a30f06751f16cdd5d0b49921dd653cefb3ea2" - "dc2b5b903e36d9924a65407283588cc6c224ab6d6324c73cdc166c" - "e1530b46984b459e966349b3"}, - {&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1, - "P521_XMD:SHA-512_SSWU_RO_TESTGEN", "abc", - "00dcec1a83b676247293e96b1672f67aa5d041a4ded49f542a971a" - "60603dd39194f4d8e587f640563a9ab57dcc69af638129b220683f" - "f03ed9ad8cfdff3833a01452", - "01edc4b497be85361a0afc508058792dc7fc6499a4c51fa3475093" - "fd9951ea46fe055e1b007a12caf9be1ce3028bd0b4ca4ffa5200f9" - "d11e7fc96e068276ad1319c2"}, - {&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1, - "P521_XMD:SHA-512_SSWU_RO_TESTGEN", "abcdef0123456789", - "01f58bfb34825d028c392976a09cebee829734f7714c84b8a13580" - "afcc2eb4726e18e307476c1fccdc857a3d6767fd2882875ab132b7" - "fa7f3f6bae8954384001b1a1", - "00ee0d2d0bfb0bdc6215814fe7096a3dfbf020dce4f0645e8e21a9" - "0d6a6113a5ca61ae7d8f3b485b04f2eb2b85e34fc7f9f1bf367386" - "2e03932b0acc3655e84d480f"}, - {&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1, - "P521_XMD:SHA-512_SSWU_RO_TESTGEN", - "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "016d9a90619bb20c49a2a73cc8c6218cd9b3fb13c720fff2e1f8db" - "ac92862c7da4faf404faeff6b64f0d9b1c5824cec99b0d0ed02b3f" - "acb6275ce553404ea361503e", - "007e301e3357fb1d53961c56e53ce2763e44b297062a3eb14b9f8d" - "6aadc92162a74f7e254a606275e76ea0ac343b3bc746f99804bacd" - "7351a76fce44347c72a6fe9a"}, - - // Custom test vector which triggers long DST path. - {&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1, - "P521_XMD:SHA-512_SSWU_RO_TESTGEN_aaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "abcdef0123456789", - "0036b0c8bbec60335ff8b0397c2cb80283b97051cc949c5c190c28" - "92b279fafd6c372dcec3e71eab85c48ed440c14498332548ee46d0" - "c85442cbdc5b4032e86c3884", - "0081e32ca4378ae89b03142361d9c7fbe66acf0351aca3a71eca50" - "7a37fb8673b69cb108d079a248aedd74f06949d6623e7f7605ea10" - "f6f751ab574c005db7377d7f"}, }; for (const auto &test : kTests) { @@ -1269,8 +1201,6 @@ TEST(ECTest, HashToCurve) { EC_RAW_POINT p; static const uint8_t kDST[] = {0, 1, 2, 3}; static const uint8_t kMessage[] = {4, 5, 6, 7}; - EXPECT_FALSE(ec_hash_to_curve_p521_xmd_sha512_sswu_draft06( - p224.get(), &p, kDST, sizeof(kDST), kMessage, sizeof(kMessage))); EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( p224.get(), &p, kDST, sizeof(kDST), kMessage, sizeof(kMessage))); } @@ -1308,31 +1238,6 @@ TEST(ECTest, HashToScalar) { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "750f2fae7d2b2f41ac737d180c1d4363d85a1504798b4976d40921" "1ddb3651c13a5b4daba9975cdfce18336791131915"}, - {&ec_hash_to_scalar_p521_xmd_sha512_draft06, NID_secp521r1, - "P521_XMD:SHA-512_SCALAR_TEST", "", - "01a6206c2fc677c11d51807bf46d64a17f92396673074c5cee9299" - "4d28eec5445d5ed89799b30b39c964ecf62f39d59e7d43de15d910" - "c2c1d69f3ebc01eab241e5dc"}, - {&ec_hash_to_scalar_p521_xmd_sha512_draft06, NID_secp521r1, - "P521_XMD:SHA-512_SCALAR_TEST", "abcdef0123456789", - "00af484a5d9389a9912f555234c578d4b1b7c4a6f5009018d133a4" - "069172c9f5ce2d853b8643fe7bb50a83427ed3520a7a793c41a455" - "a02aa99431434fb6b5b0b26e"}, - {&ec_hash_to_scalar_p521_xmd_sha512_draft06, NID_secp521r1, - "P521_XMD:SHA-512_SCALAR_TEST", - "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "00b2db2ceb64ad055cafc5a0fc92560525d6dcc4975b86bbb79013" - "a1c3ab5d412320cb55df8088a658039a70c5657d5aefaaaa81cc5d" - "eecdd40c03eb0517fe2e158c"}, }; for (const auto &test : kTests) { @@ -1358,8 +1263,6 @@ TEST(ECTest, HashToScalar) { EC_SCALAR scalar; static const uint8_t kDST[] = {0, 1, 2, 3}; static const uint8_t kMessage[] = {4, 5, 6, 7}; - EXPECT_FALSE(ec_hash_to_scalar_p521_xmd_sha512_draft06( - p224.get(), &scalar, kDST, sizeof(kDST), kMessage, sizeof(kMessage))); EXPECT_FALSE(ec_hash_to_scalar_p384_xmd_sha512_draft07( p224.get(), &scalar, kDST, sizeof(kDST), kMessage, sizeof(kMessage))); } diff --git a/crypto/trust_token/internal.h b/crypto/trust_token/internal.h index d65057f07..a44de76c0 100644 --- a/crypto/trust_token/internal.h +++ b/crypto/trust_token/internal.h @@ -77,27 +77,6 @@ OPENSSL_EXPORT void PMBTOKEN_PRETOKEN_free(PMBTOKEN_PRETOKEN *token); DEFINE_STACK_OF(PMBTOKEN_PRETOKEN) -// The following functions implement the corresponding |TRUST_TOKENS_METHOD| -// functions for |TRUST_TOKENS_experiment_v0|'s PMBTokens construction which -// uses P-521. -int pmbtoken_exp0_generate_key(CBB *out_private, CBB *out_public); -int pmbtoken_exp0_client_key_from_bytes(PMBTOKEN_CLIENT_KEY *key, - const uint8_t *in, size_t len); -int pmbtoken_exp0_issuer_key_from_bytes(PMBTOKEN_ISSUER_KEY *key, - const uint8_t *in, size_t len); -STACK_OF(PMBTOKEN_PRETOKEN) * pmbtoken_exp0_blind(CBB *cbb, size_t count); -int pmbtoken_exp0_sign(const PMBTOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, - size_t num_requested, size_t num_to_issue, - uint8_t private_metadata); -STACK_OF(TRUST_TOKEN) * - pmbtoken_exp0_unblind(const PMBTOKEN_CLIENT_KEY *key, - const STACK_OF(PMBTOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id); -int pmbtoken_exp0_read(const PMBTOKEN_ISSUER_KEY *key, - uint8_t out_nonce[PMBTOKEN_NONCE_SIZE], - uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len); - // The following functions implement the corresponding |TRUST_TOKENS_METHOD| // functions for |TRUST_TOKENS_experiment_v1|'s PMBTokens construction which // uses P-384. @@ -193,14 +172,6 @@ struct trust_token_method_st { uint8_t out_nonce[PMBTOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, size_t token_len); - - // use_token_hash determines whether to include the token hash in the SRR and - // private metadata encryption. - int use_token_hash : 1; - - // batched_proof determines whether PMBToken uses a batched DLEQOR proof when - // signing tokens. - int batched_proof : 1; }; // Structure representing a single Trust Token public key with the specified ID. diff --git a/crypto/trust_token/pmbtoken.c b/crypto/trust_token/pmbtoken.c index 291cb868a..5ea60c347 100644 --- a/crypto/trust_token/pmbtoken.c +++ b/crypto/trust_token/pmbtoken.c @@ -52,9 +52,6 @@ typedef struct { // hash_c implements the H_c operation in PMBTokens. It returns one on success // and zero on error. hash_c_func_t hash_c; - // batched_proof determines whether PMBToken uses a batched DLEQOR proof when - // signing tokens. - int batched_proof : 1; } PMBTOKEN_METHOD; static const uint8_t kDefaultAdditionalData[32] = {0}; @@ -62,7 +59,7 @@ static const uint8_t kDefaultAdditionalData[32] = {0}; static int pmbtoken_init_method(PMBTOKEN_METHOD *method, int curve_nid, const uint8_t *h_bytes, size_t h_len, hash_t_func_t hash_t, hash_s_func_t hash_s, - hash_c_func_t hash_c, int batched_proof) { + hash_c_func_t hash_c) { method->group = EC_GROUP_new_by_curve_name(curve_nid); if (method->group == NULL) { return 0; @@ -71,7 +68,6 @@ static int pmbtoken_init_method(PMBTOKEN_METHOD *method, int curve_nid, method->hash_t = hash_t; method->hash_s = hash_s; method->hash_c = hash_c; - method->batched_proof = batched_proof; EC_AFFINE h; if (!ec_point_from_uncompressed(method->group, &h, h_bytes, h_len)) { @@ -724,37 +720,31 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method, return 0; } + if (num_to_issue > ((size_t)-1) / sizeof(EC_RAW_POINT) || + num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); + return 0; + } + int ret = 0; - EC_RAW_POINT *Tps = NULL; - EC_RAW_POINT *Sps = NULL; - EC_RAW_POINT *Wps = NULL; - EC_RAW_POINT *Wsps = NULL; - EC_SCALAR *es = NULL; + EC_RAW_POINT *Tps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Sps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Wps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Wsps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); + EC_SCALAR *es = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR)); CBB batch_cbb; CBB_zero(&batch_cbb); - if (method->batched_proof) { - if (num_to_issue > ((size_t)-1) / sizeof(EC_RAW_POINT) || - num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); - goto err; - } - Tps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); - Sps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); - Wps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); - Wsps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); - es = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR)); - if (!Tps || - !Sps || - !Wps || - !Wsps || - !es || - !CBB_init(&batch_cbb, 0) || - !point_to_cbb(&batch_cbb, method->group, &key->pubs) || - !point_to_cbb(&batch_cbb, method->group, &key->pub0) || - !point_to_cbb(&batch_cbb, method->group, &key->pub1)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } + if (!Tps || + !Sps || + !Wps || + !Wsps || + !es || + !CBB_init(&batch_cbb, 0) || + !point_to_cbb(&batch_cbb, method->group, &key->pubs) || + !point_to_cbb(&batch_cbb, method->group, &key->pub0) || + !point_to_cbb(&batch_cbb, method->group, &key->pub1)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; } for (size_t i = 0; i < num_to_issue; i++) { @@ -793,25 +783,17 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method, goto err; } - if (!method->batched_proof) { - if (!CBB_add_u16_length_prefixed(cbb, &child) || - !dleq_generate(method, &child, key, &Tp, &jacobians[0], &jacobians[1], - &jacobians[2], private_metadata)) { - goto err; - } - } else { - if (!point_to_cbb(&batch_cbb, group, &Tp_affine) || - !point_to_cbb(&batch_cbb, group, &affines[0]) || - !point_to_cbb(&batch_cbb, group, &affines[1]) || - !point_to_cbb(&batch_cbb, group, &affines[2])) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - Tps[i] = Tp; - Sps[i] = jacobians[0]; - Wps[i] = jacobians[1]; - Wsps[i] = jacobians[2]; + if (!point_to_cbb(&batch_cbb, group, &Tp_affine) || + !point_to_cbb(&batch_cbb, group, &affines[0]) || + !point_to_cbb(&batch_cbb, group, &affines[1]) || + !point_to_cbb(&batch_cbb, group, &affines[2])) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; } + Tps[i] = Tp; + Sps[i] = jacobians[0]; + Wps[i] = jacobians[1]; + Wsps[i] = jacobians[2]; if (!CBB_flush(cbb)) { goto err; @@ -821,36 +803,34 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method, // The DLEQ batching construction is described in appendix B of // https://eprint.iacr.org/2020/072/20200324:214215. Note the additional // computations all act on public inputs. - if (method->batched_proof) { - for (size_t i = 0; i < num_to_issue; i++) { - if (!hash_c_batch(method, &es[i], &batch_cbb, i)) { - goto err; - } - } - - EC_RAW_POINT Tp_batch, Sp_batch, Wp_batch, Wsp_batch; - if (!ec_point_mul_scalar_public_batch(group, &Tp_batch, - /*g_scalar=*/NULL, Tps, es, - num_to_issue) || - !ec_point_mul_scalar_public_batch(group, &Sp_batch, - /*g_scalar=*/NULL, Sps, es, - num_to_issue) || - !ec_point_mul_scalar_public_batch(group, &Wp_batch, - /*g_scalar=*/NULL, Wps, es, - num_to_issue) || - !ec_point_mul_scalar_public_batch(group, &Wsp_batch, - /*g_scalar=*/NULL, Wsps, es, - num_to_issue)) { + for (size_t i = 0; i < num_to_issue; i++) { + if (!hash_c_batch(method, &es[i], &batch_cbb, i)) { goto err; } + } - CBB proof; - if (!CBB_add_u16_length_prefixed(cbb, &proof) || - !dleq_generate(method, &proof, key, &Tp_batch, &Sp_batch, &Wp_batch, - &Wsp_batch, private_metadata) || - !CBB_flush(cbb)) { - goto err; - } + EC_RAW_POINT Tp_batch, Sp_batch, Wp_batch, Wsp_batch; + if (!ec_point_mul_scalar_public_batch(group, &Tp_batch, + /*g_scalar=*/NULL, Tps, es, + num_to_issue) || + !ec_point_mul_scalar_public_batch(group, &Sp_batch, + /*g_scalar=*/NULL, Sps, es, + num_to_issue) || + !ec_point_mul_scalar_public_batch(group, &Wp_batch, + /*g_scalar=*/NULL, Wps, es, + num_to_issue) || + !ec_point_mul_scalar_public_batch(group, &Wsp_batch, + /*g_scalar=*/NULL, Wsps, es, + num_to_issue)) { + goto err; + } + + CBB proof; + if (!CBB_add_u16_length_prefixed(cbb, &proof) || + !dleq_generate(method, &proof, key, &Tp_batch, &Sp_batch, &Wp_batch, + &Wsp_batch, private_metadata) || + !CBB_flush(cbb)) { + goto err; } // Skip over any unused requests. @@ -890,36 +870,29 @@ static STACK_OF(TRUST_TOKEN) * return NULL; } - EC_RAW_POINT *Tps = NULL; - EC_RAW_POINT *Sps = NULL; - EC_RAW_POINT *Wps = NULL; - EC_RAW_POINT *Wsps = NULL; - EC_SCALAR *es = NULL; + if (count > ((size_t)-1) / sizeof(EC_RAW_POINT) || + count > ((size_t)-1) / sizeof(EC_SCALAR)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); + return 0; + } + EC_RAW_POINT *Tps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Sps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Wps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); + EC_RAW_POINT *Wsps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); + EC_SCALAR *es = OPENSSL_malloc(count * sizeof(EC_SCALAR)); CBB batch_cbb; CBB_zero(&batch_cbb); - if (method->batched_proof) { - if (count > ((size_t)-1) / sizeof(EC_RAW_POINT) || - count > ((size_t)-1) / sizeof(EC_SCALAR)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); - goto err; - } - Tps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); - Sps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); - Wps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); - Wsps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); - es = OPENSSL_malloc(count * sizeof(EC_SCALAR)); - if (!Tps || - !Sps || - !Wps || - !Wsps || - !es || - !CBB_init(&batch_cbb, 0) || - !point_to_cbb(&batch_cbb, method->group, &key->pubs) || - !point_to_cbb(&batch_cbb, method->group, &key->pub0) || - !point_to_cbb(&batch_cbb, method->group, &key->pub1)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } + if (!Tps || + !Sps || + !Wps || + !Wsps || + !es || + !CBB_init(&batch_cbb, 0) || + !point_to_cbb(&batch_cbb, method->group, &key->pubs) || + !point_to_cbb(&batch_cbb, method->group, &key->pub0) || + !point_to_cbb(&batch_cbb, method->group, &key->pub1)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; } for (size_t i = 0; i < count; i++) { @@ -928,7 +901,6 @@ static STACK_OF(TRUST_TOKEN) * uint8_t s[PMBTOKEN_NONCE_SIZE]; EC_AFFINE Wp_affine, Wsp_affine; - CBS proof; if (!CBS_copy_bytes(cbs, s, PMBTOKEN_NONCE_SIZE) || !cbs_get_prefixed_point(cbs, group, &Wp_affine) || !cbs_get_prefixed_point(cbs, group, &Wsp_affine)) { @@ -936,50 +908,29 @@ static STACK_OF(TRUST_TOKEN) * goto err; } - EC_RAW_POINT Tp, Wp, Wsp, Sp; - ec_affine_to_jacobian(group, &Tp, &pretoken->Tp); - ec_affine_to_jacobian(group, &Wp, &Wp_affine); - ec_affine_to_jacobian(group, &Wsp, &Wsp_affine); - if (!method->hash_s(group, &Sp, &pretoken->Tp, s)) { + ec_affine_to_jacobian(group, &Tps[i], &pretoken->Tp); + ec_affine_to_jacobian(group, &Wps[i], &Wp_affine); + ec_affine_to_jacobian(group, &Wsps[i], &Wsp_affine); + if (!method->hash_s(group, &Sps[i], &pretoken->Tp, s)) { goto err; } - if (!method->batched_proof) { - if(!CBS_get_u16_length_prefixed(cbs, &proof)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); - goto err; - } - - if (!dleq_verify(method, &proof, key, &Tp, &Sp, &Wp, &Wsp)) { - goto err; - } - - if (CBS_len(&proof) != 0) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); - goto err; - } - } else { - EC_AFFINE Sp_affine; - if (!point_to_cbb(&batch_cbb, group, &pretoken->Tp) || - !ec_jacobian_to_affine(group, &Sp_affine, &Sp) || - !point_to_cbb(&batch_cbb, group, &Sp_affine) || - !point_to_cbb(&batch_cbb, group, &Wp_affine) || - !point_to_cbb(&batch_cbb, group, &Wsp_affine)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - Tps[i] = Tp; - Sps[i] = Sp; - Wps[i] = Wp; - Wsps[i] = Wsp; + EC_AFFINE Sp_affine; + if (!point_to_cbb(&batch_cbb, group, &pretoken->Tp) || + !ec_jacobian_to_affine(group, &Sp_affine, &Sps[i]) || + !point_to_cbb(&batch_cbb, group, &Sp_affine) || + !point_to_cbb(&batch_cbb, group, &Wp_affine) || + !point_to_cbb(&batch_cbb, group, &Wsp_affine)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + goto err; } // Unblind the token. EC_RAW_POINT jacobians[3]; EC_AFFINE affines[3]; - if (!ec_point_mul_scalar(group, &jacobians[0], &Sp, &pretoken->r) || - !ec_point_mul_scalar(group, &jacobians[1], &Wp, &pretoken->r) || - !ec_point_mul_scalar(group, &jacobians[2], &Wsp, &pretoken->r) || + if (!ec_point_mul_scalar(group, &jacobians[0], &Sps[i], &pretoken->r) || + !ec_point_mul_scalar(group, &jacobians[1], &Wps[i], &pretoken->r) || + !ec_point_mul_scalar(group, &jacobians[2], &Wsps[i], &pretoken->r) || !ec_jacobian_to_affine_batch(group, affines, jacobians, 3)) { goto err; } @@ -1018,32 +969,30 @@ static STACK_OF(TRUST_TOKEN) * // The DLEQ batching construction is described in appendix B of // https://eprint.iacr.org/2020/072/20200324:214215. Note the additional // computations all act on public inputs. - if (method->batched_proof) { - for (size_t i = 0; i < count; i++) { - if (!hash_c_batch(method, &es[i], &batch_cbb, i)) { - goto err; - } - } - - EC_RAW_POINT Tp_batch, Sp_batch, Wp_batch, Wsp_batch; - if (!ec_point_mul_scalar_public_batch(group, &Tp_batch, - /*g_scalar=*/NULL, Tps, es, count) || - !ec_point_mul_scalar_public_batch(group, &Sp_batch, - /*g_scalar=*/NULL, Sps, es, count) || - !ec_point_mul_scalar_public_batch(group, &Wp_batch, - /*g_scalar=*/NULL, Wps, es, count) || - !ec_point_mul_scalar_public_batch(group, &Wsp_batch, - /*g_scalar=*/NULL, Wsps, es, count)) { + for (size_t i = 0; i < count; i++) { + if (!hash_c_batch(method, &es[i], &batch_cbb, i)) { goto err; } + } - CBS proof; - if (!CBS_get_u16_length_prefixed(cbs, &proof) || - !dleq_verify(method, &proof, key, &Tp_batch, &Sp_batch, &Wp_batch, - &Wsp_batch) || - CBS_len(&proof) != 0) { - goto err; - } + EC_RAW_POINT Tp_batch, Sp_batch, Wp_batch, Wsp_batch; + if (!ec_point_mul_scalar_public_batch(group, &Tp_batch, + /*g_scalar=*/NULL, Tps, es, count) || + !ec_point_mul_scalar_public_batch(group, &Sp_batch, + /*g_scalar=*/NULL, Sps, es, count) || + !ec_point_mul_scalar_public_batch(group, &Wp_batch, + /*g_scalar=*/NULL, Wps, es, count) || + !ec_point_mul_scalar_public_batch(group, &Wsp_batch, + /*g_scalar=*/NULL, Wsps, es, count)) { + goto err; + } + + CBS proof; + if (!CBS_get_u16_length_prefixed(cbs, &proof) || + !dleq_verify(method, &proof, key, &Tp_batch, &Sp_batch, &Wp_batch, + &Wsp_batch) || + CBS_len(&proof) != 0) { + goto err; } ok = 1; @@ -1127,202 +1076,6 @@ static int pmbtoken_read(const PMBTOKEN_METHOD *method, } -// PMBTokens experiment v0. - -static int pmbtoken_exp0_hash_t(const EC_GROUP *group, EC_RAW_POINT *out, - const uint8_t t[PMBTOKEN_NONCE_SIZE]) { - const uint8_t kHashTLabel[] = "PMBTokensV0 HashT"; - return ec_hash_to_curve_p521_xmd_sha512_sswu_draft06( - group, out, kHashTLabel, sizeof(kHashTLabel), t, PMBTOKEN_NONCE_SIZE); -} - -static int pmbtoken_exp0_hash_s(const EC_GROUP *group, EC_RAW_POINT *out, - const EC_AFFINE *t, - const uint8_t s[PMBTOKEN_NONCE_SIZE]) { - const uint8_t kHashSLabel[] = "PMBTokensV0 HashS"; - int ret = 0; - CBB cbb; - uint8_t *buf = NULL; - size_t len; - if (!CBB_init(&cbb, 0) || - !point_to_cbb(&cbb, group, t) || - !CBB_add_bytes(&cbb, s, PMBTOKEN_NONCE_SIZE) || - !CBB_finish(&cbb, &buf, &len) || - !ec_hash_to_curve_p521_xmd_sha512_sswu_draft06( - group, out, kHashSLabel, sizeof(kHashSLabel), buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - - ret = 1; - -err: - OPENSSL_free(buf); - CBB_cleanup(&cbb); - return ret; -} - -static int pmbtoken_exp0_hash_c(const EC_GROUP *group, EC_SCALAR *out, - uint8_t *buf, size_t len) { - const uint8_t kHashCLabel[] = "PMBTokensV0 HashC"; - return ec_hash_to_scalar_p521_xmd_sha512_draft06( - group, out, kHashCLabel, sizeof(kHashCLabel), buf, len); -} - -// H for PMBTokens v0 was generated with the following Python code. -/* -import hashlib - -SEED_H = 'PrivacyPass H' - -A = -3 -B = 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00 -P = 2**521 - 1 - -def get_y(x): - y2 = (x**3 + A*x + B) % P - y = pow(y2, (P+1)/4, P) - if (y*y) % P != y2: - raise ValueError("point not on curve") - return y - -def bit(h,i): - return (ord(h[i/8]) >> (i%8)) & 1 - -b = 521 -def decode_point(so): - s = hashlib.sha256(so + '0').digest() + hashlib.sha256(so + '1').digest() + \ - hashlib.sha256(so + '2').digest() - - x = 0 - for i in range(0,b): - x = x + (long(bit(s,i))<= P: - raise ValueError("x out of range") - y = get_y(x) - if y & 1 != bit(s,b-1): y = P-y - return (x, y) - - -def gen_point(seed): - v = hashlib.sha256(seed).digest() - it = 1 - while True: - try: - x,y = decode_point(v) - except Exception, e: - print e - it += 1 - v = hashlib.sha256(v).digest() - continue - print "Found in %d iterations:" % it - print " x = %d" % x - print " y = %d" % y - print " Encoded (hex): (%x, %x)" % (x, y) - return (x, y) - -if __name__ == "__main__": - gen_point(SEED_H) -*/ -static int pmbtoken_exp0_ok = 0; -static PMBTOKEN_METHOD pmbtoken_exp0_method; -static CRYPTO_once_t pmbtoken_exp0_method_once = CRYPTO_ONCE_INIT; - -static void pmbtoken_exp0_init_method_impl(void) { - static const uint8_t kH[] = { - 0x04, 0x01, 0xf0, 0xa9, 0xf7, 0x9e, 0xbc, 0x12, 0x6c, 0xef, 0xd1, 0xab, - 0x29, 0x10, 0x03, 0x6f, 0x4e, 0xf5, 0xbd, 0xeb, 0x0f, 0x6b, 0xc0, 0x5c, - 0x0e, 0xce, 0xfe, 0x59, 0x45, 0xd1, 0x3e, 0x25, 0x33, 0x7e, 0x4c, 0xda, - 0x64, 0x53, 0x54, 0x4e, 0xf9, 0x76, 0x0d, 0x6d, 0xc5, 0x39, 0x2a, 0xd4, - 0xce, 0x84, 0x6e, 0x31, 0xc2, 0x86, 0x21, 0xf9, 0x5c, 0x98, 0xb9, 0x3d, - 0x01, 0x74, 0x9f, 0xc5, 0x1e, 0x47, 0x24, 0x00, 0x5c, 0x17, 0x62, 0x51, - 0x7d, 0x32, 0x5e, 0x29, 0xac, 0x52, 0x14, 0x75, 0x6f, 0x36, 0xd9, 0xc7, - 0xfa, 0xbb, 0xa9, 0x3b, 0x9d, 0x70, 0x49, 0x1e, 0xb4, 0x53, 0xbc, 0x55, - 0xea, 0xad, 0x8f, 0x26, 0x1d, 0xe0, 0xbc, 0xf3, 0x50, 0x5c, 0x7e, 0x66, - 0x41, 0xb5, 0x61, 0x70, 0x12, 0x72, 0xac, 0x6a, 0xb0, 0x6e, 0x78, 0x3d, - 0x17, 0x08, 0xe3, 0xdf, 0x3c, 0xff, 0xa6, 0xa0, 0xea, 0x96, 0x67, 0x92, - 0xcd, - }; - - pmbtoken_exp0_ok = - pmbtoken_init_method(&pmbtoken_exp0_method, NID_secp521r1, kH, sizeof(kH), - pmbtoken_exp0_hash_t, pmbtoken_exp0_hash_s, - pmbtoken_exp0_hash_c, /*batched_proof=*/0); -} - -static int pmbtoken_exp0_init_method(void) { - CRYPTO_once(&pmbtoken_exp0_method_once, pmbtoken_exp0_init_method_impl); - if (!pmbtoken_exp0_ok) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); - return 0; - } - return 1; -} - -int pmbtoken_exp0_generate_key(CBB *out_private, CBB *out_public) { - if (!pmbtoken_exp0_init_method()) { - return 0; - } - - return pmbtoken_generate_key(&pmbtoken_exp0_method, out_private, out_public); -} - -int pmbtoken_exp0_client_key_from_bytes(PMBTOKEN_CLIENT_KEY *key, - const uint8_t *in, size_t len) { - if (!pmbtoken_exp0_init_method()) { - return 0; - } - return pmbtoken_client_key_from_bytes(&pmbtoken_exp0_method, key, in, len); -} - -int pmbtoken_exp0_issuer_key_from_bytes(PMBTOKEN_ISSUER_KEY *key, - const uint8_t *in, size_t len) { - if (!pmbtoken_exp0_init_method()) { - return 0; - } - return pmbtoken_issuer_key_from_bytes(&pmbtoken_exp0_method, key, in, len); -} - -STACK_OF(PMBTOKEN_PRETOKEN) * pmbtoken_exp0_blind(CBB *cbb, size_t count) { - if (!pmbtoken_exp0_init_method()) { - return NULL; - } - return pmbtoken_blind(&pmbtoken_exp0_method, cbb, count); -} - -int pmbtoken_exp0_sign(const PMBTOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, - size_t num_requested, size_t num_to_issue, - uint8_t private_metadata) { - if (!pmbtoken_exp0_init_method()) { - return 0; - } - return pmbtoken_sign(&pmbtoken_exp0_method, key, cbb, cbs, num_requested, - num_to_issue, private_metadata); -} - -STACK_OF(TRUST_TOKEN) * - pmbtoken_exp0_unblind(const PMBTOKEN_CLIENT_KEY *key, - const STACK_OF(PMBTOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id) { - if (!pmbtoken_exp0_init_method()) { - return NULL; - } - return pmbtoken_unblind(&pmbtoken_exp0_method, key, pretokens, cbs, count, - key_id); -} - -int pmbtoken_exp0_read(const PMBTOKEN_ISSUER_KEY *key, - uint8_t out_nonce[PMBTOKEN_NONCE_SIZE], - uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len) { - if (!pmbtoken_exp0_init_method()) { - return 0; - } - return pmbtoken_read(&pmbtoken_exp0_method, key, out_nonce, - out_private_metadata, token, token_len); -} - - // PMBTokens experiment v1. static int pmbtoken_exp1_hash_t(const EC_GROUP *group, EC_RAW_POINT *out, @@ -1387,7 +1140,7 @@ static void pmbtoken_exp1_init_method_impl(void) { pmbtoken_exp1_ok = pmbtoken_init_method(&pmbtoken_exp1_method, NID_secp384r1, kH, sizeof(kH), pmbtoken_exp1_hash_t, pmbtoken_exp1_hash_s, - pmbtoken_exp1_hash_c, /*batched_proof=*/1); + pmbtoken_exp1_hash_c); } static int pmbtoken_exp1_init_method(void) { diff --git a/crypto/trust_token/trust_token.c b/crypto/trust_token/trust_token.c index 1ade23e39..87b827714 100644 --- a/crypto/trust_token/trust_token.c +++ b/crypto/trust_token/trust_token.c @@ -27,21 +27,6 @@ // protocol for issuing and redeeming tokens built on top of the PMBTokens // construction. -const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v0(void) { - static const TRUST_TOKEN_METHOD kMethod = { - pmbtoken_exp0_generate_key, - pmbtoken_exp0_client_key_from_bytes, - pmbtoken_exp0_issuer_key_from_bytes, - pmbtoken_exp0_blind, - pmbtoken_exp0_sign, - pmbtoken_exp0_unblind, - pmbtoken_exp0_read, - 0 /* don't use token hash */, - 0 /* don't use batched proof */, - }; - return &kMethod; -} - const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void) { static const TRUST_TOKEN_METHOD kMethod = { pmbtoken_exp1_generate_key, @@ -51,8 +36,6 @@ const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void) { pmbtoken_exp1_sign, pmbtoken_exp1_unblind, pmbtoken_exp1_read, - 1 /* use token hash */, - 1 /* use batched proof */, }; return &kMethod; } @@ -597,16 +580,8 @@ int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, SHA256_Update(&sha_ctx, CBS_data(&token_copy), CBS_len(&token_copy)); SHA256_Final(token_hash, &sha_ctx); - uint8_t metadata_obfuscator; - if (ctx->method->use_token_hash) { - metadata_obfuscator = - get_metadata_obfuscator(ctx->metadata_key, ctx->metadata_key_len, - token_hash, sizeof(token_hash)); - } else { - metadata_obfuscator = - get_metadata_obfuscator(ctx->metadata_key, ctx->metadata_key_len, - CBS_data(&client_data), CBS_len(&client_data)); - } + uint8_t metadata_obfuscator = get_metadata_obfuscator( + ctx->metadata_key, ctx->metadata_key_len, token_hash, sizeof(token_hash)); // The SRR is constructed as per the format described in // https://docs.google.com/document/d/1TNnya6B8pyomDK2F1R9CL3dY10OAmqWlnCxsWyOBDVQ/edit#heading=h.7mkzvhpqb8l5 @@ -625,10 +600,7 @@ int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, assert(strlen(kClientDataLabel) < strlen(kExpiryTimestampLabel)); assert(strlen(kPublicLabel) < strlen(kPrivateLabel)); - size_t map_entries = 3; - if (ctx->method->use_token_hash) { - map_entries = 4; - } + size_t map_entries = 4; if (!CBB_init(&srr, 0) || !add_cbor_map(&srr, map_entries) || // SRR map @@ -637,20 +609,10 @@ int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, !add_cbor_text(&srr, kPublicLabel, strlen(kPublicLabel)) || !add_cbor_int(&srr, public_metadata) || !add_cbor_text(&srr, kPrivateLabel, strlen(kPrivateLabel)) || - !add_cbor_int(&srr, private_metadata ^ metadata_obfuscator)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (ctx->method->use_token_hash) { - if (!add_cbor_text(&srr, kTokenHashLabel, strlen(kTokenHashLabel)) || - !add_cbor_bytes(&srr, token_hash, sizeof(token_hash))) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - if (!add_cbor_text(&srr, kClientDataLabel, strlen(kClientDataLabel)) || + !add_cbor_int(&srr, private_metadata ^ metadata_obfuscator) || + !add_cbor_text(&srr, kTokenHashLabel, strlen(kTokenHashLabel)) || + !add_cbor_bytes(&srr, token_hash, sizeof(token_hash)) || + !add_cbor_text(&srr, kClientDataLabel, strlen(kClientDataLabel)) || !CBB_add_bytes(&srr, CBS_data(&client_data), CBS_len(&client_data)) || !add_cbor_text(&srr, kExpiryTimestampLabel, strlen(kExpiryTimestampLabel)) || diff --git a/crypto/trust_token/trust_token_test.cc b/crypto/trust_token/trust_token_test.cc index 41bf55ddf..f6ff86c2b 100644 --- a/crypto/trust_token/trust_token_test.cc +++ b/crypto/trust_token/trust_token_test.cc @@ -44,18 +44,6 @@ BSSL_NAMESPACE_BEGIN namespace { -TEST(TrustTokenTest, KeyGenExp0) { - uint8_t priv_key[TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE]; - uint8_t pub_key[TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE]; - size_t priv_key_len, pub_key_len; - ASSERT_TRUE(TRUST_TOKEN_generate_key( - TRUST_TOKEN_experiment_v0(), priv_key, &priv_key_len, - TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, pub_key, &pub_key_len, - TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0x0001)); - ASSERT_EQ(400u, priv_key_len); - ASSERT_EQ(409u, pub_key_len); -} - TEST(TrustTokenTest, KeyGenExp1) { uint8_t priv_key[TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE]; uint8_t pub_key[TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE]; @@ -91,7 +79,7 @@ TEST(TrustTokenTest, HExp1) { } static std::vector AllMethods() { - return {TRUST_TOKEN_experiment_v0(), TRUST_TOKEN_experiment_v1()}; + return {TRUST_TOKEN_experiment_v1()}; } class TrustTokenProtocolTestBase : public ::testing::Test { @@ -454,14 +442,7 @@ TEST_P(TrustTokenMetadataTest, SetAndGetMetadata) { const uint8_t kClientData[] = "\x70TEST CLIENT DATA"; uint64_t kRedemptionTime = 13374242; - const uint8_t kExpectedSRRNoTokenHash[] = - "\xa3\x68\x6d\x65\x74\x61\x64\x61\x74\x61\xa2\x66\x70\x75\x62\x6c\x69" - "\x63\x00\x67\x70\x72\x69\x76\x61\x74\x65\x00\x6b\x63\x6c\x69\x65\x6e" - "\x74\x2d\x64\x61\x74\x61\x70\x54\x45\x53\x54\x20\x43\x4c\x49\x45\x4e" - "\x54\x20\x44\x41\x54\x41\x70\x65\x78\x70\x69\x72\x79\x2d\x74\x69\x6d" - "\x65\x73\x74\x61\x6d\x70\x1a\x00\xcc\x15\x7a"; - - const uint8_t kExpectedSRRTokenHash[] = + const uint8_t kExpectedSRR[] = "\xa4\x68\x6d\x65\x74\x61\x64\x61\x74\x61\xa2\x66\x70\x75\x62\x6c\x69" "\x63\x00\x67\x70\x72\x69\x76\x61\x74\x65\x00\x6a\x74\x6f\x6b\x65\x6e" "\x2d\x68\x61\x73\x68\x58\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" @@ -498,50 +479,33 @@ TEST_P(TrustTokenMetadataTest, SetAndGetMetadata) { bssl::UniquePtr free_srr(srr); bssl::UniquePtr free_sig(sig); - if (method()->use_token_hash) { - const uint8_t kTokenHashDSTLabel[] = "TrustTokenV0 TokenHash"; - uint8_t token_hash[SHA256_DIGEST_LENGTH]; - SHA256_CTX sha_ctx; - SHA256_Init(&sha_ctx); - SHA256_Update(&sha_ctx, kTokenHashDSTLabel, sizeof(kTokenHashDSTLabel)); - SHA256_Update(&sha_ctx, token->data, token->len); - SHA256_Final(token_hash, &sha_ctx); - - // Check the token hash is in the SRR. - ASSERT_EQ(Bytes(token_hash), Bytes(srr + 41, sizeof(token_hash))); - - uint8_t decode_private_metadata; - ASSERT_TRUE(TRUST_TOKEN_decode_private_metadata( - method(), &decode_private_metadata, metadata_key, - sizeof(metadata_key), token_hash, sizeof(token_hash), srr[27])); - ASSERT_EQ(srr[18], public_metadata()); - ASSERT_EQ(decode_private_metadata, private_metadata()); - - // Clear out the metadata bits. - srr[18] = 0; - srr[27] = 0; - - // Clear out the token hash. - OPENSSL_memset(srr + 41, 0, sizeof(token_hash)); - - ASSERT_EQ(Bytes(kExpectedSRRTokenHash, sizeof(kExpectedSRRTokenHash) - 1), - Bytes(srr, srr_len)); - } else { - uint8_t decode_private_metadata; - ASSERT_TRUE(TRUST_TOKEN_decode_private_metadata( - method(), &decode_private_metadata, metadata_key, - sizeof(metadata_key), kClientData, sizeof(kClientData) - 1, srr[27])); - ASSERT_EQ(srr[18], public_metadata()); - ASSERT_EQ(decode_private_metadata, private_metadata()); - - // Clear out the metadata bits. - srr[18] = 0; - srr[27] = 0; - - ASSERT_EQ( - Bytes(kExpectedSRRNoTokenHash, sizeof(kExpectedSRRNoTokenHash) - 1), - Bytes(srr, srr_len)); - } + const uint8_t kTokenHashDSTLabel[] = "TrustTokenV0 TokenHash"; + uint8_t token_hash[SHA256_DIGEST_LENGTH]; + SHA256_CTX sha_ctx; + SHA256_Init(&sha_ctx); + SHA256_Update(&sha_ctx, kTokenHashDSTLabel, sizeof(kTokenHashDSTLabel)); + SHA256_Update(&sha_ctx, token->data, token->len); + SHA256_Final(token_hash, &sha_ctx); + + // Check the token hash is in the SRR. + ASSERT_EQ(Bytes(token_hash), Bytes(srr + 41, sizeof(token_hash))); + + uint8_t decode_private_metadata; + ASSERT_TRUE(TRUST_TOKEN_decode_private_metadata( + method(), &decode_private_metadata, metadata_key, sizeof(metadata_key), + token_hash, sizeof(token_hash), srr[27])); + ASSERT_EQ(srr[18], public_metadata()); + ASSERT_EQ(decode_private_metadata, private_metadata()); + + // Clear out the metadata bits. + srr[18] = 0; + srr[27] = 0; + + // Clear out the token hash. + OPENSSL_memset(srr + 41, 0, sizeof(token_hash)); + + ASSERT_EQ(Bytes(kExpectedSRR, sizeof(kExpectedSRR) - 1), + Bytes(srr, srr_len)); } } @@ -607,23 +571,14 @@ TEST_P(TrustTokenMetadataTest, TruncatedProof) { ASSERT_TRUE(CBB_add_u16(bad_response.get(), CBS_len(&tmp))); ASSERT_TRUE( CBB_add_bytes(bad_response.get(), CBS_data(&tmp), CBS_len(&tmp))); - if (!method()->batched_proof) { - ASSERT_TRUE(CBS_get_u16_length_prefixed(&real_response, &tmp)); - CBB dleq; - ASSERT_TRUE(CBB_add_u16_length_prefixed(bad_response.get(), &dleq)); - ASSERT_TRUE(CBB_add_bytes(&dleq, CBS_data(&tmp), CBS_len(&tmp) - 2)); - ASSERT_TRUE(CBB_flush(bad_response.get())); - } } - if (method()->batched_proof) { - CBS tmp; - ASSERT_TRUE(CBS_get_u16_length_prefixed(&real_response, &tmp)); - CBB dleq; - ASSERT_TRUE(CBB_add_u16_length_prefixed(bad_response.get(), &dleq)); - ASSERT_TRUE(CBB_add_bytes(&dleq, CBS_data(&tmp), CBS_len(&tmp) - 2)); - ASSERT_TRUE(CBB_flush(bad_response.get())); - } + CBS tmp; + ASSERT_TRUE(CBS_get_u16_length_prefixed(&real_response, &tmp)); + CBB dleq; + ASSERT_TRUE(CBB_add_u16_length_prefixed(bad_response.get(), &dleq)); + ASSERT_TRUE(CBB_add_bytes(&dleq, CBS_data(&tmp), CBS_len(&tmp) - 2)); + ASSERT_TRUE(CBB_flush(bad_response.get())); uint8_t *bad_buf; size_t bad_len; @@ -675,25 +630,15 @@ TEST_P(TrustTokenMetadataTest, ExcessDataProof) { ASSERT_TRUE(CBB_add_u16(bad_response.get(), CBS_len(&tmp))); ASSERT_TRUE( CBB_add_bytes(bad_response.get(), CBS_data(&tmp), CBS_len(&tmp))); - if (!method()->batched_proof) { - ASSERT_TRUE(CBS_get_u16_length_prefixed(&real_response, &tmp)); - CBB dleq; - ASSERT_TRUE(CBB_add_u16_length_prefixed(bad_response.get(), &dleq)); - ASSERT_TRUE(CBB_add_bytes(&dleq, CBS_data(&tmp), CBS_len(&tmp))); - ASSERT_TRUE(CBB_add_u16(&dleq, 42)); - ASSERT_TRUE(CBB_flush(bad_response.get())); - } } - if (method()->batched_proof) { - CBS tmp; - ASSERT_TRUE(CBS_get_u16_length_prefixed(&real_response, &tmp)); - CBB dleq; - ASSERT_TRUE(CBB_add_u16_length_prefixed(bad_response.get(), &dleq)); - ASSERT_TRUE(CBB_add_bytes(&dleq, CBS_data(&tmp), CBS_len(&tmp))); - ASSERT_TRUE(CBB_add_u16(&dleq, 42)); - ASSERT_TRUE(CBB_flush(bad_response.get())); - } + CBS tmp; + ASSERT_TRUE(CBS_get_u16_length_prefixed(&real_response, &tmp)); + CBB dleq; + ASSERT_TRUE(CBB_add_u16_length_prefixed(bad_response.get(), &dleq)); + ASSERT_TRUE(CBB_add_bytes(&dleq, CBS_data(&tmp), CBS_len(&tmp))); + ASSERT_TRUE(CBB_add_u16(&dleq, 42)); + ASSERT_TRUE(CBB_flush(bad_response.get())); uint8_t *bad_buf; size_t bad_len; diff --git a/include/openssl/trust_token.h b/include/openssl/trust_token.h index a73a8687d..9ecf75f19 100644 --- a/include/openssl/trust_token.h +++ b/include/openssl/trust_token.h @@ -36,13 +36,8 @@ extern "C" { // // WARNING: This API is unstable and subject to change. -// TRUST_TOKEN_experiment_v0 is an experimental Trust Tokens protocol using -// PMBTokens and P-521. -OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v0(void); - // TRUST_TOKEN_experiment_v1 is an experimental Trust Tokens protocol using -// PMBTokens and P-384. This version is still under developement and should not -// be used yet. +// PMBTokens and P-384. OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void); // trust_token_st represents a single-use token for the Trust Token protocol. @@ -234,9 +229,6 @@ OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_issue( // returning the SRR to the client. If the value has been reused, the caller // must discard the SRR and report an error to the caller. Returning an SRR with // replayed values allows an attacker to double-spend tokens. -// -// The private metadata construction in |TRUST_TOKEN_experiment_v0| does not -// keep the value secret and should not be used when secrecy is required. OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem( const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, size_t *out_len, TRUST_TOKEN **out_token, uint8_t **out_client_data, @@ -246,7 +238,6 @@ OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem( // TRUST_TOKEN_decode_private_metadata decodes |encrypted_bit| using the // private metadata key specified by a |key| buffer of length |key_len| and the // nonce by a |nonce| buffer of length |nonce_len|. The nonce in -// |TRUST_TOKEN_experiment_v0| is the client-data field of the SRR. The nonce in // |TRUST_TOKEN_experiment_v1| is the token-hash field of the SRR. |*out_value| // is set to the decrypted value, either zero or one. It returns one on success // and zero on error. diff --git a/tool/speed.cc b/tool/speed.cc index 2c36c80c2..af81a603f 100644 --- a/tool/speed.cc +++ b/tool/speed.cc @@ -955,32 +955,6 @@ static bool SpeedHashToCurve(const std::string &selected) { static const uint8_t kLabel[] = "label"; TimeResults results; - { - EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1); - if (group == NULL) { - return false; - } - if (!TimeFunction(&results, [&]() -> bool { - EC_RAW_POINT out; - return ec_hash_to_curve_p521_xmd_sha512_sswu_draft06( - group, &out, kLabel, sizeof(kLabel), input, sizeof(input)); - })) { - fprintf(stderr, "hash-to-curve failed.\n"); - return false; - } - results.Print("hash-to-curve P521_XMD:SHA-512_SSWU_RO_"); - - if (!TimeFunction(&results, [&]() -> bool { - EC_SCALAR out; - return ec_hash_to_scalar_p521_xmd_sha512_draft06( - group, &out, kLabel, sizeof(kLabel), input, sizeof(input)); - })) { - fprintf(stderr, "hash-to-scalar failed.\n"); - return false; - } - results.Print("hash-to-scalar P521_XMD:SHA-512"); - } - { EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp384r1); if (group == NULL) { @@ -1375,10 +1349,6 @@ bool Speed(const std::vector &args) { !SpeedRSAKeyGen(selected) || !SpeedHRSS(selected) || !SpeedHashToCurve(selected) || - !SpeedTrustToken("TrustToken-Exp0-Batch1", TRUST_TOKEN_experiment_v0(), 1, - selected) || - !SpeedTrustToken("TrustToken-Exp0-Batch10", TRUST_TOKEN_experiment_v0(), - 10, selected) || !SpeedTrustToken("TrustToken-Exp1-Batch1", TRUST_TOKEN_experiment_v1(), 1, selected) || !SpeedTrustToken("TrustToken-Exp1-Batch10", TRUST_TOKEN_experiment_v1(),