Add EC_RAW_POINT serialization function. This avoids some unnecessary EC_POINT allocations in the in-progress Trust Tokens implementation. Bug: chromium:1014199 Change-Id: I64e1fca61d111eacec02648e68972be30fd5a48f Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/40586 Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h index f98b1dd..2ac8b83 100644 --- a/crypto/fipsmodule/ec/internal.h +++ b/crypto/fipsmodule/ec/internal.h
@@ -276,6 +276,12 @@ uint8_t *out_y, size_t *out_len, size_t max_out, const EC_RAW_POINT *p); +// ec_point_to_bytes behaves like |EC_POINT_point2oct| but takes an +// |EC_RAW_POINT|. +size_t ec_point_to_bytes(const EC_GROUP *group, const EC_RAW_POINT *point, + point_conversion_form_t form, uint8_t *buf, + size_t len); + // Implementation details.
diff --git a/crypto/fipsmodule/ec/oct.c b/crypto/fipsmodule/ec/oct.c index 04b1f2c..e8a98a7 100644 --- a/crypto/fipsmodule/ec/oct.c +++ b/crypto/fipsmodule/ec/oct.c
@@ -73,10 +73,9 @@ #include "internal.h" -static size_t ec_GFp_simple_point2oct(const EC_GROUP *group, - const EC_RAW_POINT *point, - point_conversion_form_t form, - uint8_t *buf, size_t len) { +size_t ec_point_to_bytes(const EC_GROUP *group, const EC_RAW_POINT *point, + point_conversion_form_t form, uint8_t *buf, + size_t len) { if (form != POINT_CONVERSION_COMPRESSED && form != POINT_CONVERSION_UNCOMPRESSED) { OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM); @@ -226,7 +225,7 @@ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return ec_GFp_simple_point2oct(group, &point->raw, form, buf, len); + return ec_point_to_bytes(group, &point->raw, form, buf, len); } int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
diff --git a/crypto/trust_token/privacy_pass.c b/crypto/trust_token/privacy_pass.c index 84525ea..accb28a 100644 --- a/crypto/trust_token/privacy_pass.c +++ b/crypto/trust_token/privacy_pass.c
@@ -141,7 +141,7 @@ // |*out_pub| is set to the public half of the keypair. It returns one on // success and zero on failure. static int generate_keypair(EC_SCALAR *out_x, EC_SCALAR *out_y, - EC_POINT **out_pub, const EC_GROUP *group) { + EC_RAW_POINT *out_pub, const EC_GROUP *group) { EC_POINT *h = get_h(); if (h == NULL) { return 0; @@ -149,38 +149,46 @@ static const uint8_t kDefaultAdditionalData[32] = {0}; EC_RAW_POINT tmp1, tmp2; - EC_POINT *pub = EC_POINT_new(group); - if (pub == NULL || - !ec_random_nonzero_scalar(group, out_x, kDefaultAdditionalData) || + if (!ec_random_nonzero_scalar(group, out_x, kDefaultAdditionalData) || !ec_random_nonzero_scalar(group, out_y, kDefaultAdditionalData) || !ec_point_mul_scalar_base(group, &tmp1, out_x) || !ec_point_mul_scalar(group, &tmp2, &h->raw, out_y)) { EC_POINT_free(h); - EC_POINT_free(pub); OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } - group->meth->add(group, &pub->raw, &tmp1, &tmp2); - *out_pub = pub; + group->meth->add(group, out_pub, &tmp1, &tmp2); EC_POINT_free(h); return 1; } +static int point_to_cbb(CBB *out, const EC_GROUP *group, + const EC_RAW_POINT *point) { + size_t len = + ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0); + if (len == 0) { + return 0; + } + uint8_t *p; + return CBB_add_space(out, &p, len) && + ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, p, + len) == len; +} + 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) { int ok = 0; - EC_POINT *pub0 = NULL, *pub1 = NULL, *pubs = NULL; CBB cbb; CBB_zero(&cbb); - uint8_t *buf = NULL; EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1); if (group == NULL) { return 0; } + EC_RAW_POINT pub0, pub1, pubs; EC_SCALAR x0, y0, x1, y1, xs, ys; if (!generate_keypair(&x0, &y0, &pub0, group) || !generate_keypair(&x1, &y1, &pub1, group) || @@ -198,6 +206,7 @@ const EC_SCALAR *scalars[] = {&x0, &y0, &x1, &y1, &xs, &ys}; for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(scalars); i++) { + uint8_t *buf; if (!CBB_add_space(&cbb, &buf, scalar_len)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); goto err; @@ -214,14 +223,11 @@ if (!CBB_init_fixed(&cbb, out_pub_key, max_pub_key_len) || !CBB_add_u32(&cbb, id) || !CBB_add_u16_length_prefixed(&cbb, &pub_cbb) || - !EC_POINT_point2cbb(&pub_cbb, group, pub0, POINT_CONVERSION_UNCOMPRESSED, - NULL) || + !point_to_cbb(&pub_cbb, group, &pub0) || !CBB_add_u16_length_prefixed(&cbb, &pub_cbb) || - !EC_POINT_point2cbb(&pub_cbb, group, pub1, POINT_CONVERSION_UNCOMPRESSED, - NULL) || + !point_to_cbb(&pub_cbb, group, &pub1) || !CBB_add_u16_length_prefixed(&cbb, &pub_cbb) || - !EC_POINT_point2cbb(&pub_cbb, group, pubs, POINT_CONVERSION_UNCOMPRESSED, - NULL) || + !point_to_cbb(&pub_cbb, group, &pubs) || !CBB_finish(&cbb, NULL, out_pub_key_len)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); goto err; @@ -231,8 +237,5 @@ err: CBB_cleanup(&cbb); - EC_POINT_free(pub0); - EC_POINT_free(pub1); - EC_POINT_free(pubs); return ok; }