1 // Copyright 2020 The BoringSSL Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
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/sha2.h>
25 
26 #include "../ec/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 = reinterpret_cast<TRUST_TOKEN_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, kDefaultAdditionalData)) {
234       goto err;
235     }
236 
237     // pretoken->r is rinv.
238     ec_scalar_inv0_montgomery(group, &pretoken->r, &r);
239     // Convert both out of Montgomery form.
240     ec_scalar_from_montgomery(group, &r, &r);
241     ec_scalar_from_montgomery(group, &pretoken->r, &pretoken->r);
242 
243     // Tp is the blinded token in the VOPRF protocol.
244     EC_JACOBIAN P, Tp;
245     if (!method->hash_to_group(group, &P, pretoken->t) ||
246         !ec_point_mul_scalar(group, &Tp, &P, &r) ||
247         !ec_jacobian_to_affine(group, &pretoken->Tp, &Tp)) {
248       goto err;
249     }
250 
251     if (!cbb_add_point(cbb, group, &pretoken->Tp)) {
252       goto err;
253     }
254   }
255 
256   return pretokens;
257 
258 err:
259   sk_TRUST_TOKEN_PRETOKEN_pop_free(pretokens, TRUST_TOKEN_PRETOKEN_free);
260   return NULL;
261 }
262 
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)263 static int hash_to_scalar_dleq(const VOPRF_METHOD *method, EC_SCALAR *out,
264                                const EC_AFFINE *X, const EC_AFFINE *T,
265                                const EC_AFFINE *W, const EC_AFFINE *K0,
266                                const EC_AFFINE *K1) {
267   static const uint8_t kDLEQLabel[] = "DLEQ";
268 
269   const EC_GROUP *group = method->group_func();
270   int ok = 0;
271   CBB cbb;
272   CBB_zero(&cbb);
273   uint8_t *buf = NULL;
274   size_t len;
275   if (!CBB_init(&cbb, 0) ||
276       !CBB_add_bytes(&cbb, kDLEQLabel, sizeof(kDLEQLabel)) ||
277       !cbb_add_point(&cbb, group, X) || !cbb_add_point(&cbb, group, T) ||
278       !cbb_add_point(&cbb, group, W) || !cbb_add_point(&cbb, group, K0) ||
279       !cbb_add_point(&cbb, group, K1) || !CBB_finish(&cbb, &buf, &len) ||
280       !method->hash_to_scalar(group, out, buf, len)) {
281     goto err;
282   }
283 
284   ok = 1;
285 
286 err:
287   CBB_cleanup(&cbb);
288   OPENSSL_free(buf);
289   return ok;
290 }
291 
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)292 static int hash_to_scalar_challenge(const VOPRF_METHOD *method, EC_SCALAR *out,
293                                     const EC_AFFINE *Bm, const EC_AFFINE *a0,
294                                     const EC_AFFINE *a1, const EC_AFFINE *a2,
295                                     const EC_AFFINE *a3) {
296   static const uint8_t kChallengeLabel[] = "Challenge";
297 
298   const EC_GROUP *group = method->group_func();
299   CBB cbb;
300   uint8_t transcript[5 * EC_MAX_COMPRESSED + 2 + sizeof(kChallengeLabel) - 1];
301   size_t len;
302   if (!CBB_init_fixed(&cbb, transcript, sizeof(transcript)) ||
303       !cbb_serialize_point(&cbb, group, Bm) ||
304       !cbb_serialize_point(&cbb, group, a0) ||
305       !cbb_serialize_point(&cbb, group, a1) ||
306       !cbb_serialize_point(&cbb, group, a2) ||
307       !cbb_serialize_point(&cbb, group, a3) ||
308       !CBB_add_bytes(&cbb, kChallengeLabel, sizeof(kChallengeLabel) - 1) ||
309       !CBB_finish(&cbb, NULL, &len) ||
310       !method->hash_to_scalar(group, out, transcript, len)) {
311     return 0;
312   }
313 
314   return 1;
315 }
316 
hash_to_scalar_batch(const VOPRF_METHOD * method,EC_SCALAR * out,const CBB * points,size_t index)317 static int hash_to_scalar_batch(const VOPRF_METHOD *method, EC_SCALAR *out,
318                                 const CBB *points, size_t index) {
319   static const uint8_t kDLEQBatchLabel[] = "DLEQ BATCH";
320   if (index > 0xffff) {
321     // The protocol supports only two-byte batches.
322     OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
323     return 0;
324   }
325 
326   int ok = 0;
327   CBB cbb;
328   CBB_zero(&cbb);
329   uint8_t *buf = NULL;
330   size_t len;
331   if (!CBB_init(&cbb, 0) ||
332       !CBB_add_bytes(&cbb, kDLEQBatchLabel, sizeof(kDLEQBatchLabel)) ||
333       !CBB_add_bytes(&cbb, CBB_data(points), CBB_len(points)) ||
334       !CBB_add_u16(&cbb, (uint16_t)index) || !CBB_finish(&cbb, &buf, &len) ||
335       !method->hash_to_scalar(method->group_func(), out, buf, len)) {
336     goto err;
337   }
338 
339   ok = 1;
340 
341 err:
342   CBB_cleanup(&cbb);
343   OPENSSL_free(buf);
344   return ok;
345 }
346 
dleq_generate(const VOPRF_METHOD * method,CBB * cbb,const TRUST_TOKEN_ISSUER_KEY * priv,const EC_JACOBIAN * T,const EC_JACOBIAN * W)347 static int dleq_generate(const VOPRF_METHOD *method, CBB *cbb,
348                          const TRUST_TOKEN_ISSUER_KEY *priv,
349                          const EC_JACOBIAN *T, const EC_JACOBIAN *W) {
350   const EC_GROUP *group = method->group_func();
351 
352   enum {
353     idx_T,
354     idx_W,
355     idx_k0,
356     idx_k1,
357     num_idx,
358   };
359   EC_JACOBIAN jacobians[num_idx];
360 
361   // Setup the DLEQ proof.
362   EC_SCALAR r;
363   if (  // r <- Zp
364       !ec_random_nonzero_scalar(group, &r, kDefaultAdditionalData) ||
365       // k0;k1 = r*(G;T)
366       !ec_point_mul_scalar_base(group, &jacobians[idx_k0], &r) ||
367       !ec_point_mul_scalar(group, &jacobians[idx_k1], T, &r)) {
368     return 0;
369   }
370 
371   EC_AFFINE affines[num_idx];
372   jacobians[idx_T] = *T;
373   jacobians[idx_W] = *W;
374   if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) {
375     return 0;
376   }
377 
378   // Compute c = Hc(...).
379   EC_SCALAR c;
380   if (!hash_to_scalar_dleq(method, &c, &priv->pubs, &affines[idx_T],
381                            &affines[idx_W], &affines[idx_k0],
382                            &affines[idx_k1])) {
383     return 0;
384   }
385 
386 
387   EC_SCALAR c_mont;
388   ec_scalar_to_montgomery(group, &c_mont, &c);
389 
390   // u = r + c*xs
391   EC_SCALAR u;
392   ec_scalar_mul_montgomery(group, &u, &priv->xs, &c_mont);
393   ec_scalar_add(group, &u, &r, &u);
394 
395   // Store DLEQ proof in transcript.
396   if (!scalar_to_cbb(cbb, group, &c) || !scalar_to_cbb(cbb, group, &u)) {
397     return 0;
398   }
399 
400   return 1;
401 }
402 
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)403 static int mul_public_2(const EC_GROUP *group, EC_JACOBIAN *out,
404                         const EC_JACOBIAN *p0, const EC_SCALAR *scalar0,
405                         const EC_JACOBIAN *p1, const EC_SCALAR *scalar1) {
406   EC_JACOBIAN points[2] = {*p0, *p1};
407   EC_SCALAR scalars[2] = {*scalar0, *scalar1};
408   return ec_point_mul_scalar_public_batch(group, out, /*g_scalar=*/NULL, points,
409                                           scalars, 2);
410 }
411 
dleq_verify(const VOPRF_METHOD * method,CBS * cbs,const TRUST_TOKEN_CLIENT_KEY * pub,const EC_JACOBIAN * T,const EC_JACOBIAN * W)412 static int dleq_verify(const VOPRF_METHOD *method, CBS *cbs,
413                        const TRUST_TOKEN_CLIENT_KEY *pub, const EC_JACOBIAN *T,
414                        const EC_JACOBIAN *W) {
415   const EC_GROUP *group = method->group_func();
416 
417 
418   enum {
419     idx_T,
420     idx_W,
421     idx_k0,
422     idx_k1,
423     num_idx,
424   };
425   EC_JACOBIAN jacobians[num_idx];
426 
427   // Decode the DLEQ proof.
428   EC_SCALAR c, u;
429   if (!scalar_from_cbs(cbs, group, &c) || !scalar_from_cbs(cbs, group, &u)) {
430     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
431     return 0;
432   }
433 
434   // k0;k1 = u*(G;T) - c*(pub;W)
435   EC_JACOBIAN pubs;
436   ec_affine_to_jacobian(group, &pubs, &pub->pubs);
437   EC_SCALAR minus_c;
438   ec_scalar_neg(group, &minus_c, &c);
439   if (!ec_point_mul_scalar_public(group, &jacobians[idx_k0], &u, &pubs,
440                                   &minus_c) ||
441       !mul_public_2(group, &jacobians[idx_k1], T, &u, W, &minus_c)) {
442     return 0;
443   }
444 
445   // Check the DLEQ proof.
446   EC_AFFINE affines[num_idx];
447   jacobians[idx_T] = *T;
448   jacobians[idx_W] = *W;
449   if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) {
450     return 0;
451   }
452 
453   // Compute c = Hc(...).
454   EC_SCALAR calculated;
455   if (!hash_to_scalar_dleq(method, &calculated, &pub->pubs, &affines[idx_T],
456                            &affines[idx_W], &affines[idx_k0],
457                            &affines[idx_k1])) {
458     return 0;
459   }
460 
461   // c == calculated
462   if (!ec_scalar_equal_vartime(group, &c, &calculated)) {
463     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_PROOF);
464     return 0;
465   }
466 
467   return 1;
468 }
469 
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)470 static int voprf_sign_tt(const VOPRF_METHOD *method,
471                          const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
472                          size_t num_requested, size_t num_to_issue) {
473   const EC_GROUP *group = method->group_func();
474   if (num_requested < num_to_issue) {
475     OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
476     return 0;
477   }
478 
479   int ret = 0;
480   EC_JACOBIAN *BTs = reinterpret_cast<EC_JACOBIAN *>(
481       OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN)));
482   EC_JACOBIAN *Zs = reinterpret_cast<EC_JACOBIAN *>(
483       OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN)));
484   EC_SCALAR *es = reinterpret_cast<EC_SCALAR *>(
485       OPENSSL_calloc(num_to_issue, sizeof(EC_SCALAR)));
486   CBB batch_cbb;
487   CBB_zero(&batch_cbb);
488 
489   {
490     if (!BTs || !Zs || !es || !CBB_init(&batch_cbb, 0) ||
491         !cbb_add_point(&batch_cbb, group, &key->pubs)) {
492       goto err;
493     }
494 
495     for (size_t i = 0; i < num_to_issue; i++) {
496       EC_AFFINE BT_affine, Z_affine;
497       EC_JACOBIAN BT, Z;
498       if (!cbs_get_point(cbs, group, &BT_affine)) {
499         OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
500         goto err;
501       }
502       ec_affine_to_jacobian(group, &BT, &BT_affine);
503       if (!ec_point_mul_scalar(group, &Z, &BT, &key->xs) ||
504           !ec_jacobian_to_affine(group, &Z_affine, &Z) ||
505           !cbb_add_point(cbb, group, &Z_affine)) {
506         goto err;
507       }
508 
509       if (!cbb_add_point(&batch_cbb, group, &BT_affine) ||
510           !cbb_add_point(&batch_cbb, group, &Z_affine)) {
511         goto err;
512       }
513       BTs[i] = BT;
514       Zs[i] = Z;
515 
516       if (!CBB_flush(cbb)) {
517         goto err;
518       }
519     }
520 
521     // The DLEQ batching construction is described in appendix B of
522     // https://eprint.iacr.org/2020/072/20200324:214215. Note the additional
523     // computations all act on public inputs.
524     for (size_t i = 0; i < num_to_issue; i++) {
525       if (!hash_to_scalar_batch(method, &es[i], &batch_cbb, i)) {
526         goto err;
527       }
528     }
529 
530     EC_JACOBIAN BT_batch, Z_batch;
531     if (!ec_point_mul_scalar_public_batch(group, &BT_batch,
532                                           /*g_scalar=*/NULL, BTs, es,
533                                           num_to_issue) ||
534         !ec_point_mul_scalar_public_batch(group, &Z_batch,
535                                           /*g_scalar=*/NULL, Zs, es,
536                                           num_to_issue)) {
537       goto err;
538     }
539 
540     CBB proof;
541     if (!CBB_add_u16_length_prefixed(cbb, &proof) ||
542         !dleq_generate(method, &proof, key, &BT_batch, &Z_batch) ||
543         !CBB_flush(cbb)) {
544       goto err;
545     }
546 
547     // Skip over any unused requests.
548     size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
549     if (!CBS_skip(cbs, point_len * (num_requested - num_to_issue))) {
550       OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
551       goto err;
552     }
553 
554     ret = 1;
555   }
556 
557 err:
558   OPENSSL_free(BTs);
559   OPENSSL_free(Zs);
560   OPENSSL_free(es);
561   CBB_cleanup(&batch_cbb);
562   return ret;
563 }
564 
STACK_OF(TRUST_TOKEN)565 static STACK_OF(TRUST_TOKEN) *voprf_unblind_tt(
566     const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key,
567     const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
568     uint32_t key_id) {
569   const EC_GROUP *group = method->group_func();
570   if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) {
571     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
572     return NULL;
573   }
574 
575   int ok = 0;
576   STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null();
577   EC_JACOBIAN *BTs = reinterpret_cast<EC_JACOBIAN *>(
578       OPENSSL_calloc(count, sizeof(EC_JACOBIAN)));
579   EC_JACOBIAN *Zs = reinterpret_cast<EC_JACOBIAN *>(
580       OPENSSL_calloc(count, sizeof(EC_JACOBIAN)));
581   EC_SCALAR *es =
582       reinterpret_cast<EC_SCALAR *>(OPENSSL_calloc(count, sizeof(EC_SCALAR)));
583   CBB batch_cbb;
584   CBB_zero(&batch_cbb);
585   if (ret == NULL || BTs == NULL || Zs == NULL || es == NULL ||
586       !CBB_init(&batch_cbb, 0) ||
587       !cbb_add_point(&batch_cbb, group, &key->pubs)) {
588     goto err;
589   }
590 
591   for (size_t i = 0; i < count; i++) {
592     const TRUST_TOKEN_PRETOKEN *pretoken =
593         sk_TRUST_TOKEN_PRETOKEN_value(pretokens, i);
594 
595     EC_AFFINE Z_affine;
596     if (!cbs_get_point(cbs, group, &Z_affine)) {
597       OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
598       goto err;
599     }
600 
601     ec_affine_to_jacobian(group, &BTs[i], &pretoken->Tp);
602     ec_affine_to_jacobian(group, &Zs[i], &Z_affine);
603 
604     if (!cbb_add_point(&batch_cbb, group, &pretoken->Tp) ||
605         !cbb_add_point(&batch_cbb, group, &Z_affine)) {
606       goto err;
607     }
608 
609     // Unblind the token.
610     // pretoken->r is rinv.
611     EC_JACOBIAN N;
612     EC_AFFINE N_affine;
613     if (!ec_point_mul_scalar(group, &N, &Zs[i], &pretoken->r) ||
614         !ec_jacobian_to_affine(group, &N_affine, &N)) {
615       goto err;
616     }
617 
618     // Serialize the token. Include |key_id| to avoid an extra copy in the layer
619     // above.
620     CBB token_cbb;
621     size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
622     if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + (2 + point_len)) ||
623         !CBB_add_u32(&token_cbb, key_id) ||
624         !CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) ||
625         !cbb_add_point(&token_cbb, group, &N_affine) ||
626         !CBB_flush(&token_cbb)) {
627       CBB_cleanup(&token_cbb);
628       goto err;
629     }
630 
631     TRUST_TOKEN *token =
632         TRUST_TOKEN_new(CBB_data(&token_cbb), CBB_len(&token_cbb));
633     CBB_cleanup(&token_cbb);
634     if (token == NULL || !sk_TRUST_TOKEN_push(ret, token)) {
635       TRUST_TOKEN_free(token);
636       goto err;
637     }
638   }
639 
640   // The DLEQ batching construction is described in appendix B of
641   // https://eprint.iacr.org/2020/072/20200324:214215. Note the additional
642   // computations all act on public inputs.
643   for (size_t i = 0; i < count; i++) {
644     if (!hash_to_scalar_batch(method, &es[i], &batch_cbb, i)) {
645       goto err;
646     }
647   }
648 
649   EC_JACOBIAN BT_batch, Z_batch;
650   if (!ec_point_mul_scalar_public_batch(group, &BT_batch,
651                                         /*g_scalar=*/NULL, BTs, es, count) ||
652       !ec_point_mul_scalar_public_batch(group, &Z_batch,
653                                         /*g_scalar=*/NULL, Zs, es, count)) {
654     goto err;
655   }
656 
657   CBS proof;
658   if (!CBS_get_u16_length_prefixed(cbs, &proof) ||
659       !dleq_verify(method, &proof, key, &BT_batch, &Z_batch) ||
660       CBS_len(&proof) != 0) {
661     goto err;
662   }
663 
664   ok = 1;
665 
666 err:
667   OPENSSL_free(BTs);
668   OPENSSL_free(Zs);
669   OPENSSL_free(es);
670   CBB_cleanup(&batch_cbb);
671   if (!ok) {
672     sk_TRUST_TOKEN_pop_free(ret, TRUST_TOKEN_free);
673     ret = NULL;
674   }
675   return ret;
676 }
677 
sha384_update_u16(SHA512_CTX * ctx,uint16_t v)678 static void sha384_update_u16(SHA512_CTX *ctx, uint16_t v) {
679   uint8_t buf[2] = {static_cast<uint8_t>(v >> 8),
680                     static_cast<uint8_t>(v & 0xff)};
681   SHA384_Update(ctx, buf, 2);
682 }
683 
sha384_update_point_with_length(SHA512_CTX * ctx,const EC_GROUP * group,const EC_AFFINE * point)684 static void sha384_update_point_with_length(SHA512_CTX *ctx,
685                                             const EC_GROUP *group,
686                                             const EC_AFFINE *point) {
687   uint8_t buf[EC_MAX_COMPRESSED];
688   size_t len = ec_point_to_bytes(group, point, POINT_CONVERSION_COMPRESSED, buf,
689                                  sizeof(buf));
690   assert(len > 0);
691   sha384_update_u16(ctx, (uint16_t)len);
692   SHA384_Update(ctx, buf, len);
693 }
694 
compute_composite_seed(const VOPRF_METHOD * method,uint8_t out[SHA384_DIGEST_LENGTH],const EC_AFFINE * pub)695 static int compute_composite_seed(const VOPRF_METHOD *method,
696                                   uint8_t out[SHA384_DIGEST_LENGTH],
697                                   const EC_AFFINE *pub) {
698   const EC_GROUP *group = method->group_func();
699   static const uint8_t kSeedDST[] = "Seed-OPRFV1-\x01-P384-SHA384";
700 
701   SHA512_CTX hash_ctx;
702   SHA384_Init(&hash_ctx);
703   sha384_update_point_with_length(&hash_ctx, group, pub);
704   sha384_update_u16(&hash_ctx, sizeof(kSeedDST) - 1);
705   SHA384_Update(&hash_ctx, kSeedDST, sizeof(kSeedDST) - 1);
706   SHA384_Final(out, &hash_ctx);
707 
708   return 1;
709 }
710 
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)711 static int compute_composite_element(const VOPRF_METHOD *method,
712                                      uint8_t seed[SHA384_DIGEST_LENGTH],
713                                      EC_SCALAR *di, size_t index,
714                                      const EC_AFFINE *C, const EC_AFFINE *D) {
715   static const uint8_t kCompositeLabel[] = "Composite";
716   const EC_GROUP *group = method->group_func();
717 
718   if (index > UINT16_MAX) {
719     return 0;
720   }
721 
722   CBB cbb;
723   uint8_t transcript[2 + SHA384_DIGEST_LENGTH + 2 + 2 * EC_MAX_COMPRESSED +
724                      sizeof(kCompositeLabel) - 1];
725   size_t len;
726   if (!CBB_init_fixed(&cbb, transcript, sizeof(transcript)) ||
727       !CBB_add_u16(&cbb, SHA384_DIGEST_LENGTH) ||
728       !CBB_add_bytes(&cbb, seed, SHA384_DIGEST_LENGTH) ||
729       !CBB_add_u16(&cbb, index) || !cbb_serialize_point(&cbb, group, C) ||
730       !cbb_serialize_point(&cbb, group, D) ||
731       !CBB_add_bytes(&cbb, kCompositeLabel, sizeof(kCompositeLabel) - 1) ||
732       !CBB_finish(&cbb, NULL, &len) ||
733       !method->hash_to_scalar(group, di, transcript, len)) {
734     return 0;
735   }
736 
737   return 1;
738 }
739 
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)740 static int generate_proof(const VOPRF_METHOD *method, CBB *cbb,
741                           const TRUST_TOKEN_ISSUER_KEY *priv,
742                           const EC_SCALAR *r, const EC_JACOBIAN *M,
743                           const EC_JACOBIAN *Z) {
744   const EC_GROUP *group = method->group_func();
745 
746   enum {
747     idx_M,
748     idx_Z,
749     idx_t2,
750     idx_t3,
751     num_idx,
752   };
753   EC_JACOBIAN jacobians[num_idx];
754 
755   if (!ec_point_mul_scalar_base(group, &jacobians[idx_t2], r) ||
756       !ec_point_mul_scalar(group, &jacobians[idx_t3], M, r)) {
757     return 0;
758   }
759 
760 
761   EC_AFFINE affines[num_idx];
762   jacobians[idx_M] = *M;
763   jacobians[idx_Z] = *Z;
764   if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) {
765     return 0;
766   }
767 
768   EC_SCALAR c;
769   if (!hash_to_scalar_challenge(method, &c, &priv->pubs, &affines[idx_M],
770                                 &affines[idx_Z], &affines[idx_t2],
771                                 &affines[idx_t3])) {
772     return 0;
773   }
774 
775   EC_SCALAR c_mont;
776   ec_scalar_to_montgomery(group, &c_mont, &c);
777 
778   // s = r - c*xs
779   EC_SCALAR s;
780   ec_scalar_mul_montgomery(group, &s, &priv->xs, &c_mont);
781   ec_scalar_sub(group, &s, r, &s);
782 
783   // Store DLEQ proof in transcript.
784   if (!scalar_to_cbb(cbb, group, &c) || !scalar_to_cbb(cbb, group, &s)) {
785     return 0;
786   }
787 
788   return 1;
789 }
790 
verify_proof(const VOPRF_METHOD * method,CBS * cbs,const TRUST_TOKEN_CLIENT_KEY * pub,const EC_JACOBIAN * M,const EC_JACOBIAN * Z)791 static int verify_proof(const VOPRF_METHOD *method, CBS *cbs,
792                         const TRUST_TOKEN_CLIENT_KEY *pub, const EC_JACOBIAN *M,
793                         const EC_JACOBIAN *Z) {
794   const EC_GROUP *group = method->group_func();
795 
796   enum {
797     idx_M,
798     idx_Z,
799     idx_t2,
800     idx_t3,
801     num_idx,
802   };
803   EC_JACOBIAN jacobians[num_idx];
804 
805   EC_SCALAR c, s;
806   if (!scalar_from_cbs(cbs, group, &c) || !scalar_from_cbs(cbs, group, &s)) {
807     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
808     return 0;
809   }
810 
811   EC_JACOBIAN pubs;
812   ec_affine_to_jacobian(group, &pubs, &pub->pubs);
813   if (!ec_point_mul_scalar_public(group, &jacobians[idx_t2], &s, &pubs, &c) ||
814       !mul_public_2(group, &jacobians[idx_t3], M, &s, Z, &c)) {
815     return 0;
816   }
817 
818   EC_AFFINE affines[num_idx];
819   jacobians[idx_M] = *M;
820   jacobians[idx_Z] = *Z;
821   if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) {
822     return 0;
823   }
824 
825   EC_SCALAR expected_c;
826   if (!hash_to_scalar_challenge(method, &expected_c, &pub->pubs,
827                                 &affines[idx_M], &affines[idx_Z],
828                                 &affines[idx_t2], &affines[idx_t3])) {
829     return 0;
830   }
831 
832   // c == expected_c
833   if (!ec_scalar_equal_vartime(group, &c, &expected_c)) {
834     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_PROOF);
835     return 0;
836   }
837 
838   return 1;
839 }
840 
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)841 static int voprf_sign_impl(const VOPRF_METHOD *method,
842                            const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb,
843                            CBS *cbs, size_t num_requested, size_t num_to_issue,
844                            const EC_SCALAR *proof_scalar) {
845   const EC_GROUP *group = method->group_func();
846   if (num_requested < num_to_issue) {
847     OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
848     return 0;
849   }
850 
851   int ret = 0;
852   EC_JACOBIAN *BTs = reinterpret_cast<EC_JACOBIAN *>(
853       OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN)));
854   EC_JACOBIAN *Zs = reinterpret_cast<EC_JACOBIAN *>(
855       OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN)));
856   EC_SCALAR *dis = reinterpret_cast<EC_SCALAR *>(
857       OPENSSL_calloc(num_to_issue, sizeof(EC_SCALAR)));
858 
859   {
860     if (!BTs || !Zs || !dis) {
861       goto err;
862     }
863 
864     uint8_t seed[SHA384_DIGEST_LENGTH];
865     if (!compute_composite_seed(method, seed, &key->pubs)) {
866       goto err;
867     }
868 
869     // This implements the BlindEvaluateBatch as defined in section 4 of
870     // draft-robert-privacypass-batched-tokens-01, based on the constructions
871     // in draft-irtf-cfrg-voprf-21. To optimize the computation of the proof,
872     // the computation of di is done during the token signing and passed into
873     // the proof generation.
874     for (size_t i = 0; i < num_to_issue; i++) {
875       EC_AFFINE BT_affine, Z_affine;
876       EC_JACOBIAN BT, Z;
877       if (!cbs_get_point(cbs, group, &BT_affine)) {
878         OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
879         goto err;
880       }
881       ec_affine_to_jacobian(group, &BT, &BT_affine);
882       if (!ec_point_mul_scalar(group, &Z, &BT, &key->xs) ||
883           !ec_jacobian_to_affine(group, &Z_affine, &Z) ||
884           !cbb_add_point(cbb, group, &Z_affine)) {
885         goto err;
886       }
887       BTs[i] = BT;
888       Zs[i] = Z;
889       if (!compute_composite_element(method, seed, &dis[i], i, &BT_affine,
890                                      &Z_affine)) {
891         goto err;
892       }
893 
894       if (!CBB_flush(cbb)) {
895         goto err;
896       }
897     }
898 
899     EC_JACOBIAN M, Z;
900     if (!ec_point_mul_scalar_public_batch(group, &M,
901                                           /*g_scalar=*/NULL, BTs, dis,
902                                           num_to_issue) ||
903         !ec_point_mul_scalar(group, &Z, &M, &key->xs)) {
904       goto err;
905     }
906 
907     CBB proof;
908     if (!CBB_add_u16_length_prefixed(cbb, &proof) ||
909         !generate_proof(method, &proof, key, proof_scalar, &M, &Z) ||
910         !CBB_flush(cbb)) {
911       goto err;
912     }
913 
914     // Skip over any unused requests.
915     size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
916     if (!CBS_skip(cbs, point_len * (num_requested - num_to_issue))) {
917       OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
918       goto err;
919     }
920 
921     ret = 1;
922   }
923 
924 err:
925   OPENSSL_free(BTs);
926   OPENSSL_free(Zs);
927   OPENSSL_free(dis);
928   return ret;
929 }
930 
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)931 static int voprf_sign(const VOPRF_METHOD *method,
932                       const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
933                       size_t num_requested, size_t num_to_issue) {
934   EC_SCALAR proof_scalar;
935   if (!ec_random_nonzero_scalar(method->group_func(), &proof_scalar,
936                                 kDefaultAdditionalData)) {
937     return 0;
938   }
939 
940   return voprf_sign_impl(method, key, cbb, cbs, num_requested, num_to_issue,
941                          &proof_scalar);
942 }
943 
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)944 static int voprf_sign_with_proof_scalar_for_testing(
945     const VOPRF_METHOD *method, const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb,
946     CBS *cbs, size_t num_requested, size_t num_to_issue,
947     const uint8_t *proof_scalar_buf, size_t proof_scalar_len) {
948   EC_SCALAR proof_scalar;
949   if (!ec_scalar_from_bytes(method->group_func(), &proof_scalar,
950                             proof_scalar_buf, proof_scalar_len)) {
951     return 0;
952   }
953   return voprf_sign_impl(method, key, cbb, cbs, num_requested, num_to_issue,
954                          &proof_scalar);
955 }
956 
STACK_OF(TRUST_TOKEN)957 static STACK_OF(TRUST_TOKEN) *voprf_unblind(
958     const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key,
959     const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
960     uint32_t key_id) {
961   const EC_GROUP *group = method->group_func();
962   if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) {
963     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
964     return NULL;
965   }
966 
967   int ok = 0;
968   STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null();
969   EC_JACOBIAN *BTs = reinterpret_cast<EC_JACOBIAN *>(
970       OPENSSL_calloc(count, sizeof(EC_JACOBIAN)));
971   EC_JACOBIAN *Zs = reinterpret_cast<EC_JACOBIAN *>(
972       OPENSSL_calloc(count, sizeof(EC_JACOBIAN)));
973   EC_SCALAR *dis =
974       reinterpret_cast<EC_SCALAR *>(OPENSSL_calloc(count, sizeof(EC_SCALAR)));
975   if (ret == NULL || !BTs || !Zs || !dis) {
976     goto err;
977   }
978 
979   uint8_t seed[SHA384_DIGEST_LENGTH];
980   if (!compute_composite_seed(method, seed, &key->pubs)) {
981     goto err;
982   }
983 
984   for (size_t i = 0; i < count; i++) {
985     const TRUST_TOKEN_PRETOKEN *pretoken =
986         sk_TRUST_TOKEN_PRETOKEN_value(pretokens, i);
987 
988     EC_AFFINE Z_affine;
989     if (!cbs_get_point(cbs, group, &Z_affine)) {
990       OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
991       goto err;
992     }
993 
994     ec_affine_to_jacobian(group, &BTs[i], &pretoken->Tp);
995     ec_affine_to_jacobian(group, &Zs[i], &Z_affine);
996     if (!compute_composite_element(method, seed, &dis[i], i, &pretoken->Tp,
997                                    &Z_affine)) {
998       goto err;
999     }
1000 
1001     // Unblind the token.
1002     // pretoken->r is rinv.
1003     EC_JACOBIAN N;
1004     EC_AFFINE N_affine;
1005     if (!ec_point_mul_scalar(group, &N, &Zs[i], &pretoken->r) ||
1006         !ec_jacobian_to_affine(group, &N_affine, &N)) {
1007       goto err;
1008     }
1009 
1010     // Serialize the token. Include |key_id| to avoid an extra copy in the layer
1011     // above.
1012     CBB token_cbb;
1013     size_t point_len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
1014     if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + (2 + point_len)) ||
1015         !CBB_add_u32(&token_cbb, key_id) ||
1016         !CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) ||
1017         !cbb_add_point(&token_cbb, group, &N_affine) ||
1018         !CBB_flush(&token_cbb)) {
1019       CBB_cleanup(&token_cbb);
1020       goto err;
1021     }
1022 
1023     TRUST_TOKEN *token =
1024         TRUST_TOKEN_new(CBB_data(&token_cbb), CBB_len(&token_cbb));
1025     CBB_cleanup(&token_cbb);
1026     if (token == NULL || !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, count) ||
1035       !ec_point_mul_scalar_public_batch(group, &Z,
1036                                         /*g_scalar=*/NULL, Zs, dis, count)) {
1037     goto err;
1038   }
1039 
1040   CBS proof;
1041   if (!CBS_get_u16_length_prefixed(cbs, &proof) ||
1042       !verify_proof(method, &proof, key, &M, &Z) || CBS_len(&proof) != 0) {
1043     goto err;
1044   }
1045 
1046   ok = 1;
1047 
1048 err:
1049   OPENSSL_free(BTs);
1050   OPENSSL_free(Zs);
1051   OPENSSL_free(dis);
1052   if (!ok) {
1053     sk_TRUST_TOKEN_pop_free(ret, TRUST_TOKEN_free);
1054     ret = NULL;
1055   }
1056   return ret;
1057 }
1058 
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)1059 static int voprf_read(const VOPRF_METHOD *method,
1060                       const TRUST_TOKEN_ISSUER_KEY *key,
1061                       uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],
1062                       const uint8_t *token, size_t token_len,
1063                       int include_message, const uint8_t *msg, size_t msg_len) {
1064   const EC_GROUP *group = method->group_func();
1065   CBS cbs, salt;
1066   CBS_init(&cbs, token, token_len);
1067   EC_AFFINE Ws;
1068   if (!CBS_get_bytes(&cbs, &salt, TRUST_TOKEN_NONCE_SIZE) ||
1069       !cbs_get_point(&cbs, group, &Ws) || CBS_len(&cbs) != 0) {
1070     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
1071     return 0;
1072   }
1073 
1074   if (include_message) {
1075     SHA512_CTX hash_ctx;
1076     assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE);
1077     SHA512_Init(&hash_ctx);
1078     SHA512_Update(&hash_ctx, CBS_data(&salt), CBS_len(&salt));
1079     SHA512_Update(&hash_ctx, msg, msg_len);
1080     SHA512_Final(out_nonce, &hash_ctx);
1081   } else {
1082     OPENSSL_memcpy(out_nonce, CBS_data(&salt), CBS_len(&salt));
1083   }
1084 
1085 
1086   EC_JACOBIAN T;
1087   if (!method->hash_to_group(group, &T, out_nonce)) {
1088     return 0;
1089   }
1090 
1091   EC_JACOBIAN Ws_calculated;
1092   if (!ec_point_mul_scalar(group, &Ws_calculated, &T, &key->xs) ||
1093       !ec_affine_jacobian_equal(group, &Ws, &Ws_calculated)) {
1094     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BAD_VALIDITY_CHECK);
1095     return 0;
1096   }
1097 
1098   return 1;
1099 }
1100 
1101 
1102 // VOPRF experiment v2.
1103 
voprf_exp2_hash_to_group(const EC_GROUP * group,EC_JACOBIAN * out,const uint8_t t[TRUST_TOKEN_NONCE_SIZE])1104 static int voprf_exp2_hash_to_group(const EC_GROUP *group, EC_JACOBIAN *out,
1105                                     const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) {
1106   const uint8_t kHashTLabel[] = "TrustToken VOPRF Experiment V2 HashToGroup";
1107   return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(
1108       group, out, kHashTLabel, sizeof(kHashTLabel), t, TRUST_TOKEN_NONCE_SIZE);
1109 }
1110 
voprf_exp2_hash_to_scalar(const EC_GROUP * group,EC_SCALAR * out,uint8_t * buf,size_t len)1111 static int voprf_exp2_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
1112                                      uint8_t *buf, size_t len) {
1113   const uint8_t kHashCLabel[] = "TrustToken VOPRF Experiment V2 HashToScalar";
1114   return ec_hash_to_scalar_p384_xmd_sha512_draft07(
1115       group, out, kHashCLabel, sizeof(kHashCLabel), buf, len);
1116 }
1117 
1118 static VOPRF_METHOD voprf_exp2_method = {
1119     EC_group_p384, voprf_exp2_hash_to_group, voprf_exp2_hash_to_scalar};
1120 
voprf_exp2_generate_key(CBB * out_private,CBB * out_public)1121 int voprf_exp2_generate_key(CBB *out_private, CBB *out_public) {
1122   return voprf_generate_key(&voprf_exp2_method, out_private, out_public);
1123 }
1124 
voprf_exp2_derive_key_from_secret(CBB * out_private,CBB * out_public,const uint8_t * secret,size_t secret_len)1125 int voprf_exp2_derive_key_from_secret(CBB *out_private, CBB *out_public,
1126                                       const uint8_t *secret,
1127                                       size_t secret_len) {
1128   return voprf_derive_key_from_secret(&voprf_exp2_method, out_private,
1129                                       out_public, secret, secret_len);
1130 }
1131 
voprf_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY * key,const uint8_t * in,size_t len)1132 int voprf_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key,
1133                                      const uint8_t *in, size_t len) {
1134   return voprf_client_key_from_bytes(&voprf_exp2_method, key, in, len);
1135 }
1136 
voprf_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY * key,const uint8_t * in,size_t len)1137 int voprf_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key,
1138                                      const uint8_t *in, size_t len) {
1139   return voprf_issuer_key_from_bytes(&voprf_exp2_method, key, in, len);
1140 }
1141 
STACK_OF(TRUST_TOKEN_PRETOKEN)1142 STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_exp2_blind(CBB *cbb, size_t count,
1143                                                  int include_message,
1144                                                  const uint8_t *msg,
1145                                                  size_t msg_len) {
1146   return voprf_blind(&voprf_exp2_method, cbb, count, include_message, msg,
1147                      msg_len);
1148 }
1149 
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)1150 int voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
1151                     size_t num_requested, size_t num_to_issue,
1152                     uint8_t private_metadata) {
1153   if (private_metadata != 0) {
1154     return 0;
1155   }
1156   return voprf_sign_tt(&voprf_exp2_method, key, cbb, cbs, num_requested,
1157                        num_to_issue);
1158 }
1159 
STACK_OF(TRUST_TOKEN)1160 STACK_OF(TRUST_TOKEN) *voprf_exp2_unblind(
1161     const TRUST_TOKEN_CLIENT_KEY *key,
1162     const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
1163     uint32_t key_id) {
1164   return voprf_unblind_tt(&voprf_exp2_method, key, pretokens, cbs, count,
1165                           key_id);
1166 }
1167 
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)1168 int voprf_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key,
1169                     uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],
1170                     uint8_t *out_private_metadata, const uint8_t *token,
1171                     size_t token_len, int include_message, const uint8_t *msg,
1172                     size_t msg_len) {
1173   return voprf_read(&voprf_exp2_method, key, out_nonce, token, token_len,
1174                     include_message, msg, msg_len);
1175 }
1176 
1177 // VOPRF PST v1.
1178 
voprf_pst1_hash_to_group(const EC_GROUP * group,EC_JACOBIAN * out,const uint8_t t[TRUST_TOKEN_NONCE_SIZE])1179 static int voprf_pst1_hash_to_group(const EC_GROUP *group, EC_JACOBIAN *out,
1180                                     const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) {
1181   const uint8_t kHashTLabel[] = "HashToGroup-OPRFV1-\x01-P384-SHA384";
1182   return ec_hash_to_curve_p384_xmd_sha384_sswu(group, out, kHashTLabel,
1183                                                sizeof(kHashTLabel) - 1, t,
1184                                                TRUST_TOKEN_NONCE_SIZE);
1185 }
1186 
voprf_pst1_hash_to_scalar(const EC_GROUP * group,EC_SCALAR * out,uint8_t * buf,size_t len)1187 static int voprf_pst1_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
1188                                      uint8_t *buf, size_t len) {
1189   const uint8_t kHashCLabel[] = "HashToScalar-OPRFV1-\x01-P384-SHA384";
1190   return ec_hash_to_scalar_p384_xmd_sha384(group, out, kHashCLabel,
1191                                            sizeof(kHashCLabel) - 1, buf, len);
1192 }
1193 
1194 static VOPRF_METHOD voprf_pst1_method = {
1195     EC_group_p384, voprf_pst1_hash_to_group, voprf_pst1_hash_to_scalar};
1196 
voprf_pst1_generate_key(CBB * out_private,CBB * out_public)1197 int voprf_pst1_generate_key(CBB *out_private, CBB *out_public) {
1198   return voprf_generate_key(&voprf_pst1_method, out_private, out_public);
1199 }
1200 
voprf_pst1_derive_key_from_secret(CBB * out_private,CBB * out_public,const uint8_t * secret,size_t secret_len)1201 int voprf_pst1_derive_key_from_secret(CBB *out_private, CBB *out_public,
1202                                       const uint8_t *secret,
1203                                       size_t secret_len) {
1204   return voprf_derive_key_from_secret(&voprf_pst1_method, out_private,
1205                                       out_public, secret, secret_len);
1206 }
1207 
voprf_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY * key,const uint8_t * in,size_t len)1208 int voprf_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key,
1209                                      const uint8_t *in, size_t len) {
1210   return voprf_client_key_from_bytes(&voprf_pst1_method, key, in, len);
1211 }
1212 
voprf_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY * key,const uint8_t * in,size_t len)1213 int voprf_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key,
1214                                      const uint8_t *in, size_t len) {
1215   return voprf_issuer_key_from_bytes(&voprf_pst1_method, key, in, len);
1216 }
1217 
STACK_OF(TRUST_TOKEN_PRETOKEN)1218 STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_pst1_blind(CBB *cbb, size_t count,
1219                                                  int include_message,
1220                                                  const uint8_t *msg,
1221                                                  size_t msg_len) {
1222   return voprf_blind(&voprf_pst1_method, cbb, count, include_message, msg,
1223                      msg_len);
1224 }
1225 
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)1226 int voprf_pst1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
1227                     size_t num_requested, size_t num_to_issue,
1228                     uint8_t private_metadata) {
1229   if (private_metadata != 0) {
1230     return 0;
1231   }
1232   return voprf_sign(&voprf_pst1_method, key, cbb, cbs, num_requested,
1233                     num_to_issue);
1234 }
1235 
1236 
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)1237 int voprf_pst1_sign_with_proof_scalar_for_testing(
1238     const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, size_t num_requested,
1239     size_t num_to_issue, uint8_t private_metadata,
1240     const uint8_t *proof_scalar_buf, size_t proof_scalar_len) {
1241   if (private_metadata != 0) {
1242     return 0;
1243   }
1244   return voprf_sign_with_proof_scalar_for_testing(
1245       &voprf_pst1_method, key, cbb, cbs, num_requested, num_to_issue,
1246       proof_scalar_buf, proof_scalar_len);
1247 }
1248 
STACK_OF(TRUST_TOKEN)1249 STACK_OF(TRUST_TOKEN) *voprf_pst1_unblind(
1250     const TRUST_TOKEN_CLIENT_KEY *key,
1251     const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
1252     uint32_t key_id) {
1253   return voprf_unblind(&voprf_pst1_method, key, pretokens, cbs, count, key_id);
1254 }
1255 
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)1256 int voprf_pst1_read(const TRUST_TOKEN_ISSUER_KEY *key,
1257                     uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],
1258                     uint8_t *out_private_metadata, const uint8_t *token,
1259                     size_t token_len, int include_message, const uint8_t *msg,
1260                     size_t msg_len) {
1261   return voprf_read(&voprf_pst1_method, key, out_nonce, token, token_len,
1262                     include_message, msg, msg_len);
1263 }
1264