diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/engine/hw_cryptodev.c | 178 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/engine/hw_cryptodev.c | 178 |
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> | ||
71 | static void check_viac3aes(void); | ||
72 | #endif | ||
73 | |||
66 | struct dev_crypto_state { | 74 | struct 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 | ||
521 | const EVP_CIPHER cryptodev_aes_128_cbc = { | 537 | EVP_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 | ||
534 | const EVP_CIPHER cryptodev_aes_192_cbc = { | 550 | EVP_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 | ||
547 | const EVP_CIPHER cryptodev_aes_256_cbc = { | 563 | EVP_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 | |||
578 | volatile static void | ||
579 | viac3_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 | |||
604 | static int | ||
605 | xcrypt_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 | |||
686 | static int | ||
687 | xcrypt_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 | |||
694 | static int | ||
695 | xcrypt_cleanup(EVP_CIPHER_CTX *ctx) | ||
696 | { | ||
697 | bzero(ctx->cipher_data, ctx->key_len); | ||
698 | return (1); | ||
699 | } | ||
700 | |||
701 | static void | ||
702 | check_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> | ||
71 | static void check_viac3aes(void); | ||
72 | #endif | ||
73 | |||
66 | struct dev_crypto_state { | 74 | struct 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 | ||
521 | const EVP_CIPHER cryptodev_aes_128_cbc = { | 537 | EVP_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 | ||
534 | const EVP_CIPHER cryptodev_aes_192_cbc = { | 550 | EVP_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 | ||
547 | const EVP_CIPHER cryptodev_aes_256_cbc = { | 563 | EVP_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 | |||
578 | volatile static void | ||
579 | viac3_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 | |||
604 | static int | ||
605 | xcrypt_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 | |||
686 | static int | ||
687 | xcrypt_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 | |||
694 | static int | ||
695 | xcrypt_cleanup(EVP_CIPHER_CTX *ctx) | ||
696 | { | ||
697 | bzero(ctx->cipher_data, ctx->key_len); | ||
698 | return (1); | ||
699 | } | ||
700 | |||
701 | static void | ||
702 | check_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 |