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) {