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