aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/talitos.c
diff options
context:
space:
mode:
authorLee Nipper <lee.nipper@freescale.com>2008-07-03 07:08:46 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2008-07-10 08:35:17 -0400
commit70bcaca75389a6c011ddc866eb1743b070a838b0 (patch)
tree531601ecc27517eca37c745be54c5fc6bb67337a /drivers/crypto/talitos.c
parentb43e726b32b85713c7c56b6545cf71c2b02b5e1a (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.c93
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
647struct talitos_ctx { 651struct 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
658static int aes_cbc_sha1_hmac_authenc_setauthsize(struct crypto_aead *authenc, 662static 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
668static int aes_cbc_sha1_hmac_authenc_setkey(struct crypto_aead *authenc, 672static 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 */
828static void sg_to_link_tbl(struct scatterlist *sg, int sg_count, 832static 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
1041static int aes_cbc_sha1_hmac_authenc_encrypt(struct aead_request *req) 1061static 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
1058static int aes_cbc_sha1_hmac_authenc_decrypt(struct aead_request *req) 1078static 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
1092static int aes_cbc_sha1_hmac_authenc_givencrypt( 1112static 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}