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