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