summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine/hw_cryptodev.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/engine/hw_cryptodev.c')
-rw-r--r--src/lib/libcrypto/engine/hw_cryptodev.c343
1 files changed, 281 insertions, 62 deletions
diff --git a/src/lib/libcrypto/engine/hw_cryptodev.c b/src/lib/libcrypto/engine/hw_cryptodev.c
index 3e7fff1c1e..d3b186c132 100644
--- a/src/lib/libcrypto/engine/hw_cryptodev.c
+++ b/src/lib/libcrypto/engine/hw_cryptodev.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2002-2004 Theo de Raadt
2 * Copyright (c) 2002 Bob Beck <beck@openbsd.org> 3 * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
3 * Copyright (c) 2002 Theo de Raadt
4 * Copyright (c) 2002 Markus Friedl 4 * Copyright (c) 2002 Markus Friedl
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
@@ -49,11 +49,12 @@ ENGINE_load_cryptodev(void)
49 return; 49 return;
50} 50}
51 51
52#else 52#else
53 53
54#include <sys/types.h> 54#include <sys/types.h>
55#include <crypto/cryptodev.h> 55#include <crypto/cryptodev.h>
56#include <sys/ioctl.h> 56#include <sys/ioctl.h>
57
57#include <errno.h> 58#include <errno.h>
58#include <stdio.h> 59#include <stdio.h>
59#include <unistd.h> 60#include <unistd.h>
@@ -63,19 +64,34 @@ ENGINE_load_cryptodev(void)
63#include <errno.h> 64#include <errno.h>
64#include <string.h> 65#include <string.h>
65 66
67#ifdef __i386__
68#include <sys/sysctl.h>
69#include <machine/cpu.h>
70#include <machine/specialreg.h>
71
72#include <ssl/aes.h>
73
74static int check_viac3aes(void);
75#endif
76
66struct dev_crypto_state { 77struct dev_crypto_state {
67 struct session_op d_sess; 78 struct session_op d_sess;
68 int d_fd; 79 int d_fd;
69}; 80};
70 81
82struct dev_crypto_cipher {
83 int c_id;
84 int c_nid;
85 int c_ivmax;
86 int c_keylen;
87};
88
71static u_int32_t cryptodev_asymfeat = 0; 89static u_int32_t cryptodev_asymfeat = 0;
72 90
73static int get_asym_dev_crypto(void); 91static int get_asym_dev_crypto(void);
74static int open_dev_crypto(void); 92static int open_dev_crypto(void);
75static int get_dev_crypto(void); 93static int get_dev_crypto(void);
76static int cryptodev_max_iv(int cipher); 94static struct dev_crypto_cipher *cipher_nid_to_cryptodev(int nid);
77static int cryptodev_key_length_valid(int cipher, int len);
78static int cipher_nid_to_cryptodev(int nid);
79static int get_cryptodev_ciphers(const int **cnids); 95static int get_cryptodev_ciphers(const int **cnids);
80/*static int get_cryptodev_digests(const int **cnids);*/ 96/*static int get_cryptodev_digests(const int **cnids);*/
81static int cryptodev_usable_ciphers(const int **nids); 97static int cryptodev_usable_ciphers(const int **nids);
@@ -122,15 +138,12 @@ static const ENGINE_CMD_DEFN cryptodev_defns[] = {
122 { 0, NULL, NULL, 0 } 138 { 0, NULL, NULL, 0 }
123}; 139};
124 140
125static struct { 141static struct dev_crypto_cipher ciphers[] = {
126 int id;
127 int nid;
128 int ivmax;
129 int keylen;
130} ciphers[] = {
131 { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, 142 { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, },
132 { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, 143 { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, },
133 { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, }, 144 { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, },
145 { CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, },
146 { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, },
134 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, 147 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, },
135 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, }, 148 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, },
136 { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, 149 { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, },
@@ -153,7 +166,7 @@ static struct {
153#endif 166#endif
154 167
155/* 168/*
156 * Return a fd if /dev/crypto seems usable, 0 otherwise. 169 * Return a fd if /dev/crypto seems usable, -1 otherwise.
157 */ 170 */
158static int 171static int
159open_dev_crypto(void) 172open_dev_crypto(void)
@@ -180,8 +193,10 @@ get_dev_crypto(void)
180 193
181 if ((fd = open_dev_crypto()) == -1) 194 if ((fd = open_dev_crypto()) == -1)
182 return (-1); 195 return (-1);
183 if (ioctl(fd, CRIOGET, &retfd) == -1) 196 if (ioctl(fd, CRIOGET, &retfd) == -1) {
197 close(fd);
184 return (-1); 198 return (-1);
199 }
185 200
186 /* close on exec */ 201 /* close on exec */
187 if (fcntl(retfd, F_SETFD, 1) == -1) { 202 if (fcntl(retfd, F_SETFD, 1) == -1) {
@@ -202,48 +217,16 @@ get_asym_dev_crypto(void)
202 return fd; 217 return fd;
203} 218}
204 219
205/*
206 * XXXX this needs to be set for each alg - and determined from
207 * a running card.
208 */
209static int
210cryptodev_max_iv(int cipher)
211{
212 int i;
213
214 for (i = 0; ciphers[i].id; i++)
215 if (ciphers[i].id == cipher)
216 return (ciphers[i].ivmax);
217 return (0);
218}
219
220/*
221 * XXXX this needs to be set for each alg - and determined from
222 * a running card. For now, fake it out - but most of these
223 * for real devices should return 1 for the supported key
224 * sizes the device can handle.
225 */
226static int
227cryptodev_key_length_valid(int cipher, int len)
228{
229 int i;
230
231 for (i = 0; ciphers[i].id; i++)
232 if (ciphers[i].id == cipher)
233 return (ciphers[i].keylen == len);
234 return (0);
235}
236
237/* convert libcrypto nids to cryptodev */ 220/* convert libcrypto nids to cryptodev */
238static int 221static struct dev_crypto_cipher *
239cipher_nid_to_cryptodev(int nid) 222cipher_nid_to_cryptodev(int nid)
240{ 223{
241 int i; 224 int i;
242 225
243 for (i = 0; ciphers[i].id; i++) 226 for (i = 0; ciphers[i].c_id; i++)
244 if (ciphers[i].nid == nid) 227 if (ciphers[i].c_nid == nid)
245 return (ciphers[i].id); 228 return (&ciphers[i]);
246 return (0); 229 return (NULL);
247} 230}
248 231
249/* 232/*
@@ -266,18 +249,45 @@ get_cryptodev_ciphers(const int **cnids)
266 memset(&sess, 0, sizeof(sess)); 249 memset(&sess, 0, sizeof(sess));
267 sess.key = (caddr_t)"123456781234567812345678"; 250 sess.key = (caddr_t)"123456781234567812345678";
268 251
269 for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { 252 for (i = 0; ciphers[i].c_id && count < CRYPTO_ALGORITHM_MAX; i++) {
270 if (ciphers[i].nid == NID_undef) 253 if (ciphers[i].c_nid == NID_undef)
271 continue; 254 continue;
272 sess.cipher = ciphers[i].id; 255 sess.cipher = ciphers[i].c_id;
273 sess.keylen = ciphers[i].keylen; 256 sess.keylen = ciphers[i].c_keylen;
274 sess.mac = 0; 257 sess.mac = 0;
275 if (ioctl(fd, CIOCGSESSION, &sess) != -1 && 258 if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
276 ioctl(fd, CIOCFSESSION, &sess.ses) != -1) 259 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
277 nids[count++] = ciphers[i].nid; 260 nids[count++] = ciphers[i].c_nid;
278 } 261 }
279 close(fd); 262 close(fd);
280 263
264#if defined(__i386__)
265 /*
266 * On i386, always check for the VIA C3 AES instructions;
267 * even if /dev/crypto is disabled.
268 */
269 if (check_viac3aes() >= 1) {
270 int have_NID_aes_128_cbc = 0;
271 int have_NID_aes_192_cbc = 0;
272 int have_NID_aes_256_cbc = 0;
273
274 for (i = 0; i < count; i++) {
275 if (nids[i] == NID_aes_128_cbc)
276 have_NID_aes_128_cbc = 1;
277 if (nids[i] == NID_aes_192_cbc)
278 have_NID_aes_192_cbc = 1;
279 if (nids[i] == NID_aes_256_cbc)
280 have_NID_aes_256_cbc = 1;
281 }
282 if (!have_NID_aes_128_cbc)
283 nids[count++] = NID_aes_128_cbc;
284 if (!have_NID_aes_192_cbc)
285 nids[count++] = NID_aes_192_cbc;
286 if (!have_NID_aes_256_cbc)
287 nids[count++] = NID_aes_256_cbc;
288 }
289#endif
290
281 if (count > 0) 291 if (count > 0)
282 *cnids = nids; 292 *cnids = nids;
283 else 293 else
@@ -429,15 +439,15 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
429{ 439{
430 struct dev_crypto_state *state = ctx->cipher_data; 440 struct dev_crypto_state *state = ctx->cipher_data;
431 struct session_op *sess = &state->d_sess; 441 struct session_op *sess = &state->d_sess;
432 int cipher; 442 struct dev_crypto_cipher *cipher;
433 443
434 if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) 444 if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NULL)
435 return (0); 445 return (0);
436 446
437 if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) 447 if (ctx->cipher->iv_len > cipher->c_ivmax)
438 return (0); 448 return (0);
439 449
440 if (!cryptodev_key_length_valid(cipher, ctx->key_len)) 450 if (ctx->key_len != cipher->c_keylen)
441 return (0); 451 return (0);
442 452
443 memset(sess, 0, sizeof(struct session_op)); 453 memset(sess, 0, sizeof(struct session_op));
@@ -447,7 +457,7 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
447 457
448 sess->key = (unsigned char *)key; 458 sess->key = (unsigned char *)key;
449 sess->keylen = ctx->key_len; 459 sess->keylen = ctx->key_len;
450 sess->cipher = cipher; 460 sess->cipher = cipher->c_id;
451 461
452 if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { 462 if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
453 close(state->d_fd); 463 close(state->d_fd);
@@ -552,7 +562,7 @@ const EVP_CIPHER cryptodev_cast_cbc = {
552 NULL 562 NULL
553}; 563};
554 564
555const EVP_CIPHER cryptodev_aes_cbc = { 565EVP_CIPHER cryptodev_aes_128_cbc = {
556 NID_aes_128_cbc, 566 NID_aes_128_cbc,
557 16, 16, 16, 567 16, 16, 16,
558 EVP_CIPH_CBC_MODE, 568 EVP_CIPH_CBC_MODE,
@@ -565,6 +575,209 @@ const EVP_CIPHER cryptodev_aes_cbc = {
565 NULL 575 NULL
566}; 576};
567 577
578EVP_CIPHER cryptodev_aes_192_cbc = {
579 NID_aes_192_cbc,
580 16, 24, 16,
581 EVP_CIPH_CBC_MODE,
582 cryptodev_init_key,
583 cryptodev_cipher,
584 cryptodev_cleanup,
585 sizeof(struct dev_crypto_state),
586 EVP_CIPHER_set_asn1_iv,
587 EVP_CIPHER_get_asn1_iv,
588 NULL
589};
590
591EVP_CIPHER cryptodev_aes_256_cbc = {
592 NID_aes_256_cbc,
593 16, 32, 16,
594 EVP_CIPH_CBC_MODE,
595 cryptodev_init_key,
596 cryptodev_cipher,
597 cryptodev_cleanup,
598 sizeof(struct dev_crypto_state),
599 EVP_CIPHER_set_asn1_iv,
600 EVP_CIPHER_get_asn1_iv,
601 NULL
602};
603
604#if defined(__i386__)
605
606static inline void
607viac3_xcrypt_cbc(int *cw, const void *src, void *dst, void *key, int rep,
608 void *iv)
609{
610#ifdef notdef
611 printf("cw %x[%x %x %x %x] src %x dst %x key %x rep %x iv %x\n",
612 cw, cw[0], cw[1], cw[2], cw[3],
613 src, dst, key, rep, iv);
614#endif
615 /*
616 * Clear bit 30 of EFLAGS.
617 */
618 __asm __volatile("pushfl; popfl");
619
620 /*
621 * Cannot simply place key into "b" register, since the compiler
622 * -pic mode uses that register; so instead we must dance a little.
623 */
624 __asm __volatile("pushl %%ebx; movl %0, %%ebx; rep xcrypt-cbc; popl %%ebx" :
625 : "mr" (key), "a" (iv), "c" (rep), "d" (cw), "S" (src), "D" (dst)
626 : "memory", "cc");
627}
628
629#define ISUNALIGNED(x) ((long)(x)) & 15
630#define DOALIGN(v) ((void *)(((long)(v) + 15) & ~15))
631
632static int
633xcrypt_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
634 const unsigned char *in, unsigned int inl)
635{
636 unsigned char *save_iv_store[EVP_MAX_IV_LENGTH + 15];
637 unsigned char *save_iv = DOALIGN(save_iv_store);
638 unsigned char *ivs_store[EVP_MAX_IV_LENGTH + 15];
639 unsigned char *ivs = DOALIGN(ivs_store);
640 void *iiv, *iv = NULL, *ivp = NULL;
641 const void *usein = in;
642 void *useout = out, *spare;
643 int cws[4 + 3], *cw = DOALIGN(cws);
644
645 if (!inl)
646 return (1);
647 if ((inl % ctx->cipher->block_size) != 0)
648 return (0);
649
650 if (ISUNALIGNED(in) || ISUNALIGNED(out)) {
651 spare = malloc(inl);
652 if (spare == NULL)
653 return (0);
654
655 if (ISUNALIGNED(in)) {
656 bcopy(in, spare, inl);
657 usein = spare;
658 }
659 if (ISUNALIGNED(out))
660 useout = spare;
661 }
662
663 cw[0] = C3_CRYPT_CWLO_ALG_AES | C3_CRYPT_CWLO_KEYGEN_SW |
664 C3_CRYPT_CWLO_NORMAL;
665 cw[0] |= ctx->encrypt ? C3_CRYPT_CWLO_ENCRYPT : C3_CRYPT_CWLO_DECRYPT;
666 cw[1] = cw[2] = cw[3] = 0;
667
668 switch (ctx->key_len * 8) {
669 case 128:
670 cw[0] |= C3_CRYPT_CWLO_KEY128;
671 break;
672 case 192:
673 cw[0] |= C3_CRYPT_CWLO_KEY192;
674 break;
675 case 256:
676 cw[0] |= C3_CRYPT_CWLO_KEY256;
677 break;
678 }
679
680 if (ctx->cipher->iv_len) {
681 iv = (caddr_t) ctx->iv;
682 if (!ctx->encrypt) {
683 iiv = (void *) in + inl - ctx->cipher->iv_len;
684 memcpy(save_iv, iiv, ctx->cipher->iv_len);
685 }
686 }
687
688 ivp = iv;
689 if (ISUNALIGNED(iv)) {
690 bcopy(iv, ivs, ctx->cipher->iv_len);
691 ivp = ivs;
692 }
693
694 viac3_xcrypt_cbc(cw, usein, useout, ctx->cipher_data, inl / 16, ivp);
695
696 if (ISUNALIGNED(out)) {
697 bcopy(spare, out, inl);
698 free(spare);
699 }
700
701 if (ivp == ivs)
702 bcopy(ivp, iv, ctx->cipher->iv_len);
703
704 if (ctx->cipher->iv_len) {
705 if (ctx->encrypt)
706 iiv = (void *) out + inl - ctx->cipher->iv_len;
707 else
708 iiv = save_iv;
709 memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
710 }
711 return (1);
712}
713
714static int
715xcrypt_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
716 const unsigned char *iv, int enc)
717{
718 AES_KEY *k = ctx->cipher_data;
719#ifndef AES_ASM
720 int i;
721#endif
722
723 bzero(k, sizeof *k);
724 if (enc)
725 AES_set_encrypt_key(key, ctx->key_len * 8, k);
726 else
727 AES_set_decrypt_key(key, ctx->key_len * 8, k);
728
729#ifndef AES_ASM
730 /*
731 * XXX Damn OpenSSL byte swaps the expanded key!!
732 *
733 * XXX But only if we're using the C implementation of AES
734 */
735 for (i = 0; i < 4 * (AES_MAXNR + 1); i++)
736 k->rd_key[i] = htonl(k->rd_key[i]);
737#endif
738
739 return (1);
740}
741
742static int
743xcrypt_cleanup(EVP_CIPHER_CTX *ctx)
744{
745 bzero(ctx->cipher_data, ctx->cipher->ctx_size);
746 return (1);
747}
748
749static int
750check_viac3aes(void)
751{
752 int mib[2] = { CTL_MACHDEP, CPU_XCRYPT }, value;
753 size_t size = sizeof(value);
754
755 if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &value, &size,
756 NULL, 0) < 0)
757 return (0);
758 if (value == 0)
759 return (0);
760
761 if (value & C3_HAS_AES) {
762 cryptodev_aes_128_cbc.init = xcrypt_init_key;
763 cryptodev_aes_128_cbc.do_cipher = xcrypt_cipher;
764 cryptodev_aes_128_cbc.cleanup = xcrypt_cleanup;
765 cryptodev_aes_128_cbc.ctx_size = sizeof(AES_KEY);
766
767 cryptodev_aes_192_cbc.init = xcrypt_init_key;
768 cryptodev_aes_192_cbc.do_cipher = xcrypt_cipher;
769 cryptodev_aes_192_cbc.cleanup = xcrypt_cleanup;
770 cryptodev_aes_192_cbc.ctx_size = sizeof(AES_KEY);
771
772 cryptodev_aes_256_cbc.init = xcrypt_init_key;
773 cryptodev_aes_256_cbc.do_cipher = xcrypt_cipher;
774 cryptodev_aes_256_cbc.cleanup = xcrypt_cleanup;
775 cryptodev_aes_256_cbc.ctx_size = sizeof(AES_KEY);
776 }
777 return (value);
778}
779#endif /* __i386__ */
780
568/* 781/*
569 * Registered by the ENGINE when used to find out how to deal with 782 * Registered by the ENGINE when used to find out how to deal with
570 * a particular NID in the ENGINE. this says what we'll do at the 783 * a particular NID in the ENGINE. this says what we'll do at the
@@ -591,7 +804,13 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
591 *cipher = &cryptodev_cast_cbc; 804 *cipher = &cryptodev_cast_cbc;
592 break; 805 break;
593 case NID_aes_128_cbc: 806 case NID_aes_128_cbc:
594 *cipher = &cryptodev_aes_cbc; 807 *cipher = &cryptodev_aes_128_cbc;
808 break;
809 case NID_aes_192_cbc:
810 *cipher = &cryptodev_aes_192_cbc;
811 break;
812 case NID_aes_256_cbc:
813 *cipher = &cryptodev_aes_256_cbc;
595 break; 814 break;
596 default: 815 default:
597 *cipher = NULL; 816 *cipher = NULL;