xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/crypto/trust_token/voprf.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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