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