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