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