1 /* Copyright (c) 2020, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15 #include <openssl/trust_token.h>
16
17 #include <openssl/bn.h>
18 #include <openssl/bytestring.h>
19 #include <openssl/ec.h>
20 #include <openssl/err.h>
21 #include <openssl/mem.h>
22 #include <openssl/nid.h>
23 #include <openssl/rand.h>
24 #include <openssl/sha.h>
25
26 #include "../ec_extra/internal.h"
27 #include "../fipsmodule/ec/internal.h"
28
29 #include "internal.h"
30
31
32 typedef int (*hash_to_group_func_t)(const EC_GROUP *group, EC_JACOBIAN *out,
33 const uint8_t t[TRUST_TOKEN_NONCE_SIZE]);
34 typedef int (*hash_to_scalar_func_t)(const EC_GROUP *group, EC_SCALAR *out,
35 uint8_t *buf, size_t len);
36
37 typedef struct {
38 const EC_GROUP *(*group_func)(void);
39
40 // hash_to_group implements the HashToGroup operation for VOPRFs. It returns
41 // one on success and zero on error.
42 hash_to_group_func_t hash_to_group;
43 // hash_to_scalar implements the HashToScalar operation for VOPRFs. It returns
44 // one on success and zero on error.
45 hash_to_scalar_func_t hash_to_scalar;
46 } VOPRF_METHOD;
47
48 static const uint8_t kDefaultAdditionalData[32] = {0};
49
cbb_add_point(CBB * out,const EC_GROUP * group,const EC_AFFINE * point)50 static int cbb_add_point(CBB *out, const EC_GROUP *group,
51 const EC_AFFINE *point) {
52 uint8_t *p;
53 size_t len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
54 return CBB_add_space(out, &p, len) &&
55 ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, p,
56 len) == len &&
57 CBB_flush(out);
58 }
59
cbb_serialize_point(CBB * out,const EC_GROUP * group,const EC_AFFINE * point)60 static int cbb_serialize_point(CBB *out, const EC_GROUP *group,
61 const EC_AFFINE *point) {
62 uint8_t *p;
63 size_t len = ec_point_byte_len(group, POINT_CONVERSION_COMPRESSED);
64 return CBB_add_u16(out, len) && CBB_add_space(out, &p, len) &&
65 ec_point_to_bytes(group, point, POINT_CONVERSION_COMPRESSED, p, len) ==
66 len &&
67 CBB_flush(out);
68 }
69
cbs_get_point(CBS * cbs,const EC_GROUP * group,EC_AFFINE * out)70 static int cbs_get_point(CBS *cbs, const EC_GROUP *group, EC_AFFINE *out) {
71 CBS child;
72 size_t plen = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
73 if (!CBS_get_bytes(cbs, &child, plen) ||
74 !ec_point_from_uncompressed(group, out, CBS_data(&child),
75 CBS_len(&child))) {
76 return 0;
77 }
78 return 1;
79 }
80
scalar_to_cbb(CBB * out,const EC_GROUP * group,const EC_SCALAR * scalar)81 static int scalar_to_cbb(CBB *out, const EC_GROUP *group,
82 const EC_SCALAR *scalar) {
83 uint8_t *buf;
84 size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group));
85 if (!CBB_add_space(out, &buf, scalar_len)) {
86 return 0;
87 }
88 ec_scalar_to_bytes(group, buf, &scalar_len, scalar);
89 return 1;
90 }
91
scalar_from_cbs(CBS * cbs,const EC_GROUP * group,EC_SCALAR * out)92 static int scalar_from_cbs(CBS *cbs, const EC_GROUP *group, EC_SCALAR *out) {
93 size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group));
94 CBS tmp;
95 if (!CBS_get_bytes(cbs, &tmp, scalar_len)) {
96 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
97 return 0;
98 }
99
100 ec_scalar_from_bytes(group, out, CBS_data(&tmp), CBS_len(&tmp));
101 return 1;
102 }
103
voprf_calculate_key(const VOPRF_METHOD * method,CBB * out_private,CBB * out_public,const EC_SCALAR * priv)104 static int voprf_calculate_key(const VOPRF_METHOD *method, CBB *out_private,
105 CBB *out_public, const EC_SCALAR *priv) {
106 const EC_GROUP *group = method->group_func();
107 EC_JACOBIAN pub;
108 EC_AFFINE pub_affine;
109 if (!ec_point_mul_scalar_base(group, &pub, priv) ||
110 !ec_jacobian_to_affine(group, &pub_affine, &pub)) {
111 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE);
112 return 0;
113 }
114
115 if (!scalar_to_cbb(out_private, group, priv) ||
116 !cbb_add_point(out_public, group, &pub_affine)) {
117 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
118 return 0;
119 }
120
121 return 1;
122 }
123
124
voprf_generate_key(const VOPRF_METHOD * method,CBB * out_private,CBB * out_public)125 static int voprf_generate_key(const VOPRF_METHOD *method, CBB *out_private,
126 CBB *out_public) {
127 EC_SCALAR priv;
128 if (!ec_random_nonzero_scalar(method->group_func(), &priv,
129 kDefaultAdditionalData)) {
130 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE);
131 return 0;
132 }
133 return voprf_calculate_key(method, out_private, out_public, &priv);
134 }
135
voprf_derive_key_from_secret(const VOPRF_METHOD * method,CBB * out_private,CBB * out_public,const uint8_t * secret,size_t secret_len)136 static int voprf_derive_key_from_secret(const VOPRF_METHOD *method,
137 CBB *out_private, CBB *out_public,
138 const uint8_t *secret,
139 size_t secret_len) {
140 static const uint8_t kKeygenLabel[] = "TrustTokenVOPRFKeyGen";
141
142 EC_SCALAR priv;
143 int ok = 0;
144 CBB cbb;
145 CBB_zero(&cbb);
146 uint8_t *buf = NULL;
147 size_t len;
148 if (!CBB_init(&cbb, 0) ||
149 !CBB_add_bytes(&cbb, kKeygenLabel, sizeof(kKeygenLabel)) ||
150 !CBB_add_bytes(&cbb, secret, secret_len) ||
151 !CBB_finish(&cbb, &buf, &len) ||
152 !method->hash_to_scalar(method->group_func(), &priv, buf, len)) {
153 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE);
154 goto err;
155 }
156
157 ok = voprf_calculate_key(method, out_private, out_public, &priv);
158
159 err:
160 CBB_cleanup(&cbb);
161 OPENSSL_free(buf);
162 return ok;
163 }
164
voprf_client_key_from_bytes(const VOPRF_METHOD * method,TRUST_TOKEN_CLIENT_KEY * key,const uint8_t * in,size_t len)165 static int voprf_client_key_from_bytes(const VOPRF_METHOD *method,
166 TRUST_TOKEN_CLIENT_KEY *key,
167 const uint8_t *in, size_t len) {
168 const EC_GROUP *group = method->group_func();
169 if (!ec_point_from_uncompressed(group, &key->pubs, in, len)) {
170 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
171 return 0;
172 }
173
174 return 1;
175 }
176
voprf_issuer_key_from_bytes(const VOPRF_METHOD * method,TRUST_TOKEN_ISSUER_KEY * key,const uint8_t * in,size_t len)177 static int voprf_issuer_key_from_bytes(const VOPRF_METHOD *method,
178 TRUST_TOKEN_ISSUER_KEY *key,
179 const uint8_t *in, size_t len) {
180 const EC_GROUP *group = method->group_func();
181 if (!ec_scalar_from_bytes(group, &key->xs, in, len)) {
182 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
183 return 0;
184 }
185
186 // Recompute the public key.
187 EC_JACOBIAN pub;
188 if (!ec_point_mul_scalar_base(group, &pub, &key->xs) ||
189 !ec_jacobian_to_affine(group, &key->pubs, &pub)) {
190 return 0;
191 }
192
193 return 1;
194 }
195
STACK_OF(TRUST_TOKEN_PRETOKEN)196 static STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_blind(const VOPRF_METHOD *method,
197 CBB *cbb, size_t count,
198 int include_message,
199 const uint8_t *msg,
200 size_t msg_len) {
201 SHA512_CTX hash_ctx;
202
203 const EC_GROUP *group = method->group_func();
204 STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens =
205 sk_TRUST_TOKEN_PRETOKEN_new_null();
206 if (pretokens == NULL) {
207 goto err;
208 }
209
210 for (size_t i = 0; i < count; i++) {
211 // Insert |pretoken| into |pretokens| early to simplify error-handling.
212 TRUST_TOKEN_PRETOKEN *pretoken =
213 OPENSSL_malloc(sizeof(TRUST_TOKEN_PRETOKEN));
214 if (pretoken == NULL ||
215 !sk_TRUST_TOKEN_PRETOKEN_push(pretokens, pretoken)) {
216 TRUST_TOKEN_PRETOKEN_free(pretoken);
217 goto err;
218 }
219
220 RAND_bytes(pretoken->salt, sizeof(pretoken->salt));
221 if (include_message) {
222 assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE);
223 SHA512_Init(&hash_ctx);
224 SHA512_Update(&hash_ctx, pretoken->salt, sizeof(pretoken->salt));
225 SHA512_Update(&hash_ctx, msg, msg_len);
226 SHA512_Final(pretoken->t, &hash_ctx);
227 } else {
228 OPENSSL_memcpy(pretoken->t, pretoken->salt, TRUST_TOKEN_NONCE_SIZE);
229 }
230
231 // We sample r in Montgomery form to simplify inverting.
232 EC_SCALAR r;
233 if (!ec_random_nonzero_scalar(group, &r,
234 kDefaultAdditionalData)) {
235 goto err;
236 }
237
238 // pretoken->r is rinv.
239 ec_scalar_inv0_montgomery(group, &pretoken->r, &r);
240 // Convert both out of Montgomery form.
241 ec_scalar_from_montgomery(group, &r, &r);
242 ec_scalar_from_montgomery(group, &pretoken->r, &pretoken->r);
243
244 // Tp is the blinded token in the VOPRF protocol.
245 EC_JACOBIAN P, Tp;
246 if (!method->hash_to_group(group, &P, pretoken->t) ||
247 !ec_point_mul_scalar(group, &Tp, &P, &r) ||
248 !ec_jacobian_to_affine(group, &pretoken->Tp, &Tp)) {
249 goto err;
250 }
251
252 if (!cbb_add_point(cbb, group, &pretoken->Tp)) {
253 goto err;
254 }
255 }
256
257 return pretokens;
258
259 err:
260 sk_TRUST_TOKEN_PRETOKEN_pop_free(pretokens, TRUST_TOKEN_PRETOKEN_free);
261 return NULL;
262 }
263
hash_to_scalar_dleq(const VOPRF_METHOD * method,EC_SCALAR * out,const EC_AFFINE * X,const EC_AFFINE * T,const EC_AFFINE * W,const EC_AFFINE * K0,const EC_AFFINE * K1)264 static int hash_to_scalar_dleq(const VOPRF_METHOD *method, EC_SCALAR *out,
265 const EC_AFFINE *X, const EC_AFFINE *T,
266 const EC_AFFINE *W, const EC_AFFINE *K0,
267 const EC_AFFINE *K1) {
268 static const uint8_t kDLEQLabel[] = "DLEQ";
269
270 const EC_GROUP *group = method->group_func();
271 int ok = 0;
272 CBB cbb;
273 CBB_zero(&cbb);
274 uint8_t *buf = NULL;
275 size_t len;
276 if (!CBB_init(&cbb, 0) ||
277 !CBB_add_bytes(&cbb, kDLEQLabel, sizeof(kDLEQLabel)) ||
278 !cbb_add_point(&cbb, group, X) ||
279 !cbb_add_point(&cbb, group, T) ||
280 !cbb_add_point(&cbb, group, W) ||
281 !cbb_add_point(&cbb, group, K0) ||
282 !cbb_add_point(&cbb, group, K1) ||
283 !CBB_finish(&cbb, &buf, &len) ||
284 !method->hash_to_scalar(group, out, buf, len)) {
285 goto err;
286 }
287
288 ok = 1;
289
290 err:
291 CBB_cleanup(&cbb);
292 OPENSSL_free(buf);
293 return ok;
294 }
295
hash_to_scalar_challenge(const VOPRF_METHOD * method,EC_SCALAR * out,const EC_AFFINE * Bm,const EC_AFFINE * a0,const EC_AFFINE * a1,const EC_AFFINE * a2,const EC_AFFINE * a3)296 static int hash_to_scalar_challenge(const VOPRF_METHOD *method, EC_SCALAR *out,
297 const EC_AFFINE *Bm, const EC_AFFINE *a0,
298 const EC_AFFINE *a1, const EC_AFFINE *a2,
299 const EC_AFFINE *a3) {
300 static const uint8_t kChallengeLabel[] = "Challenge";
301
302 const EC_GROUP *group = method->group_func();
303 CBB cbb;
304 uint8_t transcript[5 * EC_MAX_COMPRESSED + 2 + sizeof(kChallengeLabel) - 1];
305 size_t len;
306 if (!CBB_init_fixed(&cbb, transcript, sizeof(transcript)) ||
307 !cbb_serialize_point(&cbb, group, Bm) ||
308 !cbb_serialize_point(&cbb, group, a0) ||
309 !cbb_serialize_point(&cbb, group, a1) ||
310 !cbb_serialize_point(&cbb, group, a2) ||
311 !cbb_serialize_point(&cbb, group, a3) ||
312 !CBB_add_bytes(&cbb, kChallengeLabel, sizeof(kChallengeLabel) - 1) ||
313 !CBB_finish(&cbb, NULL, &len) ||
314 !method->hash_to_scalar(group, out, transcript, len)) {
315 return 0;
316 }
317
318 return 1;
319 }
320
hash_to_scalar_batch(const VOPRF_METHOD * method,EC_SCALAR * out,const CBB * points,size_t index)321 static int hash_to_scalar_batch(const VOPRF_METHOD *method, EC_SCALAR *out,
322 const CBB *points, size_t index) {
323 static const uint8_t kDLEQBatchLabel[] = "DLEQ BATCH";
324 if (index > 0xffff) {
325 // The protocol supports only two-byte batches.
326 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
327 return 0;
328 }
329
330 int ok = 0;
331 CBB cbb;
332 CBB_zero(&cbb);
333 uint8_t *buf = NULL;
334 size_t len;
335 if (!CBB_init(&cbb, 0) ||
336 !CBB_add_bytes(&cbb, kDLEQBatchLabel, sizeof(kDLEQBatchLabel)) ||
337 !CBB_add_bytes(&cbb, CBB_data(points), CBB_len(points)) ||
338 !CBB_add_u16(&cbb, (uint16_t)index) ||
339 !CBB_finish(&cbb, &buf, &len) ||
340 !method->hash_to_scalar(method->group_func(), out, buf, len)) {
341 goto err;
342 }
343
344 ok = 1;
345
346 err:
347 CBB_cleanup(&cbb);
348 OPENSSL_free(buf);
349 return ok;
350 }
351
dleq_generate(const VOPRF_METHOD * method,CBB * cbb,const TRUST_TOKEN_ISSUER_KEY * priv,const EC_JACOBIAN * T,const EC_JACOBIAN * W)352 static int dleq_generate(const VOPRF_METHOD *method, CBB *cbb,
353 const TRUST_TOKEN_ISSUER_KEY *priv,
354 const EC_JACOBIAN *T, const EC_JACOBIAN *W) {
355 const EC_GROUP *group = method->group_func();
356
357 enum {
358 idx_T,
359 idx_W,
360 idx_k0,
361 idx_k1,
362 num_idx,
363 };
364 EC_JACOBIAN jacobians[num_idx];
365
366 // Setup the DLEQ proof.
367 EC_SCALAR r;
368 if (// r <- Zp
369 !ec_random_nonzero_scalar(group, &r, kDefaultAdditionalData) ||
370 // k0;k1 = r*(G;T)
371 !ec_point_mul_scalar_base(group, &jacobians[idx_k0], &r) ||
372 !ec_point_mul_scalar(group, &jacobians[idx_k1], T, &r)) {
373 return 0;
374 }
375
376 EC_AFFINE affines[num_idx];
377 jacobians[idx_T] = *T;
378 jacobians[idx_W] = *W;
379 if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) {
380 return 0;
381 }
382
383 // Compute c = Hc(...).
384 EC_SCALAR c;
385 if (!hash_to_scalar_dleq(method, &c, &priv->pubs, &affines[idx_T],
386 &affines[idx_W], &affines[idx_k0],
387 &affines[idx_k1])) {
388 return 0;
389 }
390
391
392 EC_SCALAR c_mont;
393 ec_scalar_to_montgomery(group, &c_mont, &c);
394
395 // u = r + c*xs
396 EC_SCALAR u;
397 ec_scalar_mul_montgomery(group, &u, &priv->xs, &c_mont);
398 ec_scalar_add(group, &u, &r, &u);
399
400 // Store DLEQ proof in transcript.
401 if (!scalar_to_cbb(cbb, group, &c) ||
402 !scalar_to_cbb(cbb, group, &u)) {
403 return 0;
404 }
405
406 return 1;
407 }
408
mul_public_2(const EC_GROUP * group,EC_JACOBIAN * out,const EC_JACOBIAN * p0,const EC_SCALAR * scalar0,const EC_JACOBIAN * p1,const EC_SCALAR * scalar1)409 static int mul_public_2(const EC_GROUP *group, EC_JACOBIAN *out,
410 const EC_JACOBIAN *p0, const EC_SCALAR *scalar0,
411 const EC_JACOBIAN *p1, const EC_SCALAR *scalar1) {
412 EC_JACOBIAN points[2] = {*p0, *p1};
413 EC_SCALAR scalars[2] = {*scalar0, *scalar1};
414 return ec_point_mul_scalar_public_batch(group, out, /*g_scalar=*/NULL, points,
415 scalars, 2);
416 }
417
dleq_verify(const VOPRF_METHOD * method,CBS * cbs,const TRUST_TOKEN_CLIENT_KEY * pub,const EC_JACOBIAN * T,const EC_JACOBIAN * W)418 static int dleq_verify(const VOPRF_METHOD *method, CBS *cbs,
419 const TRUST_TOKEN_CLIENT_KEY *pub, const EC_JACOBIAN *T,
420 const EC_JACOBIAN *W) {
421 const EC_GROUP *group = method->group_func();
422
423
424 enum {
425 idx_T,
426 idx_W,
427 idx_k0,
428 idx_k1,
429 num_idx,
430 };
431 EC_JACOBIAN jacobians[num_idx];
432
433 // Decode the DLEQ proof.
434 EC_SCALAR c, u;
435 if (!scalar_from_cbs(cbs, group, &c) ||
436 !scalar_from_cbs(cbs, group, &u)) {
437 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
438 return 0;
439 }
440
441 // k0;k1 = u*(G;T) - c*(pub;W)
442 EC_JACOBIAN pubs;
443 ec_affine_to_jacobian(group, &pubs, &pub->pubs);
444 EC_SCALAR minus_c;
445 ec_scalar_neg(group, &minus_c, &c);
446 if (!ec_point_mul_scalar_public(group, &jacobians[idx_k0], &u, &pubs,
447 &minus_c) ||
448 !mul_public_2(group, &jacobians[idx_k1], T, &u, W, &minus_c)) {
449 return 0;
450 }
451
452 // Check the DLEQ proof.
453 EC_AFFINE affines[num_idx];
454 jacobians[idx_T] = *T;
455 jacobians[idx_W] = *W;
456 if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) {
457 return 0;
458 }
459
460 // Compute c = Hc(...).
461 EC_SCALAR calculated;
462 if (!hash_to_scalar_dleq(method, &calculated, &pub->pubs, &affines[idx_T],
463 &affines[idx_W], &affines[idx_k0],
464 &affines[idx_k1])) {
465 return 0;
466 }
467
468 // c == calculated
469 if (!ec_scalar_equal_vartime(group, &c, &calculated)) {
470 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_PROOF);
471 return 0;
472 }
473
474 return 1;
475 }
476
voprf_sign_tt(const VOPRF_METHOD * method,const TRUST_TOKEN_ISSUER_KEY * key,CBB * cbb,CBS * cbs,size_t num_requested,size_t num_to_issue)477 static int voprf_sign_tt(const VOPRF_METHOD *method,
478 const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
479 size_t num_requested, size_t num_to_issue) {
480 const EC_GROUP *group = method->group_func();
481 if (num_requested < num_to_issue) {
482 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
483 return 0;
484 }
485
486 int ret = 0;
487 EC_JACOBIAN *BTs = OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN));
488 EC_JACOBIAN *Zs = OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN));
489 EC_SCALAR *es = OPENSSL_calloc(num_to_issue, sizeof(EC_SCALAR));
490 CBB batch_cbb;
491 CBB_zero(&batch_cbb);
492 if (!BTs ||
493 !Zs ||
494 !es ||
495 !CBB_init(&batch_cbb, 0) ||
496 !cbb_add_point(&batch_cbb, group, &key->pubs)) {
497 goto err;
498 }
499
500 for (size_t i = 0; i < num_to_issue; i++) {
501 EC_AFFINE BT_affine, Z_affine;
502 EC_JACOBIAN BT, Z;
503 if (!cbs_get_point(cbs, group, &BT_affine)) {
504 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
505 goto err;
506 }
507 ec_affine_to_jacobian(group, &BT, &BT_affine);
508 if (!ec_point_mul_scalar(group, &Z, &BT, &key->xs) ||
509 !ec_jacobian_to_affine(group, &Z_affine, &Z) ||
510 !cbb_add_point(cbb, group, &Z_affine)) {
511 goto err;
512 }
513
514 if (!cbb_add_point(&batch_cbb, group, &BT_affine) ||
515 !cbb_add_point(&batch_cbb, group, &Z_affine)) {
516 goto err;
517 }
518 BTs[i] = BT;
519 Zs[i] = Z;
520
521 if (!CBB_flush(cbb)) {
522 goto err;
523 }
524 }
525
526 // The DLEQ batching construction is described in appendix B of
527 // https://eprint.iacr.org/2020/072/20200324:214215. Note the additional
528 // computations all act on public inputs.
529 for (size_t i = 0; i < num_to_issue; i++) {
530 if (!hash_to_scalar_batch(method, &es[i], &batch_cbb, i)) {
531 goto err;
532 }
533 }
534
535 EC_JACOBIAN BT_batch, Z_batch;
536 if (!ec_point_mul_scalar_public_batch(group, &BT_batch,
537 /*g_scalar=*/NULL, BTs, es,
538 num_to_issue) ||
539 !ec_point_mul_scalar_public_batch(group, &Z_batch,
540 /*g_scalar=*/NULL, Zs, es,
541 num_to_issue)) {
542 goto err;
543 }
544
545 CBB proof;
546 if (!CBB_add_u16_length_prefixed(cbb, &proof) ||
547 !dleq_generate(method, &proof, key, &BT_batch, &Z_batch) ||
548 !CBB_flush(cbb)) {
549 goto err;
550 }
551
552 // Skip over any unused requests.
553 size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
554 if (!CBS_skip(cbs, point_len * (num_requested - num_to_issue))) {
555 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
556 goto err;
557 }
558
559 ret = 1;
560
561 err:
562 OPENSSL_free(BTs);
563 OPENSSL_free(Zs);
564 OPENSSL_free(es);
565 CBB_cleanup(&batch_cbb);
566 return ret;
567 }
568
STACK_OF(TRUST_TOKEN)569 static STACK_OF(TRUST_TOKEN) *voprf_unblind_tt(
570 const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key,
571 const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
572 uint32_t key_id) {
573 const EC_GROUP *group = method->group_func();
574 if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) {
575 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
576 return NULL;
577 }
578
579 int ok = 0;
580 STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null();
581 EC_JACOBIAN *BTs = OPENSSL_calloc(count, sizeof(EC_JACOBIAN));
582 EC_JACOBIAN *Zs = OPENSSL_calloc(count, sizeof(EC_JACOBIAN));
583 EC_SCALAR *es = OPENSSL_calloc(count, sizeof(EC_SCALAR));
584 CBB batch_cbb;
585 CBB_zero(&batch_cbb);
586 if (ret == NULL ||
587 BTs == NULL ||
588 Zs == NULL ||
589 es == NULL ||
590 !CBB_init(&batch_cbb, 0) ||
591 !cbb_add_point(&batch_cbb, group, &key->pubs)) {
592 goto err;
593 }
594
595 for (size_t i = 0; i < count; i++) {
596 const TRUST_TOKEN_PRETOKEN *pretoken =
597 sk_TRUST_TOKEN_PRETOKEN_value(pretokens, i);
598
599 EC_AFFINE Z_affine;
600 if (!cbs_get_point(cbs, group, &Z_affine)) {
601 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
602 goto err;
603 }
604
605 ec_affine_to_jacobian(group, &BTs[i], &pretoken->Tp);
606 ec_affine_to_jacobian(group, &Zs[i], &Z_affine);
607
608 if (!cbb_add_point(&batch_cbb, group, &pretoken->Tp) ||
609 !cbb_add_point(&batch_cbb, group, &Z_affine)) {
610 goto err;
611 }
612
613 // Unblind the token.
614 // pretoken->r is rinv.
615 EC_JACOBIAN N;
616 EC_AFFINE N_affine;
617 if (!ec_point_mul_scalar(group, &N, &Zs[i], &pretoken->r) ||
618 !ec_jacobian_to_affine(group, &N_affine, &N)) {
619 goto err;
620 }
621
622 // Serialize the token. Include |key_id| to avoid an extra copy in the layer
623 // above.
624 CBB token_cbb;
625 size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
626 if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + (2 + point_len)) ||
627 !CBB_add_u32(&token_cbb, key_id) ||
628 !CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) ||
629 !cbb_add_point(&token_cbb, group, &N_affine) ||
630 !CBB_flush(&token_cbb)) {
631 CBB_cleanup(&token_cbb);
632 goto err;
633 }
634
635 TRUST_TOKEN *token =
636 TRUST_TOKEN_new(CBB_data(&token_cbb), CBB_len(&token_cbb));
637 CBB_cleanup(&token_cbb);
638 if (token == NULL ||
639 !sk_TRUST_TOKEN_push(ret, token)) {
640 TRUST_TOKEN_free(token);
641 goto err;
642 }
643 }
644
645 // The DLEQ batching construction is described in appendix B of
646 // https://eprint.iacr.org/2020/072/20200324:214215. Note the additional
647 // computations all act on public inputs.
648 for (size_t i = 0; i < count; i++) {
649 if (!hash_to_scalar_batch(method, &es[i], &batch_cbb, i)) {
650 goto err;
651 }
652 }
653
654 EC_JACOBIAN BT_batch, Z_batch;
655 if (!ec_point_mul_scalar_public_batch(group, &BT_batch,
656 /*g_scalar=*/NULL, BTs, es, count) ||
657 !ec_point_mul_scalar_public_batch(group, &Z_batch,
658 /*g_scalar=*/NULL, Zs, es, count)) {
659 goto err;
660 }
661
662 CBS proof;
663 if (!CBS_get_u16_length_prefixed(cbs, &proof) ||
664 !dleq_verify(method, &proof, key, &BT_batch, &Z_batch) ||
665 CBS_len(&proof) != 0) {
666 goto err;
667 }
668
669 ok = 1;
670
671 err:
672 OPENSSL_free(BTs);
673 OPENSSL_free(Zs);
674 OPENSSL_free(es);
675 CBB_cleanup(&batch_cbb);
676 if (!ok) {
677 sk_TRUST_TOKEN_pop_free(ret, TRUST_TOKEN_free);
678 ret = NULL;
679 }
680 return ret;
681 }
682
sha384_update_u16(SHA512_CTX * ctx,uint16_t v)683 static void sha384_update_u16(SHA512_CTX *ctx, uint16_t v) {
684 uint8_t buf[2] = {v >> 8, v & 0xff};
685 SHA384_Update(ctx, buf, 2);
686 }
687
sha384_update_point_with_length(SHA512_CTX * ctx,const EC_GROUP * group,const EC_AFFINE * point)688 static void sha384_update_point_with_length(
689 SHA512_CTX *ctx, const EC_GROUP *group, const EC_AFFINE *point) {
690 uint8_t buf[EC_MAX_COMPRESSED];
691 size_t len = ec_point_to_bytes(group, point, POINT_CONVERSION_COMPRESSED,
692 buf, sizeof(buf));
693 assert(len > 0);
694 sha384_update_u16(ctx, (uint16_t)len);
695 SHA384_Update(ctx, buf, len);
696 }
697
compute_composite_seed(const VOPRF_METHOD * method,uint8_t out[SHA384_DIGEST_LENGTH],const EC_AFFINE * pub)698 static int compute_composite_seed(const VOPRF_METHOD *method,
699 uint8_t out[SHA384_DIGEST_LENGTH],
700 const EC_AFFINE *pub) {
701 const EC_GROUP *group = method->group_func();
702 static const uint8_t kSeedDST[] = "Seed-OPRFV1-\x01-P384-SHA384";
703
704 SHA512_CTX hash_ctx;
705 SHA384_Init(&hash_ctx);
706 sha384_update_point_with_length(&hash_ctx, group, pub);
707 sha384_update_u16(&hash_ctx, sizeof(kSeedDST) - 1);
708 SHA384_Update(&hash_ctx, kSeedDST, sizeof(kSeedDST) - 1);
709 SHA384_Final(out, &hash_ctx);
710
711 return 1;
712 }
713
compute_composite_element(const VOPRF_METHOD * method,uint8_t seed[SHA384_DIGEST_LENGTH],EC_SCALAR * di,size_t index,const EC_AFFINE * C,const EC_AFFINE * D)714 static int compute_composite_element(const VOPRF_METHOD *method,
715 uint8_t seed[SHA384_DIGEST_LENGTH],
716 EC_SCALAR *di, size_t index,
717 const EC_AFFINE *C, const EC_AFFINE *D) {
718 static const uint8_t kCompositeLabel[] = "Composite";
719 const EC_GROUP *group = method->group_func();
720
721 if (index > UINT16_MAX) {
722 return 0;
723 }
724
725 CBB cbb;
726 uint8_t transcript[2 + SHA384_DIGEST_LENGTH + 2 + 2 * EC_MAX_COMPRESSED +
727 sizeof(kCompositeLabel) - 1];
728 size_t len;
729 if (!CBB_init_fixed(&cbb, transcript, sizeof(transcript)) ||
730 !CBB_add_u16(&cbb, SHA384_DIGEST_LENGTH) ||
731 !CBB_add_bytes(&cbb, seed, SHA384_DIGEST_LENGTH) ||
732 !CBB_add_u16(&cbb, index) ||
733 !cbb_serialize_point(&cbb, group, C) ||
734 !cbb_serialize_point(&cbb, group, D) ||
735 !CBB_add_bytes(&cbb, kCompositeLabel,
736 sizeof(kCompositeLabel) - 1) ||
737 !CBB_finish(&cbb, NULL, &len) ||
738 !method->hash_to_scalar(group, di, transcript, len)) {
739 return 0;
740 }
741
742 return 1;
743 }
744
generate_proof(const VOPRF_METHOD * method,CBB * cbb,const TRUST_TOKEN_ISSUER_KEY * priv,const EC_SCALAR * r,const EC_JACOBIAN * M,const EC_JACOBIAN * Z)745 static int generate_proof(const VOPRF_METHOD *method, CBB *cbb,
746 const TRUST_TOKEN_ISSUER_KEY *priv,
747 const EC_SCALAR *r, const EC_JACOBIAN *M,
748 const EC_JACOBIAN *Z) {
749 const EC_GROUP *group = method->group_func();
750
751 enum {
752 idx_M,
753 idx_Z,
754 idx_t2,
755 idx_t3,
756 num_idx,
757 };
758 EC_JACOBIAN jacobians[num_idx];
759
760 if (!ec_point_mul_scalar_base(group, &jacobians[idx_t2], r) ||
761 !ec_point_mul_scalar(group, &jacobians[idx_t3], M, r)) {
762 return 0;
763 }
764
765
766 EC_AFFINE affines[num_idx];
767 jacobians[idx_M] = *M;
768 jacobians[idx_Z] = *Z;
769 if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) {
770 return 0;
771 }
772
773 EC_SCALAR c;
774 if (!hash_to_scalar_challenge(method, &c, &priv->pubs, &affines[idx_M],
775 &affines[idx_Z], &affines[idx_t2],
776 &affines[idx_t3])) {
777 return 0;
778 }
779
780 EC_SCALAR c_mont;
781 ec_scalar_to_montgomery(group, &c_mont, &c);
782
783 // s = r - c*xs
784 EC_SCALAR s;
785 ec_scalar_mul_montgomery(group, &s, &priv->xs, &c_mont);
786 ec_scalar_sub(group, &s, r, &s);
787
788 // Store DLEQ proof in transcript.
789 if (!scalar_to_cbb(cbb, group, &c) ||
790 !scalar_to_cbb(cbb, group, &s)) {
791 return 0;
792 }
793
794 return 1;
795 }
796
verify_proof(const VOPRF_METHOD * method,CBS * cbs,const TRUST_TOKEN_CLIENT_KEY * pub,const EC_JACOBIAN * M,const EC_JACOBIAN * Z)797 static int verify_proof(const VOPRF_METHOD *method, CBS *cbs,
798 const TRUST_TOKEN_CLIENT_KEY *pub,
799 const EC_JACOBIAN *M, const EC_JACOBIAN *Z) {
800 const EC_GROUP *group = method->group_func();
801
802 enum {
803 idx_M,
804 idx_Z,
805 idx_t2,
806 idx_t3,
807 num_idx,
808 };
809 EC_JACOBIAN jacobians[num_idx];
810
811 EC_SCALAR c, s;
812 if (!scalar_from_cbs(cbs, group, &c) ||
813 !scalar_from_cbs(cbs, group, &s)) {
814 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
815 return 0;
816 }
817
818 EC_JACOBIAN pubs;
819 ec_affine_to_jacobian(group, &pubs, &pub->pubs);
820 if (!ec_point_mul_scalar_public(group, &jacobians[idx_t2], &s, &pubs,
821 &c) ||
822 !mul_public_2(group, &jacobians[idx_t3], M, &s, Z, &c)) {
823 return 0;
824 }
825
826 EC_AFFINE affines[num_idx];
827 jacobians[idx_M] = *M;
828 jacobians[idx_Z] = *Z;
829 if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) {
830 return 0;
831 }
832
833 EC_SCALAR expected_c;
834 if (!hash_to_scalar_challenge(method, &expected_c, &pub->pubs,
835 &affines[idx_M], &affines[idx_Z],
836 &affines[idx_t2], &affines[idx_t3])) {
837 return 0;
838 }
839
840 // c == expected_c
841 if (!ec_scalar_equal_vartime(group, &c, &expected_c)) {
842 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_PROOF);
843 return 0;
844 }
845
846 return 1;
847 }
848
voprf_sign_impl(const VOPRF_METHOD * method,const TRUST_TOKEN_ISSUER_KEY * key,CBB * cbb,CBS * cbs,size_t num_requested,size_t num_to_issue,const EC_SCALAR * proof_scalar)849 static int voprf_sign_impl(const VOPRF_METHOD *method,
850 const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb,
851 CBS *cbs, size_t num_requested, size_t num_to_issue,
852 const EC_SCALAR *proof_scalar) {
853 const EC_GROUP *group = method->group_func();
854 if (num_requested < num_to_issue) {
855 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
856 return 0;
857 }
858
859 int ret = 0;
860 EC_JACOBIAN *BTs = OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN));
861 EC_JACOBIAN *Zs = OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN));
862 EC_SCALAR *dis = OPENSSL_calloc(num_to_issue, sizeof(EC_SCALAR));
863 if (!BTs || !Zs || !dis) {
864 goto err;
865 }
866
867 uint8_t seed[SHA384_DIGEST_LENGTH];
868 if (!compute_composite_seed(method, seed, &key->pubs)) {
869 goto err;
870 }
871
872 // This implements the BlindEvaluateBatch as defined in section 4 of
873 // draft-robert-privacypass-batched-tokens-01, based on the constructions
874 // in draft-irtf-cfrg-voprf-21. To optimize the computation of the proof,
875 // the computation of di is done during the token signing and passed into
876 // the proof generation.
877 for (size_t i = 0; i < num_to_issue; i++) {
878 EC_AFFINE BT_affine, Z_affine;
879 EC_JACOBIAN BT, Z;
880 if (!cbs_get_point(cbs, group, &BT_affine)) {
881 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
882 goto err;
883 }
884 ec_affine_to_jacobian(group, &BT, &BT_affine);
885 if (!ec_point_mul_scalar(group, &Z, &BT, &key->xs) ||
886 !ec_jacobian_to_affine(group, &Z_affine, &Z) ||
887 !cbb_add_point(cbb, group, &Z_affine)) {
888 goto err;
889 }
890 BTs[i] = BT;
891 Zs[i] = Z;
892 if (!compute_composite_element(method, seed, &dis[i], i, &BT_affine,
893 &Z_affine)) {
894 goto err;
895 }
896
897 if (!CBB_flush(cbb)) {
898 goto err;
899 }
900 }
901
902 EC_JACOBIAN M, Z;
903 if (!ec_point_mul_scalar_public_batch(group, &M,
904 /*g_scalar=*/NULL, BTs, dis,
905 num_to_issue) ||
906 !ec_point_mul_scalar(group, &Z, &M, &key->xs)) {
907 goto err;
908 }
909
910 CBB proof;
911 if (!CBB_add_u16_length_prefixed(cbb, &proof) ||
912 !generate_proof(method, &proof, key, proof_scalar, &M, &Z) ||
913 !CBB_flush(cbb)) {
914 goto err;
915 }
916
917 // Skip over any unused requests.
918 size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
919 if (!CBS_skip(cbs, point_len * (num_requested - num_to_issue))) {
920 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
921 goto err;
922 }
923
924 ret = 1;
925
926 err:
927 OPENSSL_free(BTs);
928 OPENSSL_free(Zs);
929 OPENSSL_free(dis);
930 return ret;
931 }
932
voprf_sign(const VOPRF_METHOD * method,const TRUST_TOKEN_ISSUER_KEY * key,CBB * cbb,CBS * cbs,size_t num_requested,size_t num_to_issue)933 static int voprf_sign(const VOPRF_METHOD *method,
934 const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
935 size_t num_requested, size_t num_to_issue) {
936 EC_SCALAR proof_scalar;
937 if (!ec_random_nonzero_scalar(method->group_func(), &proof_scalar,
938 kDefaultAdditionalData)) {
939 return 0;
940 }
941
942 return voprf_sign_impl(method, key, cbb, cbs, num_requested, num_to_issue,
943 &proof_scalar);
944 }
945
voprf_sign_with_proof_scalar_for_testing(const VOPRF_METHOD * method,const TRUST_TOKEN_ISSUER_KEY * key,CBB * cbb,CBS * cbs,size_t num_requested,size_t num_to_issue,const uint8_t * proof_scalar_buf,size_t proof_scalar_len)946 static int voprf_sign_with_proof_scalar_for_testing(
947 const VOPRF_METHOD *method, const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb,
948 CBS *cbs, size_t num_requested, size_t num_to_issue,
949 const uint8_t *proof_scalar_buf, size_t proof_scalar_len) {
950 EC_SCALAR proof_scalar;
951 if (!ec_scalar_from_bytes(method->group_func(), &proof_scalar,
952 proof_scalar_buf, proof_scalar_len)) {
953 return 0;
954 }
955 return voprf_sign_impl(method, key, cbb, cbs, num_requested, num_to_issue,
956 &proof_scalar);
957 }
958
STACK_OF(TRUST_TOKEN)959 static STACK_OF(TRUST_TOKEN) *voprf_unblind(
960 const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key,
961 const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
962 uint32_t key_id) {
963 const EC_GROUP *group = method->group_func();
964 if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) {
965 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
966 return NULL;
967 }
968
969 int ok = 0;
970 STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null();
971 EC_JACOBIAN *BTs = OPENSSL_calloc(count, sizeof(EC_JACOBIAN));
972 EC_JACOBIAN *Zs = OPENSSL_calloc(count, sizeof(EC_JACOBIAN));
973 EC_SCALAR *dis = OPENSSL_calloc(count, sizeof(EC_SCALAR));
974 if (ret == NULL || !BTs || !Zs || !dis) {
975 goto err;
976 }
977
978 uint8_t seed[SHA384_DIGEST_LENGTH];
979 if (!compute_composite_seed(method, seed, &key->pubs)) {
980 goto err;
981 }
982
983 for (size_t i = 0; i < count; i++) {
984 const TRUST_TOKEN_PRETOKEN *pretoken =
985 sk_TRUST_TOKEN_PRETOKEN_value(pretokens, i);
986
987 EC_AFFINE Z_affine;
988 if (!cbs_get_point(cbs, group, &Z_affine)) {
989 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
990 goto err;
991 }
992
993 ec_affine_to_jacobian(group, &BTs[i], &pretoken->Tp);
994 ec_affine_to_jacobian(group, &Zs[i], &Z_affine);
995 if (!compute_composite_element(method, seed, &dis[i], i, &pretoken->Tp,
996 &Z_affine)) {
997 goto err;
998 }
999
1000 // Unblind the token.
1001 // pretoken->r is rinv.
1002 EC_JACOBIAN N;
1003 EC_AFFINE N_affine;
1004 if (!ec_point_mul_scalar(group, &N, &Zs[i], &pretoken->r) ||
1005 !ec_jacobian_to_affine(group, &N_affine, &N)) {
1006 goto err;
1007 }
1008
1009 // Serialize the token. Include |key_id| to avoid an extra copy in the layer
1010 // above.
1011 CBB token_cbb;
1012 size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
1013 if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + (2 + point_len)) ||
1014 !CBB_add_u32(&token_cbb, key_id) ||
1015 !CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) ||
1016 !cbb_add_point(&token_cbb, group, &N_affine) ||
1017 !CBB_flush(&token_cbb)) {
1018 CBB_cleanup(&token_cbb);
1019 goto err;
1020 }
1021
1022 TRUST_TOKEN *token =
1023 TRUST_TOKEN_new(CBB_data(&token_cbb), CBB_len(&token_cbb));
1024 CBB_cleanup(&token_cbb);
1025 if (token == NULL ||
1026 !sk_TRUST_TOKEN_push(ret, token)) {
1027 TRUST_TOKEN_free(token);
1028 goto err;
1029 }
1030 }
1031
1032 EC_JACOBIAN M, Z;
1033 if (!ec_point_mul_scalar_public_batch(group, &M,
1034 /*g_scalar=*/NULL, BTs, dis,
1035 count) ||
1036 !ec_point_mul_scalar_public_batch(group, &Z,
1037 /*g_scalar=*/NULL, Zs, dis,
1038 count)) {
1039 goto err;
1040 }
1041
1042 CBS proof;
1043 if (!CBS_get_u16_length_prefixed(cbs, &proof) ||
1044 !verify_proof(method, &proof, key, &M, &Z) ||
1045 CBS_len(&proof) != 0) {
1046 goto err;
1047 }
1048
1049 ok = 1;
1050
1051 err:
1052 OPENSSL_free(BTs);
1053 OPENSSL_free(Zs);
1054 OPENSSL_free(dis);
1055 if (!ok) {
1056 sk_TRUST_TOKEN_pop_free(ret, TRUST_TOKEN_free);
1057 ret = NULL;
1058 }
1059 return ret;
1060 }
1061
voprf_read(const VOPRF_METHOD * method,const TRUST_TOKEN_ISSUER_KEY * key,uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],const uint8_t * token,size_t token_len,int include_message,const uint8_t * msg,size_t msg_len)1062 static int voprf_read(const VOPRF_METHOD *method,
1063 const TRUST_TOKEN_ISSUER_KEY *key,
1064 uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],
1065 const uint8_t *token, size_t token_len,
1066 int include_message, const uint8_t *msg, size_t msg_len) {
1067 const EC_GROUP *group = method->group_func();
1068 CBS cbs, salt;
1069 CBS_init(&cbs, token, token_len);
1070 EC_AFFINE Ws;
1071 if (!CBS_get_bytes(&cbs, &salt, TRUST_TOKEN_NONCE_SIZE) ||
1072 !cbs_get_point(&cbs, group, &Ws) ||
1073 CBS_len(&cbs) != 0) {
1074 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
1075 return 0;
1076 }
1077
1078 if (include_message) {
1079 SHA512_CTX hash_ctx;
1080 assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE);
1081 SHA512_Init(&hash_ctx);
1082 SHA512_Update(&hash_ctx, CBS_data(&salt), CBS_len(&salt));
1083 SHA512_Update(&hash_ctx, msg, msg_len);
1084 SHA512_Final(out_nonce, &hash_ctx);
1085 } else {
1086 OPENSSL_memcpy(out_nonce, CBS_data(&salt), CBS_len(&salt));
1087 }
1088
1089
1090 EC_JACOBIAN T;
1091 if (!method->hash_to_group(group, &T, out_nonce)) {
1092 return 0;
1093 }
1094
1095 EC_JACOBIAN Ws_calculated;
1096 if (!ec_point_mul_scalar(group, &Ws_calculated, &T, &key->xs) ||
1097 !ec_affine_jacobian_equal(group, &Ws, &Ws_calculated)) {
1098 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BAD_VALIDITY_CHECK);
1099 return 0;
1100 }
1101
1102 return 1;
1103 }
1104
1105
1106 // VOPRF experiment v2.
1107
voprf_exp2_hash_to_group(const EC_GROUP * group,EC_JACOBIAN * out,const uint8_t t[TRUST_TOKEN_NONCE_SIZE])1108 static int voprf_exp2_hash_to_group(const EC_GROUP *group, EC_JACOBIAN *out,
1109 const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) {
1110 const uint8_t kHashTLabel[] = "TrustToken VOPRF Experiment V2 HashToGroup";
1111 return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(
1112 group, out, kHashTLabel, sizeof(kHashTLabel), t, TRUST_TOKEN_NONCE_SIZE);
1113 }
1114
voprf_exp2_hash_to_scalar(const EC_GROUP * group,EC_SCALAR * out,uint8_t * buf,size_t len)1115 static int voprf_exp2_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
1116 uint8_t *buf, size_t len) {
1117 const uint8_t kHashCLabel[] = "TrustToken VOPRF Experiment V2 HashToScalar";
1118 return ec_hash_to_scalar_p384_xmd_sha512_draft07(
1119 group, out, kHashCLabel, sizeof(kHashCLabel), buf, len);
1120 }
1121
1122 static VOPRF_METHOD voprf_exp2_method = {
1123 EC_group_p384, voprf_exp2_hash_to_group, voprf_exp2_hash_to_scalar};
1124
voprf_exp2_generate_key(CBB * out_private,CBB * out_public)1125 int voprf_exp2_generate_key(CBB *out_private, CBB *out_public) {
1126 return voprf_generate_key(&voprf_exp2_method, out_private, out_public);
1127 }
1128
voprf_exp2_derive_key_from_secret(CBB * out_private,CBB * out_public,const uint8_t * secret,size_t secret_len)1129 int voprf_exp2_derive_key_from_secret(CBB *out_private, CBB *out_public,
1130 const uint8_t *secret,
1131 size_t secret_len) {
1132 return voprf_derive_key_from_secret(&voprf_exp2_method, out_private,
1133 out_public, secret, secret_len);
1134 }
1135
voprf_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY * key,const uint8_t * in,size_t len)1136 int voprf_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key,
1137 const uint8_t *in, size_t len) {
1138 return voprf_client_key_from_bytes(&voprf_exp2_method, key, in, len);
1139 }
1140
voprf_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY * key,const uint8_t * in,size_t len)1141 int voprf_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key,
1142 const uint8_t *in, size_t len) {
1143 return voprf_issuer_key_from_bytes(&voprf_exp2_method, key, in, len);
1144 }
1145
STACK_OF(TRUST_TOKEN_PRETOKEN)1146 STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_exp2_blind(CBB *cbb, size_t count,
1147 int include_message,
1148 const uint8_t *msg,
1149 size_t msg_len) {
1150 return voprf_blind(&voprf_exp2_method, cbb, count, include_message, msg,
1151 msg_len);
1152 }
1153
voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY * key,CBB * cbb,CBS * cbs,size_t num_requested,size_t num_to_issue,uint8_t private_metadata)1154 int voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
1155 size_t num_requested, size_t num_to_issue,
1156 uint8_t private_metadata) {
1157 if (private_metadata != 0) {
1158 return 0;
1159 }
1160 return voprf_sign_tt(&voprf_exp2_method, key, cbb, cbs, num_requested,
1161 num_to_issue);
1162 }
1163
STACK_OF(TRUST_TOKEN)1164 STACK_OF(TRUST_TOKEN) *voprf_exp2_unblind(
1165 const TRUST_TOKEN_CLIENT_KEY *key,
1166 const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
1167 uint32_t key_id) {
1168 return voprf_unblind_tt(&voprf_exp2_method, key, pretokens, cbs, count,
1169 key_id);
1170 }
1171
voprf_exp2_read(const TRUST_TOKEN_ISSUER_KEY * key,uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],uint8_t * out_private_metadata,const uint8_t * token,size_t token_len,int include_message,const uint8_t * msg,size_t msg_len)1172 int voprf_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key,
1173 uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],
1174 uint8_t *out_private_metadata, const uint8_t *token,
1175 size_t token_len, int include_message, const uint8_t *msg,
1176 size_t msg_len) {
1177 return voprf_read(&voprf_exp2_method, key, out_nonce, token, token_len,
1178 include_message, msg, msg_len);
1179 }
1180
1181 // VOPRF PST v1.
1182
voprf_pst1_hash_to_group(const EC_GROUP * group,EC_JACOBIAN * out,const uint8_t t[TRUST_TOKEN_NONCE_SIZE])1183 static int voprf_pst1_hash_to_group(const EC_GROUP *group, EC_JACOBIAN *out,
1184 const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) {
1185 const uint8_t kHashTLabel[] = "HashToGroup-OPRFV1-\x01-P384-SHA384";
1186 return ec_hash_to_curve_p384_xmd_sha384_sswu(group, out, kHashTLabel,
1187 sizeof(kHashTLabel) - 1, t,
1188 TRUST_TOKEN_NONCE_SIZE);
1189 }
1190
voprf_pst1_hash_to_scalar(const EC_GROUP * group,EC_SCALAR * out,uint8_t * buf,size_t len)1191 static int voprf_pst1_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
1192 uint8_t *buf, size_t len) {
1193 const uint8_t kHashCLabel[] = "HashToScalar-OPRFV1-\x01-P384-SHA384";
1194 return ec_hash_to_scalar_p384_xmd_sha384(group, out, kHashCLabel,
1195 sizeof(kHashCLabel) - 1, buf, len);
1196 }
1197
1198 static VOPRF_METHOD voprf_pst1_method = {
1199 EC_group_p384, voprf_pst1_hash_to_group, voprf_pst1_hash_to_scalar};
1200
voprf_pst1_generate_key(CBB * out_private,CBB * out_public)1201 int voprf_pst1_generate_key(CBB *out_private, CBB *out_public) {
1202 return voprf_generate_key(&voprf_pst1_method, out_private, out_public);
1203 }
1204
voprf_pst1_derive_key_from_secret(CBB * out_private,CBB * out_public,const uint8_t * secret,size_t secret_len)1205 int voprf_pst1_derive_key_from_secret(CBB *out_private, CBB *out_public,
1206 const uint8_t *secret,
1207 size_t secret_len) {
1208 return voprf_derive_key_from_secret(&voprf_pst1_method, out_private,
1209 out_public, secret, secret_len);
1210 }
1211
voprf_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY * key,const uint8_t * in,size_t len)1212 int voprf_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key,
1213 const uint8_t *in, size_t len) {
1214 return voprf_client_key_from_bytes(&voprf_pst1_method, key, in, len);
1215 }
1216
voprf_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY * key,const uint8_t * in,size_t len)1217 int voprf_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key,
1218 const uint8_t *in, size_t len) {
1219 return voprf_issuer_key_from_bytes(&voprf_pst1_method, key, in, len);
1220 }
1221
STACK_OF(TRUST_TOKEN_PRETOKEN)1222 STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_pst1_blind(CBB *cbb, size_t count,
1223 int include_message,
1224 const uint8_t *msg,
1225 size_t msg_len) {
1226 return voprf_blind(&voprf_pst1_method, cbb, count, include_message, msg,
1227 msg_len);
1228 }
1229
voprf_pst1_sign(const TRUST_TOKEN_ISSUER_KEY * key,CBB * cbb,CBS * cbs,size_t num_requested,size_t num_to_issue,uint8_t private_metadata)1230 int voprf_pst1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
1231 size_t num_requested, size_t num_to_issue,
1232 uint8_t private_metadata) {
1233 if (private_metadata != 0) {
1234 return 0;
1235 }
1236 return voprf_sign(&voprf_pst1_method, key, cbb, cbs, num_requested,
1237 num_to_issue);
1238 }
1239
1240
voprf_pst1_sign_with_proof_scalar_for_testing(const TRUST_TOKEN_ISSUER_KEY * key,CBB * cbb,CBS * cbs,size_t num_requested,size_t num_to_issue,uint8_t private_metadata,const uint8_t * proof_scalar_buf,size_t proof_scalar_len)1241 int voprf_pst1_sign_with_proof_scalar_for_testing(
1242 const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, size_t num_requested,
1243 size_t num_to_issue, uint8_t private_metadata,
1244 const uint8_t *proof_scalar_buf, size_t proof_scalar_len) {
1245 if (private_metadata != 0) {
1246 return 0;
1247 }
1248 return voprf_sign_with_proof_scalar_for_testing(
1249 &voprf_pst1_method, key, cbb, cbs, num_requested, num_to_issue,
1250 proof_scalar_buf, proof_scalar_len);
1251 }
1252
STACK_OF(TRUST_TOKEN)1253 STACK_OF(TRUST_TOKEN) *voprf_pst1_unblind(
1254 const TRUST_TOKEN_CLIENT_KEY *key,
1255 const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
1256 uint32_t key_id) {
1257 return voprf_unblind(&voprf_pst1_method, key, pretokens, cbs, count, key_id);
1258 }
1259
voprf_pst1_read(const TRUST_TOKEN_ISSUER_KEY * key,uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],uint8_t * out_private_metadata,const uint8_t * token,size_t token_len,int include_message,const uint8_t * msg,size_t msg_len)1260 int voprf_pst1_read(const TRUST_TOKEN_ISSUER_KEY *key,
1261 uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],
1262 uint8_t *out_private_metadata, const uint8_t *token,
1263 size_t token_len, int include_message, const uint8_t *msg,
1264 size_t msg_len) {
1265 return voprf_read(&voprf_pst1_method, key, out_nonce, token, token_len,
1266 include_message, msg, msg_len);
1267 }
1268