summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/engine/hw_cryptodev.c178
-rw-r--r--src/lib/libssl/src/crypto/engine/hw_cryptodev.c178
2 files changed, 348 insertions, 8 deletions
diff --git a/src/lib/libcrypto/engine/hw_cryptodev.c b/src/lib/libcrypto/engine/hw_cryptodev.c
index b502d12b6d..4959c67e92 100644
--- a/src/lib/libcrypto/engine/hw_cryptodev.c
+++ b/src/lib/libcrypto/engine/hw_cryptodev.c
@@ -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,6 +64,13 @@ 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>
71static void check_viac3aes(void);
72#endif
73
66struct dev_crypto_state { 74struct dev_crypto_state {
67 struct session_op d_sess; 75 struct session_op d_sess;
68 int d_fd; 76 int d_fd;
@@ -246,6 +254,14 @@ get_cryptodev_ciphers(const int **cnids)
246 } 254 }
247 close(fd); 255 close(fd);
248 256
257#if defined(__i386__)
258 /*
259 * On i386, always check for the VIA C3 AES instructions;
260 * even if /dev/crypto is disabled.
261 */
262 check_viac3aes();
263#endif
264
249 if (count > 0) 265 if (count > 0)
250 *cnids = nids; 266 *cnids = nids;
251 else 267 else
@@ -518,7 +534,7 @@ const EVP_CIPHER cryptodev_cast_cbc = {
518 NULL 534 NULL
519}; 535};
520 536
521const EVP_CIPHER cryptodev_aes_128_cbc = { 537EVP_CIPHER cryptodev_aes_128_cbc = {
522 NID_aes_128_cbc, 538 NID_aes_128_cbc,
523 16, 16, 16, 539 16, 16, 16,
524 EVP_CIPH_CBC_MODE, 540 EVP_CIPH_CBC_MODE,
@@ -531,7 +547,7 @@ const EVP_CIPHER cryptodev_aes_128_cbc = {
531 NULL 547 NULL
532}; 548};
533 549
534const EVP_CIPHER cryptodev_aes_192_cbc = { 550EVP_CIPHER cryptodev_aes_192_cbc = {
535 NID_aes_192_cbc, 551 NID_aes_192_cbc,
536 16, 24, 16, 552 16, 24, 16,
537 EVP_CIPH_CBC_MODE, 553 EVP_CIPH_CBC_MODE,
@@ -544,7 +560,7 @@ const EVP_CIPHER cryptodev_aes_192_cbc = {
544 NULL 560 NULL
545}; 561};
546 562
547const EVP_CIPHER cryptodev_aes_256_cbc = { 563EVP_CIPHER cryptodev_aes_256_cbc = {
548 NID_aes_256_cbc, 564 NID_aes_256_cbc,
549 16, 32, 16, 565 16, 32, 16,
550 EVP_CIPH_CBC_MODE, 566 EVP_CIPH_CBC_MODE,
@@ -557,6 +573,160 @@ const EVP_CIPHER cryptodev_aes_256_cbc = {
557 NULL 573 NULL
558}; 574};
559 575
576#if defined(__i386__)
577
578volatile static void
579viac3_crypto(int *cw, const void *src, void *dst, void *key, int rep,
580 void *iv)
581{
582#ifdef notdef
583 printf("cw %x[%x %x %x %x] src %x dst %x key %x rep %x iv %x\n",
584 cw, cw[0], cw[1], cw[2], cw[3],
585 src, dst, key, rep, iv);
586#endif
587 /*
588 * Clear bit 30 of EFLAGS.
589 */
590 __asm __volatile("pushfl; popfl");
591
592 /*
593 * Cannot simply place key into "b" register, since the compiler
594 * -pic mode uses that register; so instead we must dance a little.
595 */
596 __asm __volatile("pushl %%ebx; movl %0, %%ebx; rep xcrypt-cbc; popl %%ebx" :
597 : "mr" (key), "a" (iv), "c" (rep), "d" (cw), "S" (src), "D" (dst)
598 : "memory", "cc");
599}
600
601#define ISUNALIGNED(x) ((long)(x)) & 15
602#define DOALIGN(v) ((void *)(((long)(v) + 15) & ~15))
603
604static int
605xcrypt_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
606 const unsigned char *in, unsigned int inl)
607{
608 unsigned char *save_iv_store[EVP_MAX_IV_LENGTH + 15];
609 unsigned char *save_iv = DOALIGN(save_iv_store);
610 unsigned char *ivs_store[EVP_MAX_IV_LENGTH + 15];
611 unsigned char *ivs = DOALIGN(ivs_store);
612 void *iiv, *iv = NULL, *ivp = NULL;
613 const void *usein = in;
614 void *useout = out, *spare;
615 int cws[4 + 3], *cw = DOALIGN(cws);
616
617 if (!inl)
618 return (1);
619 if ((inl % ctx->cipher->block_size) != 0)
620 return (0);
621
622 if (ISUNALIGNED(in) || ISUNALIGNED(out)) {
623 spare = malloc(inl);
624 if (spare == NULL)
625 return (0);
626
627 if (ISUNALIGNED(in)) {
628 bcopy(in, spare, inl);
629 usein = spare;
630 }
631 if (ISUNALIGNED(out))
632 useout = spare;
633 }
634
635 cw[0] = C3_CRYPT_CWLO_ALG_AES | C3_CRYPT_CWLO_KEYGEN_HW |
636 C3_CRYPT_CWLO_NORMAL |
637 ctx->encrypt ? C3_CRYPT_CWLO_ENCRYPT : C3_CRYPT_CWLO_DECRYPT;
638 cw[1] = cw[2] = cw[3] = 0;
639
640 switch (ctx->key_len * 8) {
641 case 128:
642 cw[0] |= C3_CRYPT_CWLO_KEY128;
643 break;
644 case 192:
645 cw[0] |= C3_CRYPT_CWLO_KEY192;
646 break;
647 case 256:
648 cw[0] |= C3_CRYPT_CWLO_KEY256;
649 break;
650 }
651
652 if (ctx->cipher->iv_len) {
653 iv = (caddr_t) ctx->iv;
654 if (!ctx->encrypt) {
655 iiv = (void *) in + inl - ctx->cipher->iv_len;
656 memcpy(save_iv, iiv, ctx->cipher->iv_len);
657 }
658 }
659
660 ivp = iv;
661 if (ISUNALIGNED(iv)) {
662 bcopy(iv, ivs, ctx->cipher->iv_len);
663 ivp = ivs;
664 }
665
666 viac3_crypto(cw, usein, useout, ctx->cipher_data, inl / 16, ivp);
667
668 if (ISUNALIGNED(out)) {
669 bcopy(spare, out, inl);
670 free(spare);
671 }
672
673 if (ivp == ivs)
674 bcopy(ivp, iv, ctx->cipher->iv_len);
675
676 if (ctx->cipher->iv_len) {
677 if (ctx->encrypt)
678 iiv = (void *) out + inl - ctx->cipher->iv_len;
679 else
680 iiv = save_iv;
681 memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
682 }
683 return (1);
684}
685
686static int
687xcrypt_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
688 const unsigned char *iv, int enc)
689{
690 bcopy(key, ctx->cipher_data, ctx->key_len);
691 return (1);
692}
693
694static int
695xcrypt_cleanup(EVP_CIPHER_CTX *ctx)
696{
697 bzero(ctx->cipher_data, ctx->key_len);
698 return (1);
699}
700
701static void
702check_viac3aes(void)
703{
704 int mib[2] = { CTL_MACHDEP, CPU_XCRYPT }, value;
705 size_t size = sizeof(value);
706
707 if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &value, &size,
708 NULL, 0) < 0)
709 return;
710 if (value == 0)
711 return;
712
713 cryptodev_aes_128_cbc.init = xcrypt_init_key;
714 cryptodev_aes_128_cbc.do_cipher = xcrypt_cipher;
715 cryptodev_aes_128_cbc.cleanup = xcrypt_cleanup;
716 cryptodev_aes_128_cbc.ctx_size = 128;
717
718 cryptodev_aes_192_cbc.init = xcrypt_init_key;
719 cryptodev_aes_192_cbc.do_cipher = xcrypt_cipher;
720 cryptodev_aes_192_cbc.cleanup = xcrypt_cleanup;
721 cryptodev_aes_192_cbc.ctx_size = 128;
722
723 cryptodev_aes_256_cbc.init = xcrypt_init_key;
724 cryptodev_aes_256_cbc.do_cipher = xcrypt_cipher;
725 cryptodev_aes_256_cbc.cleanup = xcrypt_cleanup;
726 cryptodev_aes_256_cbc.ctx_size = 128;
727}
728#endif /* __i386__ */
729
560/* 730/*
561 * Registered by the ENGINE when used to find out how to deal with 731 * Registered by the ENGINE when used to find out how to deal with
562 * a particular NID in the ENGINE. this says what we'll do at the 732 * a particular NID in the ENGINE. this says what we'll do at the
diff --git a/src/lib/libssl/src/crypto/engine/hw_cryptodev.c b/src/lib/libssl/src/crypto/engine/hw_cryptodev.c
index b502d12b6d..4959c67e92 100644
--- a/src/lib/libssl/src/crypto/engine/hw_cryptodev.c
+++ b/src/lib/libssl/src/crypto/engine/hw_cryptodev.c
@@ -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,6 +64,13 @@ 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>
71static void check_viac3aes(void);
72#endif
73
66struct dev_crypto_state { 74struct dev_crypto_state {
67 struct session_op d_sess; 75 struct session_op d_sess;
68 int d_fd; 76 int d_fd;
@@ -246,6 +254,14 @@ get_cryptodev_ciphers(const int **cnids)
246 } 254 }
247 close(fd); 255 close(fd);
248 256
257#if defined(__i386__)
258 /*
259 * On i386, always check for the VIA C3 AES instructions;
260 * even if /dev/crypto is disabled.
261 */
262 check_viac3aes();
263#endif
264
249 if (count > 0) 265 if (count > 0)
250 *cnids = nids; 266 *cnids = nids;
251 else 267 else
@@ -518,7 +534,7 @@ const EVP_CIPHER cryptodev_cast_cbc = {
518 NULL 534 NULL
519}; 535};
520 536
521const EVP_CIPHER cryptodev_aes_128_cbc = { 537EVP_CIPHER cryptodev_aes_128_cbc = {
522 NID_aes_128_cbc, 538 NID_aes_128_cbc,
523 16, 16, 16, 539 16, 16, 16,
524 EVP_CIPH_CBC_MODE, 540 EVP_CIPH_CBC_MODE,
@@ -531,7 +547,7 @@ const EVP_CIPHER cryptodev_aes_128_cbc = {
531 NULL 547 NULL
532}; 548};
533 549
534const EVP_CIPHER cryptodev_aes_192_cbc = { 550EVP_CIPHER cryptodev_aes_192_cbc = {
535 NID_aes_192_cbc, 551 NID_aes_192_cbc,
536 16, 24, 16, 552 16, 24, 16,
537 EVP_CIPH_CBC_MODE, 553 EVP_CIPH_CBC_MODE,
@@ -544,7 +560,7 @@ const EVP_CIPHER cryptodev_aes_192_cbc = {
544 NULL 560 NULL
545}; 561};
546 562
547const EVP_CIPHER cryptodev_aes_256_cbc = { 563EVP_CIPHER cryptodev_aes_256_cbc = {
548 NID_aes_256_cbc, 564 NID_aes_256_cbc,
549 16, 32, 16, 565 16, 32, 16,
550 EVP_CIPH_CBC_MODE, 566 EVP_CIPH_CBC_MODE,
@@ -557,6 +573,160 @@ const EVP_CIPHER cryptodev_aes_256_cbc = {
557 NULL 573 NULL
558}; 574};
559 575
576#if defined(__i386__)
577
578volatile static void
579viac3_crypto(int *cw, const void *src, void *dst, void *key, int rep,
580 void *iv)
581{
582#ifdef notdef
583 printf("cw %x[%x %x %x %x] src %x dst %x key %x rep %x iv %x\n",
584 cw, cw[0], cw[1], cw[2], cw[3],
585 src, dst, key, rep, iv);
586#endif
587 /*
588 * Clear bit 30 of EFLAGS.
589 */
590 __asm __volatile("pushfl; popfl");
591
592 /*
593 * Cannot simply place key into "b" register, since the compiler
594 * -pic mode uses that register; so instead we must dance a little.
595 */
596 __asm __volatile("pushl %%ebx; movl %0, %%ebx; rep xcrypt-cbc; popl %%ebx" :
597 : "mr" (key), "a" (iv), "c" (rep), "d" (cw), "S" (src), "D" (dst)
598 : "memory", "cc");
599}
600
601#define ISUNALIGNED(x) ((long)(x)) & 15
602#define DOALIGN(v) ((void *)(((long)(v) + 15) & ~15))
603
604static int
605xcrypt_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
606 const unsigned char *in, unsigned int inl)
607{
608 unsigned char *save_iv_store[EVP_MAX_IV_LENGTH + 15];
609 unsigned char *save_iv = DOALIGN(save_iv_store);
610 unsigned char *ivs_store[EVP_MAX_IV_LENGTH + 15];
611 unsigned char *ivs = DOALIGN(ivs_store);
612 void *iiv, *iv = NULL, *ivp = NULL;
613 const void *usein = in;
614 void *useout = out, *spare;
615 int cws[4 + 3], *cw = DOALIGN(cws);
616
617 if (!inl)
618 return (1);
619 if ((inl % ctx->cipher->block_size) != 0)
620 return (0);
621
622 if (ISUNALIGNED(in) || ISUNALIGNED(out)) {
623 spare = malloc(inl);
624 if (spare == NULL)
625 return (0);
626
627 if (ISUNALIGNED(in)) {
628 bcopy(in, spare, inl);
629 usein = spare;
630 }
631 if (ISUNALIGNED(out))
632 useout = spare;
633 }
634
635 cw[0] = C3_CRYPT_CWLO_ALG_AES | C3_CRYPT_CWLO_KEYGEN_HW |
636 C3_CRYPT_CWLO_NORMAL |
637 ctx->encrypt ? C3_CRYPT_CWLO_ENCRYPT : C3_CRYPT_CWLO_DECRYPT;
638 cw[1] = cw[2] = cw[3] = 0;
639
640 switch (ctx->key_len * 8) {
641 case 128:
642 cw[0] |= C3_CRYPT_CWLO_KEY128;
643 break;
644 case 192:
645 cw[0] |= C3_CRYPT_CWLO_KEY192;
646 break;
647 case 256:
648 cw[0] |= C3_CRYPT_CWLO_KEY256;
649 break;
650 }
651
652 if (ctx->cipher->iv_len) {
653 iv = (caddr_t) ctx->iv;
654 if (!ctx->encrypt) {
655 iiv = (void *) in + inl - ctx->cipher->iv_len;
656 memcpy(save_iv, iiv, ctx->cipher->iv_len);
657 }
658 }
659
660 ivp = iv;
661 if (ISUNALIGNED(iv)) {
662 bcopy(iv, ivs, ctx->cipher->iv_len);
663 ivp = ivs;
664 }
665
666 viac3_crypto(cw, usein, useout, ctx->cipher_data, inl / 16, ivp);
667
668 if (ISUNALIGNED(out)) {
669 bcopy(spare, out, inl);
670 free(spare);
671 }
672
673 if (ivp == ivs)
674 bcopy(ivp, iv, ctx->cipher->iv_len);
675
676 if (ctx->cipher->iv_len) {
677 if (ctx->encrypt)
678 iiv = (void *) out + inl - ctx->cipher->iv_len;
679 else
680 iiv = save_iv;
681 memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
682 }
683 return (1);
684}
685
686static int
687xcrypt_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
688 const unsigned char *iv, int enc)
689{
690 bcopy(key, ctx->cipher_data, ctx->key_len);
691 return (1);
692}
693
694static int
695xcrypt_cleanup(EVP_CIPHER_CTX *ctx)
696{
697 bzero(ctx->cipher_data, ctx->key_len);
698 return (1);
699}
700
701static void
702check_viac3aes(void)
703{
704 int mib[2] = { CTL_MACHDEP, CPU_XCRYPT }, value;
705 size_t size = sizeof(value);
706
707 if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &value, &size,
708 NULL, 0) < 0)
709 return;
710 if (value == 0)
711 return;
712
713 cryptodev_aes_128_cbc.init = xcrypt_init_key;
714 cryptodev_aes_128_cbc.do_cipher = xcrypt_cipher;
715 cryptodev_aes_128_cbc.cleanup = xcrypt_cleanup;
716 cryptodev_aes_128_cbc.ctx_size = 128;
717
718 cryptodev_aes_192_cbc.init = xcrypt_init_key;
719 cryptodev_aes_192_cbc.do_cipher = xcrypt_cipher;
720 cryptodev_aes_192_cbc.cleanup = xcrypt_cleanup;
721 cryptodev_aes_192_cbc.ctx_size = 128;
722
723 cryptodev_aes_256_cbc.init = xcrypt_init_key;
724 cryptodev_aes_256_cbc.do_cipher = xcrypt_cipher;
725 cryptodev_aes_256_cbc.cleanup = xcrypt_cleanup;
726 cryptodev_aes_256_cbc.ctx_size = 128;
727}
728#endif /* __i386__ */
729
560/* 730/*
561 * Registered by the ENGINE when used to find out how to deal with 731 * Registered by the ENGINE when used to find out how to deal with
562 * a particular NID in the ENGINE. this says what we'll do at the 732 * a particular NID in the ENGINE. this says what we'll do at the