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