diff options
author | Lee Nipper <lee.nipper@freescale.com> | 2008-07-03 07:08:46 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2008-07-10 08:35:17 -0400 |
commit | 70bcaca75389a6c011ddc866eb1743b070a838b0 (patch) | |
tree | 531601ecc27517eca37c745be54c5fc6bb67337a /drivers/crypto/talitos.c | |
parent | b43e726b32b85713c7c56b6545cf71c2b02b5e1a (diff) |
crypto: talitos - Add support for 3des
This patch adds support for authenc(hmac(sha1),cbc(des3_ede))
to the talitos crypto driver for the Freescale Security Engine.
Some adjustments were made to the scatterlist to link table conversion
to make 3des work for ping -s 1439..1446.
Signed-off-by: Lee Nipper <lee.nipper@freescale.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/talitos.c')
-rw-r--r-- | drivers/crypto/talitos.c | 93 |
1 files changed, 68 insertions, 25 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index e12331296a00..e8459e00da31 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c | |||
@@ -642,20 +642,24 @@ static void talitos_unregister_rng(struct device *dev) | |||
642 | #define TALITOS_MAX_KEY_SIZE 64 | 642 | #define TALITOS_MAX_KEY_SIZE 64 |
643 | #define TALITOS_MAX_AUTH_SIZE 20 | 643 | #define TALITOS_MAX_AUTH_SIZE 20 |
644 | #define TALITOS_AES_MIN_BLOCK_SIZE 16 | 644 | #define TALITOS_AES_MIN_BLOCK_SIZE 16 |
645 | #define TALITOS_3DES_MIN_BLOCK_SIZE 24 | ||
646 | |||
645 | #define TALITOS_AES_IV_LENGTH 16 | 647 | #define TALITOS_AES_IV_LENGTH 16 |
648 | #define TALITOS_3DES_IV_LENGTH 8 | ||
649 | #define TALITOS_MAX_IV_LENGTH 16 | ||
646 | 650 | ||
647 | struct talitos_ctx { | 651 | struct talitos_ctx { |
648 | struct device *dev; | 652 | struct device *dev; |
649 | __be32 desc_hdr_template; | 653 | __be32 desc_hdr_template; |
650 | u8 key[TALITOS_MAX_KEY_SIZE]; | 654 | u8 key[TALITOS_MAX_KEY_SIZE]; |
651 | u8 iv[TALITOS_AES_IV_LENGTH]; | 655 | u8 iv[TALITOS_MAX_IV_LENGTH]; |
652 | unsigned int keylen; | 656 | unsigned int keylen; |
653 | unsigned int enckeylen; | 657 | unsigned int enckeylen; |
654 | unsigned int authkeylen; | 658 | unsigned int authkeylen; |
655 | unsigned int authsize; | 659 | unsigned int authsize; |
656 | }; | 660 | }; |
657 | 661 | ||
658 | static int aes_cbc_sha1_hmac_authenc_setauthsize(struct crypto_aead *authenc, | 662 | static int aead_authenc_setauthsize(struct crypto_aead *authenc, |
659 | unsigned int authsize) | 663 | unsigned int authsize) |
660 | { | 664 | { |
661 | struct talitos_ctx *ctx = crypto_aead_ctx(authenc); | 665 | struct talitos_ctx *ctx = crypto_aead_ctx(authenc); |
@@ -665,7 +669,7 @@ static int aes_cbc_sha1_hmac_authenc_setauthsize(struct crypto_aead *authenc, | |||
665 | return 0; | 669 | return 0; |
666 | } | 670 | } |
667 | 671 | ||
668 | static int aes_cbc_sha1_hmac_authenc_setkey(struct crypto_aead *authenc, | 672 | static int aead_authenc_setkey(struct crypto_aead *authenc, |
669 | const u8 *key, unsigned int keylen) | 673 | const u8 *key, unsigned int keylen) |
670 | { | 674 | { |
671 | struct talitos_ctx *ctx = crypto_aead_ctx(authenc); | 675 | struct talitos_ctx *ctx = crypto_aead_ctx(authenc); |
@@ -825,10 +829,12 @@ static void ipsec_esp_decrypt_done(struct device *dev, | |||
825 | * convert scatterlist to SEC h/w link table format | 829 | * convert scatterlist to SEC h/w link table format |
826 | * stop at cryptlen bytes | 830 | * stop at cryptlen bytes |
827 | */ | 831 | */ |
828 | static void sg_to_link_tbl(struct scatterlist *sg, int sg_count, | 832 | static int sg_to_link_tbl(struct scatterlist *sg, int sg_count, |
829 | int cryptlen, struct talitos_ptr *link_tbl_ptr) | 833 | int cryptlen, struct talitos_ptr *link_tbl_ptr) |
830 | { | 834 | { |
831 | while (cryptlen > 0) { | 835 | int n_sg = sg_count; |
836 | |||
837 | while (n_sg--) { | ||
832 | link_tbl_ptr->ptr = cpu_to_be32(sg_dma_address(sg)); | 838 | link_tbl_ptr->ptr = cpu_to_be32(sg_dma_address(sg)); |
833 | link_tbl_ptr->len = cpu_to_be16(sg_dma_len(sg)); | 839 | link_tbl_ptr->len = cpu_to_be16(sg_dma_len(sg)); |
834 | link_tbl_ptr->j_extent = 0; | 840 | link_tbl_ptr->j_extent = 0; |
@@ -837,13 +843,22 @@ static void sg_to_link_tbl(struct scatterlist *sg, int sg_count, | |||
837 | sg = sg_next(sg); | 843 | sg = sg_next(sg); |
838 | } | 844 | } |
839 | 845 | ||
840 | /* adjust (decrease) last entry's len to cryptlen */ | 846 | /* adjust (decrease) last one (or two) entry's len to cryptlen */ |
841 | link_tbl_ptr--; | 847 | link_tbl_ptr--; |
848 | while (link_tbl_ptr->len <= (-cryptlen)) { | ||
849 | /* Empty this entry, and move to previous one */ | ||
850 | cryptlen += be16_to_cpu(link_tbl_ptr->len); | ||
851 | link_tbl_ptr->len = 0; | ||
852 | sg_count--; | ||
853 | link_tbl_ptr--; | ||
854 | } | ||
842 | link_tbl_ptr->len = cpu_to_be16(be16_to_cpu(link_tbl_ptr->len) | 855 | link_tbl_ptr->len = cpu_to_be16(be16_to_cpu(link_tbl_ptr->len) |
843 | + cryptlen); | 856 | + cryptlen); |
844 | 857 | ||
845 | /* tag end of link table */ | 858 | /* tag end of link table */ |
846 | link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN; | 859 | link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN; |
860 | |||
861 | return sg_count; | ||
847 | } | 862 | } |
848 | 863 | ||
849 | /* | 864 | /* |
@@ -900,12 +915,17 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq, | |||
900 | if (sg_count == 1) { | 915 | if (sg_count == 1) { |
901 | desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src)); | 916 | desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src)); |
902 | } else { | 917 | } else { |
903 | sg_to_link_tbl(areq->src, sg_count, cryptlen, | 918 | sg_count = sg_to_link_tbl(areq->src, sg_count, cryptlen, |
904 | &edesc->link_tbl[0]); | 919 | &edesc->link_tbl[0]); |
905 | desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; | 920 | if (sg_count > 1) { |
906 | desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl); | 921 | desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; |
907 | dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, | 922 | desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl); |
908 | edesc->dma_len, DMA_BIDIRECTIONAL); | 923 | dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, |
924 | edesc->dma_len, DMA_BIDIRECTIONAL); | ||
925 | } else { | ||
926 | /* Only one segment now, so no link tbl needed */ | ||
927 | desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src)); | ||
928 | } | ||
909 | } | 929 | } |
910 | 930 | ||
911 | /* cipher out */ | 931 | /* cipher out */ |
@@ -931,8 +951,8 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq, | |||
931 | memcpy(link_tbl_ptr, &edesc->link_tbl[0], | 951 | memcpy(link_tbl_ptr, &edesc->link_tbl[0], |
932 | edesc->src_nents * sizeof(struct talitos_ptr)); | 952 | edesc->src_nents * sizeof(struct talitos_ptr)); |
933 | } else { | 953 | } else { |
934 | sg_to_link_tbl(areq->dst, sg_count, cryptlen, | 954 | sg_count = sg_to_link_tbl(areq->dst, sg_count, cryptlen, |
935 | link_tbl_ptr); | 955 | link_tbl_ptr); |
936 | } | 956 | } |
937 | link_tbl_ptr += sg_count - 1; | 957 | link_tbl_ptr += sg_count - 1; |
938 | 958 | ||
@@ -1038,7 +1058,7 @@ static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq, | |||
1038 | return edesc; | 1058 | return edesc; |
1039 | } | 1059 | } |
1040 | 1060 | ||
1041 | static int aes_cbc_sha1_hmac_authenc_encrypt(struct aead_request *req) | 1061 | static int aead_authenc_encrypt(struct aead_request *req) |
1042 | { | 1062 | { |
1043 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); | 1063 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); |
1044 | struct talitos_ctx *ctx = crypto_aead_ctx(authenc); | 1064 | struct talitos_ctx *ctx = crypto_aead_ctx(authenc); |
@@ -1050,12 +1070,12 @@ static int aes_cbc_sha1_hmac_authenc_encrypt(struct aead_request *req) | |||
1050 | return PTR_ERR(edesc); | 1070 | return PTR_ERR(edesc); |
1051 | 1071 | ||
1052 | /* set encrypt */ | 1072 | /* set encrypt */ |
1053 | edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_AESU_ENC; | 1073 | edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT; |
1054 | 1074 | ||
1055 | return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_encrypt_done); | 1075 | return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_encrypt_done); |
1056 | } | 1076 | } |
1057 | 1077 | ||
1058 | static int aes_cbc_sha1_hmac_authenc_decrypt(struct aead_request *req) | 1078 | static int aead_authenc_decrypt(struct aead_request *req) |
1059 | { | 1079 | { |
1060 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); | 1080 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); |
1061 | struct talitos_ctx *ctx = crypto_aead_ctx(authenc); | 1081 | struct talitos_ctx *ctx = crypto_aead_ctx(authenc); |
@@ -1089,7 +1109,7 @@ static int aes_cbc_sha1_hmac_authenc_decrypt(struct aead_request *req) | |||
1089 | return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_done); | 1109 | return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_done); |
1090 | } | 1110 | } |
1091 | 1111 | ||
1092 | static int aes_cbc_sha1_hmac_authenc_givencrypt( | 1112 | static int aead_authenc_givencrypt( |
1093 | struct aead_givcrypt_request *req) | 1113 | struct aead_givcrypt_request *req) |
1094 | { | 1114 | { |
1095 | struct aead_request *areq = &req->areq; | 1115 | struct aead_request *areq = &req->areq; |
@@ -1103,7 +1123,7 @@ static int aes_cbc_sha1_hmac_authenc_givencrypt( | |||
1103 | return PTR_ERR(edesc); | 1123 | return PTR_ERR(edesc); |
1104 | 1124 | ||
1105 | /* set encrypt */ | 1125 | /* set encrypt */ |
1106 | edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_AESU_ENC; | 1126 | edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT; |
1107 | 1127 | ||
1108 | memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc)); | 1128 | memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc)); |
1109 | 1129 | ||
@@ -1127,11 +1147,11 @@ static struct talitos_alg_template driver_algs[] = { | |||
1127 | .driver_name = "authenc(hmac(sha1-talitos),cbc(aes-talitos))", | 1147 | .driver_name = "authenc(hmac(sha1-talitos),cbc(aes-talitos))", |
1128 | .blocksize = TALITOS_AES_MIN_BLOCK_SIZE, | 1148 | .blocksize = TALITOS_AES_MIN_BLOCK_SIZE, |
1129 | .aead = { | 1149 | .aead = { |
1130 | .setkey = aes_cbc_sha1_hmac_authenc_setkey, | 1150 | .setkey = aead_authenc_setkey, |
1131 | .setauthsize = aes_cbc_sha1_hmac_authenc_setauthsize, | 1151 | .setauthsize = aead_authenc_setauthsize, |
1132 | .encrypt = aes_cbc_sha1_hmac_authenc_encrypt, | 1152 | .encrypt = aead_authenc_encrypt, |
1133 | .decrypt = aes_cbc_sha1_hmac_authenc_decrypt, | 1153 | .decrypt = aead_authenc_decrypt, |
1134 | .givencrypt = aes_cbc_sha1_hmac_authenc_givencrypt, | 1154 | .givencrypt = aead_authenc_givencrypt, |
1135 | .geniv = "<built-in>", | 1155 | .geniv = "<built-in>", |
1136 | .ivsize = TALITOS_AES_IV_LENGTH, | 1156 | .ivsize = TALITOS_AES_IV_LENGTH, |
1137 | .maxauthsize = TALITOS_MAX_AUTH_SIZE, | 1157 | .maxauthsize = TALITOS_MAX_AUTH_SIZE, |
@@ -1143,6 +1163,29 @@ static struct talitos_alg_template driver_algs[] = { | |||
1143 | DESC_HDR_MODE1_MDEU_INIT | | 1163 | DESC_HDR_MODE1_MDEU_INIT | |
1144 | DESC_HDR_MODE1_MDEU_PAD | | 1164 | DESC_HDR_MODE1_MDEU_PAD | |
1145 | DESC_HDR_MODE1_MDEU_SHA1_HMAC, | 1165 | DESC_HDR_MODE1_MDEU_SHA1_HMAC, |
1166 | }, | ||
1167 | { | ||
1168 | .name = "authenc(hmac(sha1),cbc(des3_ede))", | ||
1169 | .driver_name = "authenc(hmac(sha1-talitos),cbc(3des-talitos))", | ||
1170 | .blocksize = TALITOS_3DES_MIN_BLOCK_SIZE, | ||
1171 | .aead = { | ||
1172 | .setkey = aead_authenc_setkey, | ||
1173 | .setauthsize = aead_authenc_setauthsize, | ||
1174 | .encrypt = aead_authenc_encrypt, | ||
1175 | .decrypt = aead_authenc_decrypt, | ||
1176 | .givencrypt = aead_authenc_givencrypt, | ||
1177 | .geniv = "<built-in>", | ||
1178 | .ivsize = TALITOS_3DES_IV_LENGTH, | ||
1179 | .maxauthsize = TALITOS_MAX_AUTH_SIZE, | ||
1180 | }, | ||
1181 | .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | | ||
1182 | DESC_HDR_SEL0_DEU | | ||
1183 | DESC_HDR_MODE0_DEU_CBC | | ||
1184 | DESC_HDR_MODE0_DEU_3DES | | ||
1185 | DESC_HDR_SEL1_MDEUA | | ||
1186 | DESC_HDR_MODE1_MDEU_INIT | | ||
1187 | DESC_HDR_MODE1_MDEU_PAD | | ||
1188 | DESC_HDR_MODE1_MDEU_SHA1_HMAC, | ||
1146 | } | 1189 | } |
1147 | }; | 1190 | }; |
1148 | 1191 | ||
@@ -1166,7 +1209,7 @@ static int talitos_cra_init(struct crypto_tfm *tfm) | |||
1166 | ctx->desc_hdr_template = talitos_alg->desc_hdr_template; | 1209 | ctx->desc_hdr_template = talitos_alg->desc_hdr_template; |
1167 | 1210 | ||
1168 | /* random first IV */ | 1211 | /* random first IV */ |
1169 | get_random_bytes(ctx->iv, TALITOS_AES_IV_LENGTH); | 1212 | get_random_bytes(ctx->iv, TALITOS_MAX_IV_LENGTH); |
1170 | 1213 | ||
1171 | return 0; | 1214 | return 0; |
1172 | } | 1215 | } |