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