Introduce a TRUST_TOKEN_METHOD hook to select TRUST_TOKEN variations. For now, it does nothing. This will make it easier to transition between versions of the experiment while the protocol evolves. Update-Note: Pass TRUST_TOKEN_experiment_v0() into any existing code that now needs a TRUST_TOKEN_METHOD. Change-Id: I434e18c794ab30545e367eb902e434e6311b7497 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/41066 Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com>
diff --git a/crypto/trust_token/internal.h b/crypto/trust_token/internal.h index c9abf91..56c750a 100644 --- a/crypto/trust_token/internal.h +++ b/crypto/trust_token/internal.h
@@ -30,6 +30,8 @@ #endif +// PMBTokens. +// // PMBTokens is described in https://eprint.iacr.org/2020/072/20200324:214215 // and provides anonymous tokens with private metadata. We implement the // construction with validity verification, described in appendix H, @@ -130,6 +132,14 @@ size_t token_len); + +// Trust Tokens internals. + +struct trust_token_method_st { + // TODO(davidben): Add functions here to swap out the PMBTokens mechanism. + char empty; +}; + // Structure representing a single Trust Token public key with the specified ID. struct trust_token_client_key_st { uint32_t id; @@ -144,6 +154,8 @@ }; struct trust_token_client_st { + const TRUST_TOKEN_METHOD *method; + // max_batchsize is the maximum supported batchsize. uint16_t max_batchsize; @@ -163,6 +175,8 @@ struct trust_token_issuer_st { + const TRUST_TOKEN_METHOD *method; + // max_batchsize is the maximum supported batchsize. uint16_t max_batchsize;
diff --git a/crypto/trust_token/trust_token.c b/crypto/trust_token/trust_token.c index 260368a..f34b41b 100644 --- a/crypto/trust_token/trust_token.c +++ b/crypto/trust_token/trust_token.c
@@ -27,6 +27,11 @@ // 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 = {0}; + return &kMethod; +} + TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len) { TRUST_TOKEN *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN)); if (ret == NULL) { @@ -52,7 +57,8 @@ OPENSSL_free(token); } -int TRUST_TOKEN_generate_key(uint8_t *out_priv_key, size_t *out_priv_key_len, +int TRUST_TOKEN_generate_key(const TRUST_TOKEN_METHOD *method, + uint8_t *out_priv_key, size_t *out_priv_key_len, size_t max_priv_key_len, uint8_t *out_pub_key, size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id) { @@ -87,7 +93,8 @@ return ret; } -TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(size_t max_batchsize) { +TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD *method, + size_t max_batchsize) { if (max_batchsize > 0xffff) { // The protocol supports only two-byte token counts. OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); @@ -100,6 +107,7 @@ return NULL; } OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_CLIENT)); + ret->method = method; ret->max_batchsize = (uint16_t)max_batchsize; return ret; } @@ -300,7 +308,8 @@ return 1; } -TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(size_t max_batchsize) { +TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD *method, + size_t max_batchsize) { if (max_batchsize > 0xffff) { // The protocol supports only two-byte token counts. OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); @@ -313,6 +322,7 @@ return NULL; } OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_ISSUER)); + ret->method = method; ret->max_batchsize = (uint16_t)max_batchsize; return ret; } @@ -631,7 +641,8 @@ return ok; } -int TRUST_TOKEN_decode_private_metadata(uint8_t *out_value, const uint8_t *key, +int TRUST_TOKEN_decode_private_metadata(const TRUST_TOKEN_METHOD *method, + uint8_t *out_value, const uint8_t *key, size_t key_len, const uint8_t *client_data, size_t client_data_len,
diff --git a/crypto/trust_token/trust_token_test.cc b/crypto/trust_token/trust_token_test.cc index e312dc8..cf9ad7e 100644 --- a/crypto/trust_token/trust_token_test.cc +++ b/crypto/trust_token/trust_token_test.cc
@@ -45,8 +45,9 @@ uint8_t pub_key[TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE]; size_t priv_key_len, pub_key_len; ASSERT_TRUE(TRUST_TOKEN_generate_key( - priv_key, &priv_key_len, TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, pub_key, - &pub_key_len, TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0x0001)); + 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); } @@ -59,11 +60,16 @@ return 7 + i; } + // TODO(davidben): Parameterize this on the Trust Tokens method. + static const TRUST_TOKEN_METHOD *method() { + return TRUST_TOKEN_experiment_v0(); + } + protected: void SetupContexts() { - client.reset(TRUST_TOKEN_CLIENT_new(client_max_batchsize)); + client.reset(TRUST_TOKEN_CLIENT_new(method(), client_max_batchsize)); ASSERT_TRUE(client); - issuer.reset(TRUST_TOKEN_ISSUER_new(issuer_max_batchsize)); + issuer.reset(TRUST_TOKEN_ISSUER_new(method(), issuer_max_batchsize)); ASSERT_TRUE(issuer); for (size_t i = 0; i < 3; i++) { @@ -71,8 +77,8 @@ uint8_t pub_key[TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE]; size_t priv_key_len, pub_key_len, key_index; ASSERT_TRUE(TRUST_TOKEN_generate_key( - priv_key, &priv_key_len, TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, pub_key, - &pub_key_len, TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, KeyID(i))); + method(), priv_key, &priv_key_len, TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, + pub_key, &pub_key_len, TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, KeyID(i))); ASSERT_TRUE(TRUST_TOKEN_CLIENT_add_key(client.get(), &key_index, pub_key, pub_key_len)); ASSERT_EQ(i, key_index); @@ -302,9 +308,9 @@ } TEST_F(TrustTokenProtocolTest, IssuedWithBadKeyID) { - client.reset(TRUST_TOKEN_CLIENT_new(client_max_batchsize)); + client.reset(TRUST_TOKEN_CLIENT_new(method(), client_max_batchsize)); ASSERT_TRUE(client); - issuer.reset(TRUST_TOKEN_ISSUER_new(issuer_max_batchsize)); + issuer.reset(TRUST_TOKEN_ISSUER_new(method(), issuer_max_batchsize)); ASSERT_TRUE(issuer); // We configure the client and the issuer with different key IDs and test @@ -316,15 +322,15 @@ uint8_t pub_key[TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE]; size_t priv_key_len, pub_key_len, key_index; ASSERT_TRUE(TRUST_TOKEN_generate_key( - priv_key, &priv_key_len, TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, pub_key, - &pub_key_len, TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, kClientKeyID)); + method(), priv_key, &priv_key_len, TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, + pub_key, &pub_key_len, TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, kClientKeyID)); ASSERT_TRUE(TRUST_TOKEN_CLIENT_add_key(client.get(), &key_index, pub_key, pub_key_len)); ASSERT_EQ(0UL, key_index); ASSERT_TRUE(TRUST_TOKEN_generate_key( - priv_key, &priv_key_len, TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, pub_key, - &pub_key_len, TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, kIssuerKeyID)); + method(), priv_key, &priv_key_len, TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, + pub_key, &pub_key_len, TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, kIssuerKeyID)); ASSERT_TRUE(TRUST_TOKEN_ISSUER_add_key(issuer.get(), priv_key, priv_key_len)); @@ -423,8 +429,8 @@ uint8_t private_metadata; ASSERT_TRUE(TRUST_TOKEN_decode_private_metadata( - &private_metadata, metadata_key, sizeof(metadata_key), kClientData, - sizeof(kClientData) - 1, srr[27])); + method(), &private_metadata, metadata_key, sizeof(metadata_key), + kClientData, sizeof(kClientData) - 1, srr[27])); ASSERT_EQ(srr[18], std::get<0>(GetParam())); ASSERT_EQ(private_metadata, std::get<1>(GetParam()));
diff --git a/include/openssl/base.h b/include/openssl/base.h index 7218967..7f6acce 100644 --- a/include/openssl/base.h +++ b/include/openssl/base.h
@@ -425,6 +425,7 @@ typedef struct trust_token_st TRUST_TOKEN; typedef struct trust_token_client_st TRUST_TOKEN_CLIENT; typedef struct trust_token_issuer_st TRUST_TOKEN_ISSUER; +typedef struct trust_token_method_st TRUST_TOKEN_METHOD; typedef struct v3_ext_ctx X509V3_CTX; typedef struct x509_attributes_st X509_ATTRIBUTE; typedef struct x509_cert_aux_st X509_CERT_AUX;
diff --git a/include/openssl/trust_token.h b/include/openssl/trust_token.h index 008857e..e5837cf 100644 --- a/include/openssl/trust_token.h +++ b/include/openssl/trust_token.h
@@ -36,6 +36,10 @@ // // 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_st represents a single-use token for the Trust Token protocol. // For the client, this is the token and its corresponding signature. For the // issuer, this is the token itself. @@ -71,9 +75,9 @@ // // This function returns one on success or zero on error. OPENSSL_EXPORT int TRUST_TOKEN_generate_key( - uint8_t *out_priv_key, size_t *out_priv_key_len, size_t max_priv_key_len, - uint8_t *out_pub_key, size_t *out_pub_key_len, size_t max_pub_key_len, - uint32_t id); + const TRUST_TOKEN_METHOD *method, uint8_t *out_priv_key, + size_t *out_priv_key_len, size_t max_priv_key_len, uint8_t *out_pub_key, + size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id); // Trust Token client implementation. @@ -86,7 +90,8 @@ // Issuance requests must be made in batches smaller than |max_batchsize|. This // function will return an error if |max_batchsize| is too large for Trust // Tokens. -OPENSSL_EXPORT TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(size_t max_batchsize); +OPENSSL_EXPORT TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new( + const TRUST_TOKEN_METHOD *method, size_t max_batchsize); // TRUST_TOKEN_CLIENT_free releases memory associated with |ctx|. OPENSSL_EXPORT void TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT *ctx); @@ -166,7 +171,8 @@ // Issuance requests must be made in batches smaller than |max_batchsize|. This // function will return an error if |max_batchsize| is too large for Trust // Tokens. -OPENSSL_EXPORT TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(size_t max_batchsize); +OPENSSL_EXPORT TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new( + const TRUST_TOKEN_METHOD *method, size_t max_batchsize); // TRUST_TOKEN_ISSUER_free releases memory associated with |ctx|. OPENSSL_EXPORT void TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER *ctx); @@ -240,8 +246,9 @@ // |*out_value is set to the decrypted value, either zero or one. It returns one // on success and zero on error. OPENSSL_EXPORT int TRUST_TOKEN_decode_private_metadata( - uint8_t *out_value, const uint8_t *key, size_t key_len, - const uint8_t *client_data, size_t client_data_len, uint8_t encrypted_bit); + const TRUST_TOKEN_METHOD *method, uint8_t *out_value, const uint8_t *key, + size_t key_len, const uint8_t *client_data, size_t client_data_len, + uint8_t encrypted_bit); #if defined(__cplusplus) @@ -255,7 +262,6 @@ BORINGSSL_MAKE_DELETER(TRUST_TOKEN_CLIENT, TRUST_TOKEN_CLIENT_free) BORINGSSL_MAKE_DELETER(TRUST_TOKEN_ISSUER, TRUST_TOKEN_ISSUER_free) - BSSL_NAMESPACE_END } // extern C++
diff --git a/tool/speed.cc b/tool/speed.cc index b1f530d..ac71043 100644 --- a/tool/speed.cc +++ b/tool/speed.cc
@@ -1019,8 +1019,8 @@ return out; } -static bool SpeedTrustToken(std::string name, size_t batchsize, - const std::string &selected) { +static bool SpeedTrustToken(std::string name, const TRUST_TOKEN_METHOD *method, + size_t batchsize, const std::string &selected) { if (!selected.empty() && selected.find("trusttoken") == std::string::npos) { return true; } @@ -1031,24 +1031,25 @@ uint8_t pub_key[TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE]; size_t priv_key_len, pub_key_len; return TRUST_TOKEN_generate_key( - priv_key, &priv_key_len, TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, pub_key, - &pub_key_len, TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0); + method, priv_key, &priv_key_len, TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, + pub_key, &pub_key_len, TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0); })) { fprintf(stderr, "TRUST_TOKEN_generate_key failed.\n"); return false; } results.Print(name + " generate_key"); - bssl::UniquePtr<TRUST_TOKEN_CLIENT> client(TRUST_TOKEN_CLIENT_new(batchsize)); - bssl::UniquePtr<TRUST_TOKEN_ISSUER> issuer(TRUST_TOKEN_ISSUER_new(batchsize)); + bssl::UniquePtr<TRUST_TOKEN_CLIENT> client( + TRUST_TOKEN_CLIENT_new(method, batchsize)); + bssl::UniquePtr<TRUST_TOKEN_ISSUER> issuer( + TRUST_TOKEN_ISSUER_new(method, batchsize)); 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, key_index; - if (!client || - !issuer || + if (!client || !issuer || !TRUST_TOKEN_generate_key( - priv_key, &priv_key_len, TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, pub_key, - &pub_key_len, TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0) || + method, priv_key, &priv_key_len, TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, + pub_key, &pub_key_len, TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0) || !TRUST_TOKEN_CLIENT_add_key(client.get(), &key_index, pub_key, pub_key_len) || !TRUST_TOKEN_ISSUER_add_key(issuer.get(), priv_key, priv_key_len)) { @@ -1374,8 +1375,10 @@ !SpeedRSAKeyGen(selected) || !SpeedHRSS(selected) || !SpeedHashToCurve(selected) || - !SpeedTrustToken("TrustToken-Batch1", 1, selected) || - !SpeedTrustToken("TrustToken-Batch10", 10, selected)) { + !SpeedTrustToken("TrustToken-Exp0-Batch1", TRUST_TOKEN_experiment_v0(), 1, + selected) || + !SpeedTrustToken("TrustToken-Exp0-Batch10", TRUST_TOKEN_experiment_v0(), + 10, selected)) { return false; } if (g_print_json) {