• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2019, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <map>
16 #include <string>
17 #include <vector>
18 
19 #include <assert.h>
20 #include <errno.h>
21 #include <limits.h>
22 #include <string.h>
23 #include <sys/uio.h>
24 #include <unistd.h>
25 #include <cstdarg>
26 
27 #include <openssl/aead.h>
28 #include <openssl/aes.h>
29 #include <openssl/bn.h>
30 #include <openssl/cipher.h>
31 #include <openssl/cmac.h>
32 #include <openssl/ctrdrbg.h>
33 #include <openssl/dh.h>
34 #include <openssl/digest.h>
35 #include <openssl/ec.h>
36 #include <openssl/ec_key.h>
37 #include <openssl/ecdh.h>
38 #include <openssl/ecdsa.h>
39 #include <openssl/err.h>
40 #include <openssl/hmac.h>
41 #include <openssl/obj.h>
42 #include <openssl/rsa.h>
43 #include <openssl/sha.h>
44 #include <openssl/span.h>
45 
46 #include "../../../../crypto/fipsmodule/ec/internal.h"
47 #include "../../../../crypto/fipsmodule/rand/internal.h"
48 #include "../../../../crypto/fipsmodule/tls/internal.h"
49 #include "modulewrapper.h"
50 
51 
52 namespace bssl {
53 namespace acvp {
54 
55 #if defined(OPENSSL_TRUSTY)
56 #include <trusty_log.h>
57 #define LOG_ERROR(...) TLOGE(__VA_ARGS__)
58 #define TLOG_TAG "modulewrapper"
59 #else
60 #define LOG_ERROR(...) fprintf(stderr, __VA_ARGS__)
61 #endif  // OPENSSL_TRUSTY
62 
63 constexpr size_t kMaxArgLength = (1 << 20);
64 
65 RequestBuffer::~RequestBuffer() = default;
66 
67 class RequestBufferImpl : public RequestBuffer {
68  public:
69   ~RequestBufferImpl() = default;
70 
71   std::vector<uint8_t> buf;
72   Span<const uint8_t> args[kMaxArgs];
73 };
74 
75 // static
New()76 std::unique_ptr<RequestBuffer> RequestBuffer::New() {
77   return std::unique_ptr<RequestBuffer>(new RequestBufferImpl);
78 }
79 
ReadAll(int fd,void * in_data,size_t data_len)80 static bool ReadAll(int fd, void *in_data, size_t data_len) {
81   uint8_t *data = reinterpret_cast<uint8_t *>(in_data);
82   size_t done = 0;
83 
84   while (done < data_len) {
85     ssize_t r;
86     do {
87       r = read(fd, &data[done], data_len - done);
88     } while (r == -1 && errno == EINTR);
89 
90     if (r <= 0) {
91       return false;
92     }
93 
94     done += r;
95   }
96 
97   return true;
98 }
99 
ParseArgsFromFd(int fd,RequestBuffer * in_buffer)100 Span<const Span<const uint8_t>> ParseArgsFromFd(int fd,
101                                                 RequestBuffer *in_buffer) {
102   RequestBufferImpl *buffer = reinterpret_cast<RequestBufferImpl *>(in_buffer);
103   uint32_t nums[1 + kMaxArgs];
104   const Span<const Span<const uint8_t>> empty_span;
105 
106   if (!ReadAll(fd, nums, sizeof(uint32_t) * 2)) {
107     return empty_span;
108   }
109 
110   const size_t num_args = nums[0];
111   if (num_args == 0) {
112     LOG_ERROR("Invalid, zero-argument operation requested.\n");
113     return empty_span;
114   } else if (num_args > kMaxArgs) {
115     LOG_ERROR("Operation requested with %zu args, but %zu is the limit.\n",
116               num_args, kMaxArgs);
117     return empty_span;
118   }
119 
120   if (num_args > 1 &&
121       !ReadAll(fd, &nums[2], sizeof(uint32_t) * (num_args - 1))) {
122     return empty_span;
123   }
124 
125   size_t need = 0;
126   for (size_t i = 0; i < num_args; i++) {
127     const size_t arg_length = nums[i + 1];
128     if (i == 0 && arg_length > kMaxNameLength) {
129       LOG_ERROR("Operation with name of length %zu exceeded limit of %zu.\n",
130                 arg_length, kMaxNameLength);
131       return empty_span;
132     } else if (arg_length > kMaxArgLength) {
133       LOG_ERROR(
134           "Operation with argument of length %zu exceeded limit of %zu.\n",
135           arg_length, kMaxArgLength);
136       return empty_span;
137     }
138 
139     // This static_assert confirms that the following addition doesn't
140     // overflow.
141     static_assert((kMaxArgs - 1 * kMaxArgLength) + kMaxNameLength > (1 << 30),
142                   "Argument limits permit excessive messages");
143     need += arg_length;
144   }
145 
146   if (need > buffer->buf.size()) {
147     size_t alloced = need + (need >> 1);
148     if (alloced < need) {
149       abort();
150     }
151     buffer->buf.resize(alloced);
152   }
153 
154   if (!ReadAll(fd, buffer->buf.data(), need)) {
155     return empty_span;
156   }
157 
158   size_t offset = 0;
159   for (size_t i = 0; i < num_args; i++) {
160     buffer->args[i] = Span<const uint8_t>(&buffer->buf[offset], nums[i + 1]);
161     offset += nums[i + 1];
162   }
163 
164   return Span<const Span<const uint8_t>>(buffer->args, num_args);
165 }
166 
WriteReplyToFd(int fd,const std::vector<Span<const uint8_t>> & spans)167 bool WriteReplyToFd(int fd, const std::vector<Span<const uint8_t>> &spans) {
168   if (spans.empty() || spans.size() > kMaxArgs) {
169     abort();
170   }
171 
172   uint32_t nums[1 + kMaxArgs];
173   iovec iovs[kMaxArgs + 1];
174   nums[0] = spans.size();
175   iovs[0].iov_base = nums;
176   iovs[0].iov_len = sizeof(uint32_t) * (1 + spans.size());
177 
178   size_t num_iov = 1;
179   for (size_t i = 0; i < spans.size(); i++) {
180     const auto &span = spans[i];
181     nums[i + 1] = span.size();
182     if (span.empty()) {
183       continue;
184     }
185 
186     iovs[num_iov].iov_base = const_cast<uint8_t *>(span.data());
187     iovs[num_iov].iov_len = span.size();
188     num_iov++;
189   }
190 
191   size_t iov_done = 0;
192   while (iov_done < num_iov) {
193     ssize_t r;
194     do {
195       r = writev(fd, &iovs[iov_done], num_iov - iov_done);
196     } while (r == -1 && errno == EINTR);
197 
198     if (r <= 0) {
199       return false;
200     }
201 
202     size_t written = r;
203     for (size_t i = iov_done; i < num_iov && written > 0; i++) {
204       iovec &iov = iovs[i];
205 
206       size_t done = written;
207       if (done > iov.iov_len) {
208         done = iov.iov_len;
209       }
210 
211       iov.iov_base = reinterpret_cast<uint8_t *>(iov.iov_base) + done;
212       iov.iov_len -= done;
213       written -= done;
214 
215       if (iov.iov_len == 0) {
216         iov_done++;
217       }
218     }
219 
220     assert(written == 0);
221   }
222 
223   return true;
224 }
225 
GetConfig(const Span<const uint8_t> args[],ReplyCallback write_reply)226 static bool GetConfig(const Span<const uint8_t> args[], ReplyCallback write_reply) {
227   static constexpr char kConfig[] =
228       R"([
229       {
230         "algorithm": "SHA2-224",
231         "revision": "1.0",
232         "messageLength": [{
233           "min": 0, "max": 65528, "increment": 8
234         }]
235       },
236       {
237         "algorithm": "SHA2-256",
238         "revision": "1.0",
239         "messageLength": [{
240           "min": 0, "max": 65528, "increment": 8
241         }]
242       },
243       {
244         "algorithm": "SHA2-384",
245         "revision": "1.0",
246         "messageLength": [{
247           "min": 0, "max": 65528, "increment": 8
248         }]
249       },
250       {
251         "algorithm": "SHA2-512",
252         "revision": "1.0",
253         "messageLength": [{
254           "min": 0, "max": 65528, "increment": 8
255         }]
256       },
257       {
258         "algorithm": "SHA2-512/256",
259         "revision": "1.0",
260         "messageLength": [{
261           "min": 0, "max": 65528, "increment": 8
262         }]
263       },
264       {
265         "algorithm": "SHA-1",
266         "revision": "1.0",
267         "messageLength": [{
268           "min": 0, "max": 65528, "increment": 8
269         }]
270       },
271       {
272         "algorithm": "ACVP-AES-ECB",
273         "revision": "1.0",
274         "direction": ["encrypt", "decrypt"],
275         "keyLen": [128, 192, 256]
276       },
277       {
278         "algorithm": "ACVP-AES-CTR",
279         "revision": "1.0",
280         "direction": ["encrypt", "decrypt"],
281         "keyLen": [128, 192, 256],
282         "payloadLen": [{
283           "min": 8, "max": 128, "increment": 8
284         }],
285         "incrementalCounter": true,
286         "overflowCounter": true,
287         "performCounterTests": true
288       },
289       {
290         "algorithm": "ACVP-AES-CBC",
291         "revision": "1.0",
292         "direction": ["encrypt", "decrypt"],
293         "keyLen": [128, 192, 256]
294       },
295       {
296         "algorithm": "ACVP-AES-GCM",
297         "revision": "1.0",
298         "direction": ["encrypt", "decrypt"],
299         "keyLen": [128, 192, 256],
300         "payloadLen": [{
301           "min": 0, "max": 65536, "increment": 8
302         }],
303         "aadLen": [{
304           "min": 0, "max": 65536, "increment": 8
305         }],
306         "tagLen": [32, 64, 96, 104, 112, 120, 128],
307         "ivLen": [96],
308         "ivGen": "external"
309       },
310       {
311         "algorithm": "ACVP-AES-GMAC",
312         "revision": "1.0",
313         "direction": ["encrypt", "decrypt"],
314         "keyLen": [128, 192, 256],
315         "payloadLen": [{
316           "min": 0, "max": 65536, "increment": 8
317         }],
318         "aadLen": [{
319           "min": 0, "max": 65536, "increment": 8
320         }],
321         "tagLen": [32, 64, 96, 104, 112, 120, 128],
322         "ivLen": [96],
323         "ivGen": "external"
324       },
325       {
326         "algorithm": "ACVP-AES-KW",
327         "revision": "1.0",
328         "direction": [
329             "encrypt",
330             "decrypt"
331         ],
332         "kwCipher": [
333             "cipher"
334         ],
335         "keyLen": [
336             128, 192, 256
337         ],
338         "payloadLen": [{"min": 128, "max": 4096, "increment": 64}]
339       },
340       {
341         "algorithm": "ACVP-AES-KWP",
342         "revision": "1.0",
343         "direction": [
344             "encrypt",
345             "decrypt"
346         ],
347         "kwCipher": [
348             "cipher"
349         ],
350         "keyLen": [
351             128, 192, 256
352         ],
353         "payloadLen": [{"min": 8, "max": 4096, "increment": 8}]
354       },
355       {
356         "algorithm": "ACVP-AES-CCM",
357         "revision": "1.0",
358         "direction": [
359             "encrypt",
360             "decrypt"
361         ],
362         "keyLen": [
363             128
364         ],
365         "payloadLen": [{"min": 0, "max": 256, "increment": 8}],
366         "ivLen": [104],
367         "tagLen": [32, 64],
368         "aadLen": [{"min": 0, "max": 524288, "increment": 8}]
369       },
370       {
371         "algorithm": "HMAC-SHA-1",
372         "revision": "1.0",
373         "keyLen": [{
374           "min": 8, "max": 524288, "increment": 8
375         }],
376         "macLen": [{
377           "min": 32, "max": 160, "increment": 8
378         }]
379       },
380       {
381         "algorithm": "HMAC-SHA2-224",
382         "revision": "1.0",
383         "keyLen": [{
384           "min": 8, "max": 524288, "increment": 8
385         }],
386         "macLen": [{
387           "min": 32, "max": 224, "increment": 8
388         }]
389       },
390       {
391         "algorithm": "HMAC-SHA2-256",
392         "revision": "1.0",
393         "keyLen": [{
394           "min": 8, "max": 524288, "increment": 8
395         }],
396         "macLen": [{
397           "min": 32, "max": 256, "increment": 8
398         }]
399       },
400       {
401         "algorithm": "HMAC-SHA2-384",
402         "revision": "1.0",
403         "keyLen": [{
404           "min": 8, "max": 524288, "increment": 8
405         }],
406         "macLen": [{
407           "min": 32, "max": 384, "increment": 8
408         }]
409       },
410       {
411         "algorithm": "HMAC-SHA2-512",
412         "revision": "1.0",
413         "keyLen": [{
414           "min": 8, "max": 524288, "increment": 8
415         }],
416         "macLen": [{
417           "min": 32, "max": 512, "increment": 8
418         }]
419       },
420       {
421         "algorithm": "HMAC-SHA2-512/256",
422         "revision": "1.0",
423         "keyLen": [{
424           "min": 8, "max": 524288, "increment": 8
425         }],
426         "macLen": [{
427           "min": 32, "max": 256, "increment": 8
428         }]
429       },
430       {
431         "algorithm": "ctrDRBG",
432         "revision": "1.0",
433         "predResistanceEnabled": [false],
434         "reseedImplemented": true,
435         "capabilities": [{
436           "mode": "AES-256",
437           "derFuncEnabled": false,
438           "entropyInputLen": [384],
439           "nonceLen": [0],
440           "persoStringLen": [{"min": 0, "max": 384, "increment": 16}],
441           "additionalInputLen": [
442             {"min": 0, "max": 384, "increment": 16}
443           ],
444           "returnedBitsLen": 2048
445         }]
446       },
447       {
448         "algorithm": "ECDSA",
449         "mode": "keyGen",
450         "revision": "1.0",
451         "curve": [
452           "P-224",
453           "P-256",
454           "P-384",
455           "P-521"
456         ],
457         "secretGenerationMode": [
458           "testing candidates"
459         ]
460       },
461       {
462         "algorithm": "ECDSA",
463         "mode": "keyVer",
464         "revision": "1.0",
465         "curve": [
466           "P-224",
467           "P-256",
468           "P-384",
469           "P-521"
470         ]
471       },
472       {
473         "algorithm": "ECDSA",
474         "mode": "sigGen",
475         "revision": "1.0",
476         "capabilities": [{
477           "curve": [
478             "P-224",
479             "P-256",
480             "P-384",
481             "P-521"
482           ],
483           "hashAlg": [
484             "SHA2-224",
485             "SHA2-256",
486             "SHA2-384",
487             "SHA2-512",
488             "SHA2-512/256"
489           ]
490         }]
491       },
492       {
493         "algorithm": "ECDSA",
494         "mode": "sigVer",
495         "revision": "1.0",
496         "capabilities": [{
497           "curve": [
498             "P-224",
499             "P-256",
500             "P-384",
501             "P-521"
502           ],
503           "hashAlg": [
504             "SHA-1",
505             "SHA2-224",
506             "SHA2-256",
507             "SHA2-384",
508             "SHA2-512",
509             "SHA2-512/256"
510           ]
511         }]
512       },
513       {
514         "algorithm": "RSA",
515         "mode": "keyGen",
516         "revision": "FIPS186-4",
517         "infoGeneratedByServer": true,
518         "pubExpMode": "fixed",
519         "fixedPubExp": "010001",
520         "keyFormat": "standard",
521         "capabilities": [{
522           "randPQ": "B.3.3",
523           "properties": [{
524             "modulo": 2048,
525             "primeTest": [
526               "tblC2"
527             ]
528           },{
529             "modulo": 3072,
530             "primeTest": [
531               "tblC2"
532             ]
533           },{
534             "modulo": 4096,
535             "primeTest": [
536               "tblC2"
537             ]
538           }]
539         }]
540       },
541       {
542         "algorithm": "RSA",
543         "mode": "sigGen",
544         "revision": "FIPS186-4",
545         "capabilities": [{
546           "sigType": "pkcs1v1.5",
547           "properties": [{
548             "modulo": 2048,
549             "hashPair": [{
550               "hashAlg": "SHA2-224"
551             }, {
552               "hashAlg": "SHA2-256"
553             }, {
554               "hashAlg": "SHA2-384"
555             }, {
556               "hashAlg": "SHA2-512"
557             }]
558           }]
559         },{
560           "sigType": "pkcs1v1.5",
561           "properties": [{
562             "modulo": 3072,
563             "hashPair": [{
564               "hashAlg": "SHA2-224"
565             }, {
566               "hashAlg": "SHA2-256"
567             }, {
568               "hashAlg": "SHA2-384"
569             }, {
570               "hashAlg": "SHA2-512"
571             }]
572           }]
573         },{
574           "sigType": "pkcs1v1.5",
575           "properties": [{
576             "modulo": 4096,
577             "hashPair": [{
578               "hashAlg": "SHA2-224"
579             }, {
580               "hashAlg": "SHA2-256"
581             }, {
582               "hashAlg": "SHA2-384"
583             }, {
584               "hashAlg": "SHA2-512"
585             }]
586           }]
587         },{
588           "sigType": "pss",
589           "properties": [{
590             "modulo": 2048,
591             "hashPair": [{
592               "hashAlg": "SHA2-224",
593               "saltLen": 28
594             }, {
595               "hashAlg": "SHA2-256",
596               "saltLen": 32
597             }, {
598               "hashAlg": "SHA2-384",
599               "saltLen": 48
600             }, {
601               "hashAlg": "SHA2-512",
602               "saltLen": 64
603             }, {
604               "hashAlg": "SHA2-512/256",
605               "saltLen": 32
606             }]
607           }]
608         },{
609           "sigType": "pss",
610           "properties": [{
611             "modulo": 3072,
612             "hashPair": [{
613               "hashAlg": "SHA2-224",
614               "saltLen": 28
615             }, {
616               "hashAlg": "SHA2-256",
617               "saltLen": 32
618             }, {
619               "hashAlg": "SHA2-384",
620               "saltLen": 48
621             }, {
622               "hashAlg": "SHA2-512",
623               "saltLen": 64
624             }, {
625               "hashAlg": "SHA2-512/256",
626               "saltLen": 32
627             }]
628           }]
629         },{
630           "sigType": "pss",
631           "properties": [{
632             "modulo": 4096,
633             "hashPair": [{
634               "hashAlg": "SHA2-224",
635               "saltLen": 28
636             }, {
637               "hashAlg": "SHA2-256",
638               "saltLen": 32
639             }, {
640               "hashAlg": "SHA2-384",
641               "saltLen": 48
642             }, {
643               "hashAlg": "SHA2-512",
644               "saltLen": 64
645             }, {
646               "hashAlg": "SHA2-512/256",
647               "saltLen": 32
648             }]
649           }]
650         }]
651       },
652       {
653         "algorithm": "RSA",
654         "mode": "sigVer",
655         "revision": "FIPS186-4",
656         "pubExpMode": "fixed",
657         "fixedPubExp": "010001",
658         "capabilities": [{
659           "sigType": "pkcs1v1.5",
660           "properties": [{
661             "modulo": 1024,
662             "hashPair": [{
663               "hashAlg": "SHA2-224"
664             }, {
665               "hashAlg": "SHA2-256"
666             }, {
667               "hashAlg": "SHA2-384"
668             }, {
669               "hashAlg": "SHA2-512"
670             }, {
671               "hashAlg": "SHA-1"
672             }]
673           }]
674         },{
675           "sigType": "pkcs1v1.5",
676           "properties": [{
677             "modulo": 2048,
678             "hashPair": [{
679               "hashAlg": "SHA2-224"
680             }, {
681               "hashAlg": "SHA2-256"
682             }, {
683               "hashAlg": "SHA2-384"
684             }, {
685               "hashAlg": "SHA2-512"
686             }, {
687               "hashAlg": "SHA-1"
688             }]
689           }]
690         },{
691           "sigType": "pkcs1v1.5",
692           "properties": [{
693             "modulo": 3072,
694             "hashPair": [{
695               "hashAlg": "SHA2-224"
696             }, {
697               "hashAlg": "SHA2-256"
698             }, {
699               "hashAlg": "SHA2-384"
700             }, {
701               "hashAlg": "SHA2-512"
702             }, {
703               "hashAlg": "SHA-1"
704             }]
705           }]
706         },{
707           "sigType": "pkcs1v1.5",
708           "properties": [{
709             "modulo": 4096,
710             "hashPair": [{
711               "hashAlg": "SHA2-224"
712             }, {
713               "hashAlg": "SHA2-256"
714             }, {
715               "hashAlg": "SHA2-384"
716             }, {
717               "hashAlg": "SHA2-512"
718             }, {
719               "hashAlg": "SHA-1"
720             }]
721           }]
722         },{
723           "sigType": "pss",
724           "properties": [{
725             "modulo": 1024,
726             "hashPair": [{
727               "hashAlg": "SHA2-224",
728               "saltLen": 28
729             }, {
730               "hashAlg": "SHA2-256",
731               "saltLen": 32
732             }, {
733               "hashAlg": "SHA2-384",
734               "saltLen": 48
735             }, {
736               "hashAlg": "SHA2-512/256",
737               "saltLen": 32
738             }, {
739               "hashAlg": "SHA-1",
740               "saltLen": 20
741             }]
742           }]
743         },{
744           "sigType": "pss",
745           "properties": [{
746             "modulo": 2048,
747             "hashPair": [{
748               "hashAlg": "SHA2-224",
749               "saltLen": 28
750             }, {
751               "hashAlg": "SHA2-256",
752               "saltLen": 32
753             }, {
754               "hashAlg": "SHA2-384",
755               "saltLen": 48
756             }, {
757               "hashAlg": "SHA2-512",
758               "saltLen": 64
759             }, {
760               "hashAlg": "SHA2-512/256",
761               "saltLen": 32
762             }, {
763               "hashAlg": "SHA-1",
764               "saltLen": 20
765             }]
766           }]
767         },{
768           "sigType": "pss",
769           "properties": [{
770             "modulo": 3072,
771             "hashPair": [{
772               "hashAlg": "SHA2-224",
773               "saltLen": 28
774             }, {
775               "hashAlg": "SHA2-256",
776               "saltLen": 32
777             }, {
778               "hashAlg": "SHA2-384",
779               "saltLen": 48
780             }, {
781               "hashAlg": "SHA2-512",
782               "saltLen": 64
783             }, {
784               "hashAlg": "SHA2-512/256",
785               "saltLen": 32
786             }, {
787               "hashAlg": "SHA-1",
788               "saltLen": 20
789             }]
790           }]
791         },{
792           "sigType": "pss",
793           "properties": [{
794             "modulo": 4096,
795             "hashPair": [{
796               "hashAlg": "SHA2-224",
797               "saltLen": 28
798             }, {
799               "hashAlg": "SHA2-256",
800               "saltLen": 32
801             }, {
802               "hashAlg": "SHA2-384",
803               "saltLen": 48
804             }, {
805               "hashAlg": "SHA2-512",
806               "saltLen": 64
807             }, {
808               "hashAlg": "SHA2-512/256",
809               "saltLen": 32
810             }, {
811               "hashAlg": "SHA-1",
812               "saltLen": 20
813             }]
814           }]
815         }]
816       },
817       {
818         "algorithm": "CMAC-AES",
819         "acvptoolTestOnly": true,
820         "revision": "1.0",
821         "capabilities": [{
822           "direction": ["gen", "ver"],
823           "msgLen": [{
824             "min": 0,
825             "max": 524288,
826             "increment": 8
827           }],
828           "keyLen": [128, 256],
829           "macLen": [{
830             "min": 8,
831             "max": 128,
832             "increment": 8
833           }]
834         }]
835       },
836       {
837         "algorithm": "kdf-components",
838         "revision": "1.0",
839         "mode": "tls",
840         "tlsVersion": [
841           "v1.0/1.1",
842           "v1.2"
843         ],
844         "hashAlg": [
845           "SHA2-256",
846           "SHA2-384",
847           "SHA2-512"
848         ]
849       },
850       {
851         "algorithm": "KAS-ECC-SSC",
852         "revision": "Sp800-56Ar3",
853         "scheme": {
854           "ephemeralUnified": {
855             "kasRole": [
856               "initiator",
857               "responder"
858             ]
859           },
860           "staticUnified": {
861             "kasRole": [
862               "initiator",
863               "responder"
864             ]
865           }
866         },
867         "domainParameterGenerationMethods": [
868           "P-224",
869           "P-256",
870           "P-384",
871           "P-521"
872         ]
873       },
874       {
875         "algorithm": "KAS-FFC-SSC",
876         "revision": "Sp800-56Ar3",
877         "scheme": {
878           "dhEphem": {
879             "kasRole": [
880               "initiator"
881             ]
882           }
883         },
884         "domainParameterGenerationMethods": [
885           "FB",
886           "FC"
887         ]
888       }
889     ])";
890   return write_reply({Span<const uint8_t>(
891       reinterpret_cast<const uint8_t *>(kConfig), sizeof(kConfig) - 1)});
892 }
893 
894 template <uint8_t *(*OneShotHash)(const uint8_t *, size_t, uint8_t *),
895           size_t DigestLength>
Hash(const Span<const uint8_t> args[],ReplyCallback write_reply)896 static bool Hash(const Span<const uint8_t> args[], ReplyCallback write_reply) {
897   uint8_t digest[DigestLength];
898   OneShotHash(args[0].data(), args[0].size(), digest);
899   return write_reply({Span<const uint8_t>(digest)});
900 }
901 
902 template <uint8_t *(*OneShotHash)(const uint8_t *, size_t, uint8_t *),
903           size_t DigestLength>
HashMCT(const Span<const uint8_t> args[],ReplyCallback write_reply)904 static bool HashMCT(const Span<const uint8_t> args[],
905                     ReplyCallback write_reply) {
906   if (args[0].size() != DigestLength) {
907     return false;
908   }
909 
910   uint8_t buf[DigestLength * 3];
911   memcpy(buf, args[0].data(), DigestLength);
912   memcpy(buf + DigestLength, args[0].data(), DigestLength);
913   memcpy(buf + 2 * DigestLength, args[0].data(), DigestLength);
914 
915   for (size_t i = 0; i < 1000; i++) {
916     uint8_t digest[DigestLength];
917     OneShotHash(buf, sizeof(buf), digest);
918     memmove(buf, buf + DigestLength, DigestLength * 2);
919     memcpy(buf + DigestLength * 2, digest, DigestLength);
920   }
921 
922   return write_reply(
923       {Span<const uint8_t>(buf + 2 * DigestLength, DigestLength)});
924 }
925 
GetIterations(const Span<const uint8_t> iterations_bytes)926 static uint32_t GetIterations(const Span<const uint8_t> iterations_bytes) {
927   uint32_t iterations;
928   if (iterations_bytes.size() != sizeof(iterations)) {
929     LOG_ERROR(
930         "Expected %u-byte input for number of iterations, but found %u "
931         "bytes.\n",
932         static_cast<unsigned>(sizeof(iterations)),
933         static_cast<unsigned>(iterations_bytes.size()));
934     abort();
935   }
936 
937   memcpy(&iterations, iterations_bytes.data(), sizeof(iterations));
938   if (iterations == 0 || iterations == UINT32_MAX) {
939     LOG_ERROR("Invalid number of iterations: %x.\n",
940          static_cast<unsigned>(iterations));
941     abort();
942   }
943 
944   return iterations;
945 }
946 
947 template <int (*SetKey)(const uint8_t *key, unsigned bits, AES_KEY *out),
948           void (*Block)(const uint8_t *in, uint8_t *out, const AES_KEY *key)>
AES(const Span<const uint8_t> args[],ReplyCallback write_reply)949 static bool AES(const Span<const uint8_t> args[], ReplyCallback write_reply) {
950   AES_KEY key;
951   if (SetKey(args[0].data(), args[0].size() * 8, &key) != 0) {
952     return false;
953   }
954   if (args[1].size() % AES_BLOCK_SIZE != 0) {
955     return false;
956   }
957   std::vector<uint8_t> result(args[1].begin(), args[1].end());
958   const uint32_t iterations = GetIterations(args[2]);
959 
960   std::vector<uint8_t> prev_result;
961   for (uint32_t j = 0; j < iterations; j++) {
962     if (j == iterations - 1) {
963       prev_result = result;
964     }
965 
966     for (size_t i = 0; i < args[1].size(); i += AES_BLOCK_SIZE) {
967       Block(result.data() + i, result.data() + i, &key);
968     }
969   }
970 
971   return write_reply(
972       {Span<const uint8_t>(result), Span<const uint8_t>(prev_result)});
973 }
974 
975 template <int (*SetKey)(const uint8_t *key, unsigned bits, AES_KEY *out),
976           int Direction>
AES_CBC(const Span<const uint8_t> args[],ReplyCallback write_reply)977 static bool AES_CBC(const Span<const uint8_t> args[], ReplyCallback write_reply) {
978   AES_KEY key;
979   if (SetKey(args[0].data(), args[0].size() * 8, &key) != 0) {
980     return false;
981   }
982   if (args[1].size() % AES_BLOCK_SIZE != 0 || args[1].empty() ||
983       args[2].size() != AES_BLOCK_SIZE) {
984     return false;
985   }
986   std::vector<uint8_t> input(args[1].begin(), args[1].end());
987   std::vector<uint8_t> iv(args[2].begin(), args[2].end());
988   const uint32_t iterations = GetIterations(args[3]);
989 
990   std::vector<uint8_t> result(input.size());
991   std::vector<uint8_t> prev_result, prev_input;
992 
993   for (uint32_t j = 0; j < iterations; j++) {
994     prev_result = result;
995     if (j > 0) {
996       if (Direction == AES_ENCRYPT) {
997         iv = result;
998       } else {
999         iv = prev_input;
1000       }
1001     }
1002 
1003     // AES_cbc_encrypt will mutate the given IV, but we need it later.
1004     uint8_t iv_copy[AES_BLOCK_SIZE];
1005     memcpy(iv_copy, iv.data(), sizeof(iv_copy));
1006     AES_cbc_encrypt(input.data(), result.data(), input.size(), &key, iv_copy,
1007                     Direction);
1008 
1009     if (Direction == AES_DECRYPT) {
1010       prev_input = input;
1011     }
1012 
1013     if (j == 0) {
1014       input = iv;
1015     } else {
1016       input = prev_result;
1017     }
1018   }
1019 
1020   return write_reply(
1021       {Span<const uint8_t>(result), Span<const uint8_t>(prev_result)});
1022 }
1023 
AES_CTR(const Span<const uint8_t> args[],ReplyCallback write_reply)1024 static bool AES_CTR(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1025   static const uint32_t kOneIteration = 1;
1026   if (args[3].size() != sizeof(kOneIteration) ||
1027       memcmp(args[3].data(), &kOneIteration, sizeof(kOneIteration))) {
1028     LOG_ERROR("Only a single iteration supported with AES-CTR\n");
1029     return false;
1030   }
1031 
1032   AES_KEY key;
1033   if (AES_set_encrypt_key(args[0].data(), args[0].size() * 8, &key) != 0) {
1034     return false;
1035   }
1036   if (args[2].size() != AES_BLOCK_SIZE) {
1037     return false;
1038   }
1039   uint8_t iv[AES_BLOCK_SIZE];
1040   memcpy(iv, args[2].data(), AES_BLOCK_SIZE);
1041   if (GetIterations(args[3]) != 1) {
1042     LOG_ERROR("Multiple iterations of AES-CTR is not supported.\n");
1043     return false;
1044   }
1045 
1046   std::vector<uint8_t> out;
1047   out.resize(args[1].size());
1048   unsigned num = 0;
1049   uint8_t ecount_buf[AES_BLOCK_SIZE];
1050   AES_ctr128_encrypt(args[1].data(), out.data(), args[1].size(), &key, iv,
1051                      ecount_buf, &num);
1052   return write_reply({Span<const uint8_t>(out)});
1053 }
1054 
AESGCMSetup(EVP_AEAD_CTX * ctx,Span<const uint8_t> tag_len_span,Span<const uint8_t> key)1055 static bool AESGCMSetup(EVP_AEAD_CTX *ctx, Span<const uint8_t> tag_len_span,
1056                         Span<const uint8_t> key) {
1057   uint32_t tag_len_32;
1058   if (tag_len_span.size() != sizeof(tag_len_32)) {
1059     LOG_ERROR("Tag size value is %u bytes, not an uint32_t\n",
1060               static_cast<unsigned>(tag_len_span.size()));
1061     return false;
1062   }
1063   memcpy(&tag_len_32, tag_len_span.data(), sizeof(tag_len_32));
1064 
1065   const EVP_AEAD *aead;
1066   switch (key.size()) {
1067     case 16:
1068       aead = EVP_aead_aes_128_gcm();
1069       break;
1070     case 24:
1071       aead = EVP_aead_aes_192_gcm();
1072       break;
1073     case 32:
1074       aead = EVP_aead_aes_256_gcm();
1075       break;
1076     default:
1077       LOG_ERROR("Bad AES-GCM key length %u\n", static_cast<unsigned>(key.size()));
1078       return false;
1079   }
1080 
1081   if (!EVP_AEAD_CTX_init(ctx, aead, key.data(), key.size(), tag_len_32,
1082                          nullptr)) {
1083     LOG_ERROR("Failed to setup AES-GCM with tag length %u\n",
1084               static_cast<unsigned>(tag_len_32));
1085     return false;
1086   }
1087 
1088   return true;
1089 }
1090 
AESCCMSetup(EVP_AEAD_CTX * ctx,Span<const uint8_t> tag_len_span,Span<const uint8_t> key)1091 static bool AESCCMSetup(EVP_AEAD_CTX *ctx, Span<const uint8_t> tag_len_span,
1092                         Span<const uint8_t> key) {
1093   uint32_t tag_len_32;
1094   if (tag_len_span.size() != sizeof(tag_len_32)) {
1095     LOG_ERROR("Tag size value is %u bytes, not an uint32_t\n",
1096               static_cast<unsigned>(tag_len_span.size()));
1097     return false;
1098   }
1099   memcpy(&tag_len_32, tag_len_span.data(), sizeof(tag_len_32));
1100   const EVP_AEAD *aead;
1101   switch (tag_len_32) {
1102     case 4:
1103       aead = EVP_aead_aes_128_ccm_bluetooth();
1104       break;
1105 
1106     case 8:
1107       aead = EVP_aead_aes_128_ccm_bluetooth_8();
1108       break;
1109 
1110     default:
1111       LOG_ERROR(
1112           "AES-CCM only supports 4- and 8-byte tags, but %u was requested\n",
1113           static_cast<unsigned>(tag_len_32));
1114       return false;
1115   }
1116 
1117   if (key.size() != 16) {
1118     LOG_ERROR("AES-CCM only supports 128-bit keys, but %u bits were given\n",
1119               static_cast<unsigned>(key.size() * 8));
1120     return false;
1121   }
1122 
1123   if (!EVP_AEAD_CTX_init(ctx, aead, key.data(), key.size(), tag_len_32,
1124                          nullptr)) {
1125     LOG_ERROR("Failed to setup AES-CCM with tag length %u\n",
1126               static_cast<unsigned>(tag_len_32));
1127     return false;
1128   }
1129 
1130   return true;
1131 }
1132 
1133 template <bool (*SetupFunc)(EVP_AEAD_CTX *ctx, Span<const uint8_t> tag_len_span,
1134                             Span<const uint8_t> key)>
AEADSeal(const Span<const uint8_t> args[],ReplyCallback write_reply)1135 static bool AEADSeal(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1136   Span<const uint8_t> tag_len_span = args[0];
1137   Span<const uint8_t> key = args[1];
1138   Span<const uint8_t> plaintext = args[2];
1139   Span<const uint8_t> nonce = args[3];
1140   Span<const uint8_t> ad = args[4];
1141 
1142   bssl::ScopedEVP_AEAD_CTX ctx;
1143   if (!SetupFunc(ctx.get(), tag_len_span, key)) {
1144     return false;
1145   }
1146 
1147   if (EVP_AEAD_MAX_OVERHEAD + plaintext.size() < EVP_AEAD_MAX_OVERHEAD) {
1148     return false;
1149   }
1150   std::vector<uint8_t> out(EVP_AEAD_MAX_OVERHEAD + plaintext.size());
1151 
1152   size_t out_len;
1153   if (!EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(),
1154                          nonce.data(), nonce.size(), plaintext.data(),
1155                          plaintext.size(), ad.data(), ad.size())) {
1156     return false;
1157   }
1158 
1159   out.resize(out_len);
1160   return write_reply({Span<const uint8_t>(out)});
1161 }
1162 
1163 template <bool (*SetupFunc)(EVP_AEAD_CTX *ctx, Span<const uint8_t> tag_len_span,
1164                             Span<const uint8_t> key)>
AEADOpen(const Span<const uint8_t> args[],ReplyCallback write_reply)1165 static bool AEADOpen(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1166   Span<const uint8_t> tag_len_span = args[0];
1167   Span<const uint8_t> key = args[1];
1168   Span<const uint8_t> ciphertext = args[2];
1169   Span<const uint8_t> nonce = args[3];
1170   Span<const uint8_t> ad = args[4];
1171 
1172   bssl::ScopedEVP_AEAD_CTX ctx;
1173   if (!SetupFunc(ctx.get(), tag_len_span, key)) {
1174     return false;
1175   }
1176 
1177   std::vector<uint8_t> out(ciphertext.size());
1178   size_t out_len;
1179   uint8_t success_flag[1] = {0};
1180 
1181   if (!EVP_AEAD_CTX_open(ctx.get(), out.data(), &out_len, out.size(),
1182                          nonce.data(), nonce.size(), ciphertext.data(),
1183                          ciphertext.size(), ad.data(), ad.size())) {
1184     return write_reply(
1185         {Span<const uint8_t>(success_flag), Span<const uint8_t>()});
1186   }
1187 
1188   out.resize(out_len);
1189   success_flag[0] = 1;
1190   return write_reply(
1191       {Span<const uint8_t>(success_flag), Span<const uint8_t>(out)});
1192 }
1193 
AESPaddedKeyWrapSetup(AES_KEY * out,bool decrypt,Span<const uint8_t> key)1194 static bool AESPaddedKeyWrapSetup(AES_KEY *out, bool decrypt,
1195                                   Span<const uint8_t> key) {
1196   if ((decrypt ? AES_set_decrypt_key : AES_set_encrypt_key)(
1197           key.data(), key.size() * 8, out) != 0) {
1198     LOG_ERROR("Invalid AES key length for AES-KW(P): %u\n",
1199               static_cast<unsigned>(key.size()));
1200     return false;
1201   }
1202   return true;
1203 }
1204 
AESKeyWrapSetup(AES_KEY * out,bool decrypt,Span<const uint8_t> key,Span<const uint8_t> input)1205 static bool AESKeyWrapSetup(AES_KEY *out, bool decrypt, Span<const uint8_t> key,
1206                             Span<const uint8_t> input) {
1207   if (!AESPaddedKeyWrapSetup(out, decrypt, key)) {
1208     return false;
1209   }
1210 
1211   if (input.size() % 8) {
1212     LOG_ERROR("Invalid AES-KW input length: %u\n",
1213               static_cast<unsigned>(input.size()));
1214     return false;
1215   }
1216 
1217   return true;
1218 }
1219 
AESKeyWrapSeal(const Span<const uint8_t> args[],ReplyCallback write_reply)1220 static bool AESKeyWrapSeal(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1221   Span<const uint8_t> key = args[1];
1222   Span<const uint8_t> plaintext = args[2];
1223 
1224   AES_KEY aes;
1225   if (!AESKeyWrapSetup(&aes, /*decrypt=*/false, key, plaintext) ||
1226       plaintext.size() > INT_MAX - 8) {
1227     return false;
1228   }
1229 
1230   std::vector<uint8_t> out(plaintext.size() + 8);
1231   if (AES_wrap_key(&aes, /*iv=*/nullptr, out.data(), plaintext.data(),
1232                    plaintext.size()) != static_cast<int>(out.size())) {
1233     LOG_ERROR("AES-KW failed\n");
1234     return false;
1235   }
1236 
1237   return write_reply({Span<const uint8_t>(out)});
1238 }
1239 
AESKeyWrapOpen(const Span<const uint8_t> args[],ReplyCallback write_reply)1240 static bool AESKeyWrapOpen(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1241   Span<const uint8_t> key = args[1];
1242   Span<const uint8_t> ciphertext = args[2];
1243 
1244   AES_KEY aes;
1245   if (!AESKeyWrapSetup(&aes, /*decrypt=*/true, key, ciphertext) ||
1246       ciphertext.size() < 8 || ciphertext.size() > INT_MAX) {
1247     return false;
1248   }
1249 
1250   std::vector<uint8_t> out(ciphertext.size() - 8);
1251   uint8_t success_flag[1] = {0};
1252   if (AES_unwrap_key(&aes, /*iv=*/nullptr, out.data(), ciphertext.data(),
1253                      ciphertext.size()) != static_cast<int>(out.size())) {
1254     return write_reply(
1255         {Span<const uint8_t>(success_flag), Span<const uint8_t>()});
1256   }
1257 
1258   success_flag[0] = 1;
1259   return write_reply(
1260       {Span<const uint8_t>(success_flag), Span<const uint8_t>(out)});
1261 }
1262 
AESPaddedKeyWrapSeal(const Span<const uint8_t> args[],ReplyCallback write_reply)1263 static bool AESPaddedKeyWrapSeal(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1264   Span<const uint8_t> key = args[1];
1265   Span<const uint8_t> plaintext = args[2];
1266 
1267   AES_KEY aes;
1268   if (!AESPaddedKeyWrapSetup(&aes, /*decrypt=*/false, key) ||
1269       plaintext.size() + 15 < 15) {
1270     return false;
1271   }
1272 
1273   std::vector<uint8_t> out(plaintext.size() + 15);
1274   size_t out_len;
1275   if (!AES_wrap_key_padded(&aes, out.data(), &out_len, out.size(),
1276                            plaintext.data(), plaintext.size())) {
1277     LOG_ERROR("AES-KWP failed\n");
1278     return false;
1279   }
1280 
1281   out.resize(out_len);
1282   return write_reply({Span<const uint8_t>(out)});
1283 }
1284 
AESPaddedKeyWrapOpen(const Span<const uint8_t> args[],ReplyCallback write_reply)1285 static bool AESPaddedKeyWrapOpen(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1286   Span<const uint8_t> key = args[1];
1287   Span<const uint8_t> ciphertext = args[2];
1288 
1289   AES_KEY aes;
1290   if (!AESPaddedKeyWrapSetup(&aes, /*decrypt=*/true, key) ||
1291       ciphertext.size() % 8) {
1292     return false;
1293   }
1294 
1295   std::vector<uint8_t> out(ciphertext.size());
1296   size_t out_len;
1297   uint8_t success_flag[1] = {0};
1298   if (!AES_unwrap_key_padded(&aes, out.data(), &out_len, out.size(),
1299                              ciphertext.data(), ciphertext.size())) {
1300     return write_reply(
1301         {Span<const uint8_t>(success_flag), Span<const uint8_t>()});
1302   }
1303 
1304   success_flag[0] = 1;
1305   out.resize(out_len);
1306   return write_reply(
1307       {Span<const uint8_t>(success_flag), Span<const uint8_t>(out)});
1308 }
1309 
1310 template <bool Encrypt>
TDES(const Span<const uint8_t> args[],ReplyCallback write_reply)1311 static bool TDES(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1312   const EVP_CIPHER *cipher = EVP_des_ede3();
1313 
1314   if (args[0].size() != 24) {
1315     LOG_ERROR("Bad key length %u for 3DES.\n",
1316               static_cast<unsigned>(args[0].size()));
1317     return false;
1318   }
1319   bssl::ScopedEVP_CIPHER_CTX ctx;
1320   if (!EVP_CipherInit_ex(ctx.get(), cipher, nullptr, args[0].data(), nullptr,
1321                          Encrypt ? 1 : 0) ||
1322       !EVP_CIPHER_CTX_set_padding(ctx.get(), 0)) {
1323     return false;
1324   }
1325 
1326   if (args[1].size() % 8) {
1327     LOG_ERROR("Bad input length %u for 3DES.\n",
1328               static_cast<unsigned>(args[1].size()));
1329     return false;
1330   }
1331   std::vector<uint8_t> result(args[1].begin(), args[1].end());
1332 
1333   const uint32_t iterations = GetIterations(args[2]);
1334   std::vector<uint8_t> prev_result, prev_prev_result;
1335 
1336   for (uint32_t j = 0; j < iterations; j++) {
1337     if (j == iterations - 1) {
1338       prev_result = result;
1339     } else if (iterations >= 2 && j == iterations - 2) {
1340       prev_prev_result = result;
1341     }
1342 
1343     int out_len;
1344     if (!EVP_CipherUpdate(ctx.get(), result.data(), &out_len, result.data(),
1345                           result.size()) ||
1346         out_len != static_cast<int>(result.size())) {
1347       return false;
1348     }
1349   }
1350 
1351   return write_reply({Span<const uint8_t>(result),
1352                       Span<const uint8_t>(prev_result),
1353                       Span<const uint8_t>(prev_prev_result)});
1354 }
1355 
1356 template <bool Encrypt>
TDES_CBC(const Span<const uint8_t> args[],ReplyCallback write_reply)1357 static bool TDES_CBC(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1358   const EVP_CIPHER *cipher = EVP_des_ede3_cbc();
1359 
1360   if (args[0].size() != 24) {
1361     LOG_ERROR("Bad key length %u for 3DES.\n",
1362               static_cast<unsigned>(args[0].size()));
1363     return false;
1364   }
1365 
1366   if (args[1].size() % 8 || args[1].size() == 0) {
1367     LOG_ERROR("Bad input length %u for 3DES.\n",
1368               static_cast<unsigned>(args[1].size()));
1369     return false;
1370   }
1371   std::vector<uint8_t> input(args[1].begin(), args[1].end());
1372 
1373   if (args[2].size() != EVP_CIPHER_iv_length(cipher)) {
1374     LOG_ERROR("Bad IV length %u for 3DES.\n",
1375               static_cast<unsigned>(args[2].size()));
1376     return false;
1377   }
1378   std::vector<uint8_t> iv(args[2].begin(), args[2].end());
1379   const uint32_t iterations = GetIterations(args[3]);
1380 
1381   std::vector<uint8_t> result(input.size());
1382   std::vector<uint8_t> prev_result, prev_prev_result;
1383   bssl::ScopedEVP_CIPHER_CTX ctx;
1384   if (!EVP_CipherInit_ex(ctx.get(), cipher, nullptr, args[0].data(), iv.data(),
1385                          Encrypt ? 1 : 0) ||
1386       !EVP_CIPHER_CTX_set_padding(ctx.get(), 0)) {
1387     return false;
1388   }
1389 
1390   for (uint32_t j = 0; j < iterations; j++) {
1391     prev_prev_result = prev_result;
1392     prev_result = result;
1393 
1394     int out_len, out_len2;
1395     if (!EVP_CipherInit_ex(ctx.get(), nullptr, nullptr, nullptr, iv.data(),
1396                            -1) ||
1397         !EVP_CipherUpdate(ctx.get(), result.data(), &out_len, input.data(),
1398                           input.size()) ||
1399         !EVP_CipherFinal_ex(ctx.get(), result.data() + out_len, &out_len2) ||
1400         (out_len + out_len2) != static_cast<int>(result.size())) {
1401       return false;
1402     }
1403 
1404     if (Encrypt) {
1405       if (j == 0) {
1406         input = iv;
1407       } else {
1408         input = prev_result;
1409       }
1410       iv = result;
1411     } else {
1412       iv = input;
1413       input = result;
1414     }
1415   }
1416 
1417   return write_reply({Span<const uint8_t>(result),
1418                      Span<const uint8_t>(prev_result),
1419                      Span<const uint8_t>(prev_prev_result)});
1420 }
1421 
1422 template <const EVP_MD *HashFunc()>
HMAC(const Span<const uint8_t> args[],ReplyCallback write_reply)1423 static bool HMAC(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1424   const EVP_MD *const md = HashFunc();
1425   uint8_t digest[EVP_MAX_MD_SIZE];
1426   unsigned digest_len;
1427   if (::HMAC(md, args[1].data(), args[1].size(), args[0].data(), args[0].size(),
1428              digest, &digest_len) == nullptr) {
1429     return false;
1430   }
1431   return write_reply({Span<const uint8_t>(digest, digest_len)});
1432 }
1433 
1434 template <bool WithReseed>
DRBG(const Span<const uint8_t> args[],ReplyCallback write_reply)1435 static bool DRBG(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1436   const auto out_len_bytes = args[0];
1437   const auto entropy = args[1];
1438   const auto personalisation = args[2];
1439 
1440   Span<const uint8_t> reseed_additional_data, reseed_entropy, additional_data1,
1441       additional_data2, nonce;
1442   if (!WithReseed) {
1443     additional_data1 = args[3];
1444     additional_data2 = args[4];
1445     nonce = args[5];
1446   } else {
1447     reseed_additional_data = args[3];
1448     reseed_entropy = args[4];
1449     additional_data1 = args[5];
1450     additional_data2 = args[6];
1451     nonce = args[7];
1452   }
1453 
1454   uint32_t out_len;
1455   if (out_len_bytes.size() != sizeof(out_len) ||
1456       entropy.size() != CTR_DRBG_ENTROPY_LEN ||
1457       (!reseed_entropy.empty() &&
1458        reseed_entropy.size() != CTR_DRBG_ENTROPY_LEN) ||
1459       // nonces are not supported
1460       nonce.size() != 0) {
1461     return false;
1462   }
1463   memcpy(&out_len, out_len_bytes.data(), sizeof(out_len));
1464   if (out_len > (1 << 24)) {
1465     return false;
1466   }
1467   std::vector<uint8_t> out(out_len);
1468 
1469   CTR_DRBG_STATE drbg;
1470   if (!CTR_DRBG_init(&drbg, entropy.data(), personalisation.data(),
1471                      personalisation.size()) ||
1472       (!reseed_entropy.empty() &&
1473        !CTR_DRBG_reseed(&drbg, reseed_entropy.data(),
1474                         reseed_additional_data.data(),
1475                         reseed_additional_data.size())) ||
1476       !CTR_DRBG_generate(&drbg, out.data(), out_len, additional_data1.data(),
1477                          additional_data1.size()) ||
1478       !CTR_DRBG_generate(&drbg, out.data(), out_len, additional_data2.data(),
1479                          additional_data2.size())) {
1480     return false;
1481   }
1482 
1483   return write_reply({Span<const uint8_t>(out)});
1484 }
1485 
StringEq(Span<const uint8_t> a,const char * b)1486 static bool StringEq(Span<const uint8_t> a, const char *b) {
1487   const size_t len = strlen(b);
1488   return a.size() == len && memcmp(a.data(), b, len) == 0;
1489 }
1490 
ECKeyFromName(Span<const uint8_t> name)1491 static bssl::UniquePtr<EC_KEY> ECKeyFromName(Span<const uint8_t> name) {
1492   int nid;
1493   if (StringEq(name, "P-224")) {
1494     nid = NID_secp224r1;
1495   } else if (StringEq(name, "P-256")) {
1496     nid = NID_X9_62_prime256v1;
1497   } else if (StringEq(name, "P-384")) {
1498     nid = NID_secp384r1;
1499   } else if (StringEq(name, "P-521")) {
1500     nid = NID_secp521r1;
1501   } else {
1502     return nullptr;
1503   }
1504 
1505   return bssl::UniquePtr<EC_KEY>(EC_KEY_new_by_curve_name(nid));
1506 }
1507 
BIGNUMBytes(const BIGNUM * bn)1508 static std::vector<uint8_t> BIGNUMBytes(const BIGNUM *bn) {
1509   const size_t len = BN_num_bytes(bn);
1510   std::vector<uint8_t> ret(len);
1511   BN_bn2bin(bn, ret.data());
1512   return ret;
1513 }
1514 
GetPublicKeyBytes(const EC_KEY * key)1515 static std::pair<std::vector<uint8_t>, std::vector<uint8_t>> GetPublicKeyBytes(
1516     const EC_KEY *key) {
1517   bssl::UniquePtr<BIGNUM> x(BN_new());
1518   bssl::UniquePtr<BIGNUM> y(BN_new());
1519   if (!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(key),
1520                                            EC_KEY_get0_public_key(key), x.get(),
1521                                            y.get(), /*ctx=*/nullptr)) {
1522     abort();
1523   }
1524 
1525   std::vector<uint8_t> x_bytes = BIGNUMBytes(x.get());
1526   std::vector<uint8_t> y_bytes = BIGNUMBytes(y.get());
1527 
1528   return std::make_pair(std::move(x_bytes), std::move(y_bytes));
1529 }
1530 
ECDSAKeyGen(const Span<const uint8_t> args[],ReplyCallback write_reply)1531 static bool ECDSAKeyGen(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1532   bssl::UniquePtr<EC_KEY> key = ECKeyFromName(args[0]);
1533   if (!key || !EC_KEY_generate_key_fips(key.get())) {
1534     return false;
1535   }
1536 
1537   const auto pub_key = GetPublicKeyBytes(key.get());
1538   std::vector<uint8_t> d_bytes =
1539       BIGNUMBytes(EC_KEY_get0_private_key(key.get()));
1540 
1541   return write_reply({Span<const uint8_t>(d_bytes),
1542                       Span<const uint8_t>(pub_key.first),
1543                       Span<const uint8_t>(pub_key.second)});
1544 }
1545 
BytesToBIGNUM(Span<const uint8_t> bytes)1546 static bssl::UniquePtr<BIGNUM> BytesToBIGNUM(Span<const uint8_t> bytes) {
1547   bssl::UniquePtr<BIGNUM> bn(BN_new());
1548   BN_bin2bn(bytes.data(), bytes.size(), bn.get());
1549   return bn;
1550 }
1551 
ECDSAKeyVer(const Span<const uint8_t> args[],ReplyCallback write_reply)1552 static bool ECDSAKeyVer(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1553   bssl::UniquePtr<EC_KEY> key = ECKeyFromName(args[0]);
1554   if (!key) {
1555     return false;
1556   }
1557 
1558   bssl::UniquePtr<BIGNUM> x(BytesToBIGNUM(args[1]));
1559   bssl::UniquePtr<BIGNUM> y(BytesToBIGNUM(args[2]));
1560 
1561   bssl::UniquePtr<EC_POINT> point(EC_POINT_new(EC_KEY_get0_group(key.get())));
1562   uint8_t reply[1];
1563   if (!EC_POINT_set_affine_coordinates_GFp(EC_KEY_get0_group(key.get()),
1564                                            point.get(), x.get(), y.get(),
1565                                            /*ctx=*/nullptr) ||
1566       !EC_KEY_set_public_key(key.get(), point.get()) ||
1567       !EC_KEY_check_fips(key.get())) {
1568     reply[0] = 0;
1569   } else {
1570     reply[0] = 1;
1571   }
1572 
1573   return write_reply({Span<const uint8_t>(reply)});
1574 }
1575 
HashFromName(Span<const uint8_t> name)1576 static const EVP_MD *HashFromName(Span<const uint8_t> name) {
1577   if (StringEq(name, "SHA-1")) {
1578     return EVP_sha1();
1579   } else if (StringEq(name, "SHA2-224")) {
1580     return EVP_sha224();
1581   } else if (StringEq(name, "SHA2-256")) {
1582     return EVP_sha256();
1583   } else if (StringEq(name, "SHA2-384")) {
1584     return EVP_sha384();
1585   } else if (StringEq(name, "SHA2-512")) {
1586     return EVP_sha512();
1587   } else if (StringEq(name, "SHA2-512/256")) {
1588     return EVP_sha512_256();
1589   } else {
1590     return nullptr;
1591   }
1592 }
1593 
ECDSASigGen(const Span<const uint8_t> args[],ReplyCallback write_reply)1594 static bool ECDSASigGen(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1595   bssl::UniquePtr<EC_KEY> key = ECKeyFromName(args[0]);
1596   bssl::UniquePtr<BIGNUM> d = BytesToBIGNUM(args[1]);
1597   const EVP_MD *hash = HashFromName(args[2]);
1598   uint8_t digest[EVP_MAX_MD_SIZE];
1599   unsigned digest_len;
1600   if (!key || !hash ||
1601       !EVP_Digest(args[3].data(), args[3].size(), digest, &digest_len, hash,
1602                   /*impl=*/nullptr) ||
1603       !EC_KEY_set_private_key(key.get(), d.get())) {
1604     return false;
1605   }
1606 
1607   bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_do_sign(digest, digest_len, key.get()));
1608   if (!sig) {
1609     return false;
1610   }
1611 
1612   std::vector<uint8_t> r_bytes(BIGNUMBytes(sig->r));
1613   std::vector<uint8_t> s_bytes(BIGNUMBytes(sig->s));
1614 
1615   return write_reply(
1616       {Span<const uint8_t>(r_bytes), Span<const uint8_t>(s_bytes)});
1617 }
1618 
ECDSASigVer(const Span<const uint8_t> args[],ReplyCallback write_reply)1619 static bool ECDSASigVer(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1620   bssl::UniquePtr<EC_KEY> key = ECKeyFromName(args[0]);
1621   const EVP_MD *hash = HashFromName(args[1]);
1622   auto msg = args[2];
1623   bssl::UniquePtr<BIGNUM> x(BytesToBIGNUM(args[3]));
1624   bssl::UniquePtr<BIGNUM> y(BytesToBIGNUM(args[4]));
1625   bssl::UniquePtr<BIGNUM> r(BytesToBIGNUM(args[5]));
1626   bssl::UniquePtr<BIGNUM> s(BytesToBIGNUM(args[6]));
1627   ECDSA_SIG sig;
1628   sig.r = r.get();
1629   sig.s = s.get();
1630 
1631   uint8_t digest[EVP_MAX_MD_SIZE];
1632   unsigned digest_len;
1633   if (!key || !hash ||
1634       !EVP_Digest(msg.data(), msg.size(), digest, &digest_len, hash,
1635                   /*impl=*/nullptr)) {
1636     return false;
1637   }
1638 
1639   bssl::UniquePtr<EC_POINT> point(EC_POINT_new(EC_KEY_get0_group(key.get())));
1640   uint8_t reply[1];
1641   if (!EC_POINT_set_affine_coordinates_GFp(EC_KEY_get0_group(key.get()),
1642                                            point.get(), x.get(), y.get(),
1643                                            /*ctx=*/nullptr) ||
1644       !EC_KEY_set_public_key(key.get(), point.get()) ||
1645       !EC_KEY_check_fips(key.get()) ||
1646       !ECDSA_do_verify(digest, digest_len, &sig, key.get())) {
1647     reply[0] = 0;
1648   } else {
1649     reply[0] = 1;
1650   }
1651 
1652   return write_reply({Span<const uint8_t>(reply)});
1653 }
1654 
CMAC_AES(const Span<const uint8_t> args[],ReplyCallback write_reply)1655 static bool CMAC_AES(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1656   uint8_t mac[16];
1657   if (!AES_CMAC(mac, args[1].data(), args[1].size(), args[2].data(),
1658                 args[2].size())) {
1659     return false;
1660   }
1661 
1662   uint32_t mac_len;
1663   if (args[0].size() != sizeof(mac_len)) {
1664     return false;
1665   }
1666   memcpy(&mac_len, args[0].data(), sizeof(mac_len));
1667   if (mac_len > sizeof(mac)) {
1668     return false;
1669   }
1670 
1671   return write_reply({Span<const uint8_t>(mac, mac_len)});
1672 }
1673 
CMAC_AESVerify(const Span<const uint8_t> args[],ReplyCallback write_reply)1674 static bool CMAC_AESVerify(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1675   // This function is just for testing since libcrypto doesn't do the
1676   // verification itself. The regcap doesn't advertise "ver" support.
1677   uint8_t mac[16];
1678   if (!AES_CMAC(mac, args[0].data(), args[0].size(), args[1].data(),
1679                 args[1].size()) ||
1680       args[2].size() > sizeof(mac)) {
1681     return false;
1682   }
1683 
1684   const uint8_t ok = (OPENSSL_memcmp(mac, args[2].data(), args[2].size()) == 0);
1685   return write_reply({Span<const uint8_t>(&ok, sizeof(ok))});
1686 }
1687 
CachedRSAKeys()1688 static std::map<unsigned, bssl::UniquePtr<RSA>>& CachedRSAKeys() {
1689   static std::map<unsigned, bssl::UniquePtr<RSA>> keys;
1690   return keys;
1691 }
1692 
GetRSAKey(unsigned bits)1693 static RSA* GetRSAKey(unsigned bits) {
1694   auto it = CachedRSAKeys().find(bits);
1695   if (it != CachedRSAKeys().end()) {
1696     return it->second.get();
1697   }
1698 
1699   bssl::UniquePtr<RSA> key(RSA_new());
1700   if (!RSA_generate_key_fips(key.get(), bits, nullptr)) {
1701     abort();
1702   }
1703 
1704   RSA *const ret = key.get();
1705   CachedRSAKeys().emplace(static_cast<unsigned>(bits), std::move(key));
1706 
1707   return ret;
1708 }
1709 
RSAKeyGen(const Span<const uint8_t> args[],ReplyCallback write_reply)1710 static bool RSAKeyGen(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1711   uint32_t bits;
1712   if (args[0].size() != sizeof(bits)) {
1713     return false;
1714   }
1715   memcpy(&bits, args[0].data(), sizeof(bits));
1716 
1717   bssl::UniquePtr<RSA> key(RSA_new());
1718   if (!RSA_generate_key_fips(key.get(), bits, nullptr)) {
1719     LOG_ERROR("RSA_generate_key_fips failed for modulus length %u.\n", bits);
1720     return false;
1721   }
1722 
1723   const BIGNUM *n, *e, *d, *p, *q;
1724   RSA_get0_key(key.get(), &n, &e, &d);
1725   RSA_get0_factors(key.get(), &p, &q);
1726 
1727   if (!write_reply({BIGNUMBytes(e), BIGNUMBytes(p), BIGNUMBytes(q),
1728                     BIGNUMBytes(n), BIGNUMBytes(d)})) {
1729     return false;
1730   }
1731 
1732   CachedRSAKeys().emplace(static_cast<unsigned>(bits), std::move(key));
1733   return true;
1734 }
1735 
1736 template <const EVP_MD *(MDFunc)(), bool UsePSS>
RSASigGen(const Span<const uint8_t> args[],ReplyCallback write_reply)1737 static bool RSASigGen(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1738   uint32_t bits;
1739   if (args[0].size() != sizeof(bits)) {
1740     return false;
1741   }
1742   memcpy(&bits, args[0].data(), sizeof(bits));
1743   const Span<const uint8_t> msg = args[1];
1744 
1745   RSA *const key = GetRSAKey(bits);
1746   const EVP_MD *const md = MDFunc();
1747   uint8_t digest_buf[EVP_MAX_MD_SIZE];
1748   unsigned digest_len;
1749   if (!EVP_Digest(msg.data(), msg.size(), digest_buf, &digest_len, md, NULL)) {
1750     return false;
1751   }
1752 
1753   std::vector<uint8_t> sig(RSA_size(key));
1754   size_t sig_len;
1755   if (UsePSS) {
1756     if (!RSA_sign_pss_mgf1(key, &sig_len, sig.data(), sig.size(), digest_buf,
1757                            digest_len, md, md, -1)) {
1758       return false;
1759     }
1760   } else {
1761     unsigned sig_len_u;
1762     if (!RSA_sign(EVP_MD_type(md), digest_buf, digest_len, sig.data(),
1763                   &sig_len_u, key)) {
1764       return false;
1765     }
1766     sig_len = sig_len_u;
1767   }
1768 
1769   sig.resize(sig_len);
1770 
1771   return write_reply(
1772       {BIGNUMBytes(RSA_get0_n(key)), BIGNUMBytes(RSA_get0_e(key)), sig});
1773 }
1774 
1775 template <const EVP_MD *(MDFunc)(), bool UsePSS>
RSASigVer(const Span<const uint8_t> args[],ReplyCallback write_reply)1776 static bool RSASigVer(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1777   const Span<const uint8_t> n_bytes = args[0];
1778   const Span<const uint8_t> e_bytes = args[1];
1779   const Span<const uint8_t> msg = args[2];
1780   const Span<const uint8_t> sig = args[3];
1781 
1782   BIGNUM *n = BN_new();
1783   BIGNUM *e = BN_new();
1784   bssl::UniquePtr<RSA> key(RSA_new());
1785   if (!BN_bin2bn(n_bytes.data(), n_bytes.size(), n) ||
1786       !BN_bin2bn(e_bytes.data(), e_bytes.size(), e) ||
1787       !RSA_set0_key(key.get(), n, e, /*d=*/nullptr)) {
1788     return false;
1789   }
1790 
1791   const EVP_MD *const md = MDFunc();
1792   uint8_t digest_buf[EVP_MAX_MD_SIZE];
1793   unsigned digest_len;
1794   if (!EVP_Digest(msg.data(), msg.size(), digest_buf, &digest_len, md, NULL)) {
1795     return false;
1796   }
1797 
1798   uint8_t ok;
1799   if (UsePSS) {
1800     ok = RSA_verify_pss_mgf1(key.get(), digest_buf, digest_len, md, md, -1,
1801                              sig.data(), sig.size());
1802   } else {
1803     ok = RSA_verify(EVP_MD_type(md), digest_buf, digest_len, sig.data(),
1804                     sig.size(), key.get());
1805   }
1806   ERR_clear_error();
1807 
1808   return write_reply({Span<const uint8_t>(&ok, 1)});
1809 }
1810 
1811 template <const EVP_MD *(MDFunc)()>
TLSKDF(const Span<const uint8_t> args[],ReplyCallback write_reply)1812 static bool TLSKDF(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1813   const Span<const uint8_t> out_len_bytes = args[0];
1814   const Span<const uint8_t> secret = args[1];
1815   const Span<const uint8_t> label = args[2];
1816   const Span<const uint8_t> seed1 = args[3];
1817   const Span<const uint8_t> seed2 = args[4];
1818   const EVP_MD *md = MDFunc();
1819 
1820   uint32_t out_len;
1821   if (out_len_bytes.size() != sizeof(out_len)) {
1822     return 0;
1823   }
1824   memcpy(&out_len, out_len_bytes.data(), sizeof(out_len));
1825 
1826   std::vector<uint8_t> out(static_cast<size_t>(out_len));
1827   if (!CRYPTO_tls1_prf(md, out.data(), out.size(), secret.data(), secret.size(),
1828                        reinterpret_cast<const char *>(label.data()),
1829                        label.size(), seed1.data(), seed1.size(), seed2.data(),
1830                        seed2.size())) {
1831     return 0;
1832   }
1833 
1834   return write_reply({out});
1835 }
1836 
1837 template <int Nid>
ECDH(const Span<const uint8_t> args[],ReplyCallback write_reply)1838 static bool ECDH(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1839   bssl::UniquePtr<BIGNUM> their_x(BytesToBIGNUM(args[0]));
1840   bssl::UniquePtr<BIGNUM> their_y(BytesToBIGNUM(args[1]));
1841   const Span<const uint8_t> private_key = args[2];
1842 
1843   bssl::UniquePtr<EC_KEY> ec_key(EC_KEY_new_by_curve_name(Nid));
1844   bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
1845 
1846   const EC_GROUP *const group = EC_KEY_get0_group(ec_key.get());
1847   bssl::UniquePtr<EC_POINT> their_point(EC_POINT_new(group));
1848   if (!EC_POINT_set_affine_coordinates_GFp(
1849           group, their_point.get(), their_x.get(), their_y.get(), ctx.get())) {
1850     LOG_ERROR("Invalid peer point for ECDH.\n");
1851     return false;
1852   }
1853 
1854   if (!private_key.empty()) {
1855     bssl::UniquePtr<BIGNUM> our_k(BytesToBIGNUM(private_key));
1856     if (!EC_KEY_set_private_key(ec_key.get(), our_k.get())) {
1857       LOG_ERROR("EC_KEY_set_private_key failed.\n");
1858       return false;
1859     }
1860 
1861     bssl::UniquePtr<EC_POINT> our_pub(EC_POINT_new(group));
1862     if (!EC_POINT_mul(group, our_pub.get(), our_k.get(), nullptr, nullptr,
1863                       ctx.get()) ||
1864         !EC_KEY_set_public_key(ec_key.get(), our_pub.get())) {
1865       LOG_ERROR("Calculating public key failed.\n");
1866       return false;
1867     }
1868   } else if (!EC_KEY_generate_key_fips(ec_key.get())) {
1869     LOG_ERROR("EC_KEY_generate_key_fips failed.\n");
1870     return false;
1871   }
1872 
1873   // The output buffer is one larger than |EC_MAX_BYTES| so that truncation
1874   // can be detected.
1875   std::vector<uint8_t> output(EC_MAX_BYTES + 1);
1876   const int out_len =
1877       ECDH_compute_key(output.data(), output.size(), their_point.get(),
1878                        ec_key.get(), /*kdf=*/nullptr);
1879   if (out_len < 0) {
1880     LOG_ERROR("ECDH_compute_key failed.\n");
1881     return false;
1882   } else if (static_cast<size_t>(out_len) == output.size()) {
1883     LOG_ERROR("ECDH_compute_key output may have been truncated.\n");
1884     return false;
1885   }
1886   output.resize(static_cast<size_t>(out_len));
1887 
1888   const EC_POINT *pub = EC_KEY_get0_public_key(ec_key.get());
1889   bssl::UniquePtr<BIGNUM> x(BN_new());
1890   bssl::UniquePtr<BIGNUM> y(BN_new());
1891   if (!EC_POINT_get_affine_coordinates_GFp(group, pub, x.get(), y.get(),
1892                                            ctx.get())) {
1893     LOG_ERROR("EC_POINT_get_affine_coordinates_GFp failed.\n");
1894     return false;
1895   }
1896 
1897   return write_reply({BIGNUMBytes(x.get()), BIGNUMBytes(y.get()), output});
1898 }
1899 
FFDH(const Span<const uint8_t> args[],ReplyCallback write_reply)1900 static bool FFDH(const Span<const uint8_t> args[], ReplyCallback write_reply) {
1901   bssl::UniquePtr<BIGNUM> p(BytesToBIGNUM(args[0]));
1902   bssl::UniquePtr<BIGNUM> q(BytesToBIGNUM(args[1]));
1903   bssl::UniquePtr<BIGNUM> g(BytesToBIGNUM(args[2]));
1904   bssl::UniquePtr<BIGNUM> their_pub(BytesToBIGNUM(args[3]));
1905   const Span<const uint8_t> private_key_span = args[4];
1906   const Span<const uint8_t> public_key_span = args[5];
1907 
1908   bssl::UniquePtr<DH> dh(DH_new());
1909   if (!DH_set0_pqg(dh.get(), p.get(), q.get(), g.get())) {
1910     LOG_ERROR("DH_set0_pqg failed.\n");
1911     return 0;
1912   }
1913 
1914   // DH_set0_pqg took ownership of these values.
1915   p.release();
1916   q.release();
1917   g.release();
1918 
1919   if (!private_key_span.empty()) {
1920     bssl::UniquePtr<BIGNUM> private_key(BytesToBIGNUM(private_key_span));
1921     bssl::UniquePtr<BIGNUM> public_key(BytesToBIGNUM(public_key_span));
1922 
1923     if (!DH_set0_key(dh.get(), public_key.get(), private_key.get())) {
1924       LOG_ERROR("DH_set0_key failed.\n");
1925       return 0;
1926     }
1927 
1928     // DH_set0_key took ownership of these values.
1929     public_key.release();
1930     private_key.release();
1931   } else if (!DH_generate_key(dh.get())) {
1932     LOG_ERROR("DH_generate_key failed.\n");
1933     return false;
1934   }
1935 
1936   std::vector<uint8_t> z(DH_size(dh.get()));
1937   if (DH_compute_key_padded(z.data(), their_pub.get(), dh.get()) !=
1938       static_cast<int>(z.size())) {
1939     LOG_ERROR("DH_compute_key_hashed failed.\n");
1940     return false;
1941   }
1942 
1943   return write_reply({BIGNUMBytes(DH_get0_pub_key(dh.get())), z});
1944 }
1945 
1946 static constexpr struct {
1947   char name[kMaxNameLength + 1];
1948   uint8_t num_expected_args;
1949   bool (*handler)(const Span<const uint8_t> args[], ReplyCallback write_reply);
1950 } kFunctions[] = {
1951     {"getConfig", 0, GetConfig},
1952     {"SHA-1", 1, Hash<SHA1, SHA_DIGEST_LENGTH>},
1953     {"SHA2-224", 1, Hash<SHA224, SHA224_DIGEST_LENGTH>},
1954     {"SHA2-256", 1, Hash<SHA256, SHA256_DIGEST_LENGTH>},
1955     {"SHA2-384", 1, Hash<SHA384, SHA384_DIGEST_LENGTH>},
1956     {"SHA2-512", 1, Hash<SHA512, SHA512_DIGEST_LENGTH>},
1957     {"SHA2-512/256", 1, Hash<SHA512_256, SHA512_256_DIGEST_LENGTH>},
1958     {"SHA-1/MCT", 1, HashMCT<SHA1, SHA_DIGEST_LENGTH>},
1959     {"SHA2-224/MCT", 1, HashMCT<SHA224, SHA224_DIGEST_LENGTH>},
1960     {"SHA2-256/MCT", 1, HashMCT<SHA256, SHA256_DIGEST_LENGTH>},
1961     {"SHA2-384/MCT", 1, HashMCT<SHA384, SHA384_DIGEST_LENGTH>},
1962     {"SHA2-512/MCT", 1, HashMCT<SHA512, SHA512_DIGEST_LENGTH>},
1963     {"SHA2-512/256/MCT", 1, HashMCT<SHA512_256, SHA512_256_DIGEST_LENGTH>},
1964     {"AES/encrypt", 3, AES<AES_set_encrypt_key, AES_encrypt>},
1965     {"AES/decrypt", 3, AES<AES_set_decrypt_key, AES_decrypt>},
1966     {"AES-CBC/encrypt", 4, AES_CBC<AES_set_encrypt_key, AES_ENCRYPT>},
1967     {"AES-CBC/decrypt", 4, AES_CBC<AES_set_decrypt_key, AES_DECRYPT>},
1968     {"AES-CTR/encrypt", 4, AES_CTR},
1969     {"AES-CTR/decrypt", 4, AES_CTR},
1970     {"AES-GCM/seal", 5, AEADSeal<AESGCMSetup>},
1971     {"AES-GCM/open", 5, AEADOpen<AESGCMSetup>},
1972     {"AES-KW/seal", 5, AESKeyWrapSeal},
1973     {"AES-KW/open", 5, AESKeyWrapOpen},
1974     {"AES-KWP/seal", 5, AESPaddedKeyWrapSeal},
1975     {"AES-KWP/open", 5, AESPaddedKeyWrapOpen},
1976     {"AES-CCM/seal", 5, AEADSeal<AESCCMSetup>},
1977     {"AES-CCM/open", 5, AEADOpen<AESCCMSetup>},
1978     {"3DES-ECB/encrypt", 3, TDES<true>},
1979     {"3DES-ECB/decrypt", 3, TDES<false>},
1980     {"3DES-CBC/encrypt", 4, TDES_CBC<true>},
1981     {"3DES-CBC/decrypt", 4, TDES_CBC<false>},
1982     {"HMAC-SHA-1", 2, HMAC<EVP_sha1>},
1983     {"HMAC-SHA2-224", 2, HMAC<EVP_sha224>},
1984     {"HMAC-SHA2-256", 2, HMAC<EVP_sha256>},
1985     {"HMAC-SHA2-384", 2, HMAC<EVP_sha384>},
1986     {"HMAC-SHA2-512", 2, HMAC<EVP_sha512>},
1987     {"HMAC-SHA2-512/256", 2, HMAC<EVP_sha512_256>},
1988     {"ctrDRBG/AES-256", 6, DRBG<false>},
1989     {"ctrDRBG-reseed/AES-256", 8, DRBG<true>},
1990     {"ECDSA/keyGen", 1, ECDSAKeyGen},
1991     {"ECDSA/keyVer", 3, ECDSAKeyVer},
1992     {"ECDSA/sigGen", 4, ECDSASigGen},
1993     {"ECDSA/sigVer", 7, ECDSASigVer},
1994     {"CMAC-AES", 3, CMAC_AES},
1995     {"CMAC-AES/verify", 3, CMAC_AESVerify},
1996     {"RSA/keyGen", 1, RSAKeyGen},
1997     {"RSA/sigGen/SHA2-224/pkcs1v1.5", 2, RSASigGen<EVP_sha224, false>},
1998     {"RSA/sigGen/SHA2-256/pkcs1v1.5", 2, RSASigGen<EVP_sha256, false>},
1999     {"RSA/sigGen/SHA2-384/pkcs1v1.5", 2, RSASigGen<EVP_sha384, false>},
2000     {"RSA/sigGen/SHA2-512/pkcs1v1.5", 2, RSASigGen<EVP_sha512, false>},
2001     {"RSA/sigGen/SHA-1/pkcs1v1.5", 2, RSASigGen<EVP_sha1, false>},
2002     {"RSA/sigGen/SHA2-224/pss", 2, RSASigGen<EVP_sha224, true>},
2003     {"RSA/sigGen/SHA2-256/pss", 2, RSASigGen<EVP_sha256, true>},
2004     {"RSA/sigGen/SHA2-384/pss", 2, RSASigGen<EVP_sha384, true>},
2005     {"RSA/sigGen/SHA2-512/pss", 2, RSASigGen<EVP_sha512, true>},
2006     {"RSA/sigGen/SHA2-512/256/pss", 2, RSASigGen<EVP_sha512_256, true>},
2007     {"RSA/sigGen/SHA-1/pss", 2, RSASigGen<EVP_sha1, true>},
2008     {"RSA/sigVer/SHA2-224/pkcs1v1.5", 4, RSASigVer<EVP_sha224, false>},
2009     {"RSA/sigVer/SHA2-256/pkcs1v1.5", 4, RSASigVer<EVP_sha256, false>},
2010     {"RSA/sigVer/SHA2-384/pkcs1v1.5", 4, RSASigVer<EVP_sha384, false>},
2011     {"RSA/sigVer/SHA2-512/pkcs1v1.5", 4, RSASigVer<EVP_sha512, false>},
2012     {"RSA/sigVer/SHA-1/pkcs1v1.5", 4, RSASigVer<EVP_sha1, false>},
2013     {"RSA/sigVer/SHA2-224/pss", 4, RSASigVer<EVP_sha224, true>},
2014     {"RSA/sigVer/SHA2-256/pss", 4, RSASigVer<EVP_sha256, true>},
2015     {"RSA/sigVer/SHA2-384/pss", 4, RSASigVer<EVP_sha384, true>},
2016     {"RSA/sigVer/SHA2-512/pss", 4, RSASigVer<EVP_sha512, true>},
2017     {"RSA/sigVer/SHA2-512/256/pss", 4, RSASigVer<EVP_sha512_256, true>},
2018     {"RSA/sigVer/SHA-1/pss", 4, RSASigVer<EVP_sha1, true>},
2019     {"TLSKDF/1.0/SHA-1", 5, TLSKDF<EVP_md5_sha1>},
2020     {"TLSKDF/1.2/SHA2-256", 5, TLSKDF<EVP_sha256>},
2021     {"TLSKDF/1.2/SHA2-384", 5, TLSKDF<EVP_sha384>},
2022     {"TLSKDF/1.2/SHA2-512", 5, TLSKDF<EVP_sha512>},
2023     {"ECDH/P-224", 3, ECDH<NID_secp224r1>},
2024     {"ECDH/P-256", 3, ECDH<NID_X9_62_prime256v1>},
2025     {"ECDH/P-384", 3, ECDH<NID_secp384r1>},
2026     {"ECDH/P-521", 3, ECDH<NID_secp521r1>},
2027     {"FFDH", 6, FFDH},
2028 };
2029 
FindHandler(Span<const Span<const uint8_t>> args)2030 Handler FindHandler(Span<const Span<const uint8_t>> args) {
2031   const bssl::Span<const uint8_t> algorithm = args[0];
2032   for (const auto &func : kFunctions) {
2033     if (algorithm.size() == strlen(func.name) &&
2034         memcmp(algorithm.data(), func.name, algorithm.size()) == 0) {
2035       if (args.size() - 1 != func.num_expected_args) {
2036         LOG_ERROR("\'%s\' operation received %zu arguments but expected %u.\n",
2037                   func.name, args.size() - 1, func.num_expected_args);
2038         return nullptr;
2039       }
2040 
2041       return func.handler;
2042     }
2043   }
2044 
2045   const std::string name(reinterpret_cast<const char *>(algorithm.data()),
2046                          algorithm.size());
2047   LOG_ERROR("Unknown operation: %s\n", name.c_str());
2048   return nullptr;
2049 }
2050 
2051 }  // namespace acvp
2052 }  // namespace bssl
2053