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;
}