summaryrefslogtreecommitdiffstats
path: root/drivers/crypto/sahara.c
diff options
context:
space:
mode:
authorSteffen Trumtrar <s.trumtrar@pengutronix.de>2014-12-01 07:26:34 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2014-12-03 09:30:19 -0500
commit5a2bb93f599247e049f5ae06a573f1152987c572 (patch)
treeb03e388da1155d432fcf6398ed0994464e25a93b /drivers/crypto/sahara.c
parentc0c3c89ae34764890c2294dc4ddf055940b64c36 (diff)
crypto: sahara - add support for SHA1/256
Add support for the MDHA unit in the SAHARA core. The MDHA can generate hash digests for MD5 and SHA1 in version 3 and additionally SHA224 and SHA256 in version 4. Add the SHA1 and SHA256 algorithms to the driver. The implementation was tested with the in-kernel testmgr and a userspace testprogram using AF_ALG with+without upto 128 pthreads on each AES and SHA256 on i.MX53. Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/sahara.c')
-rw-r--r--drivers/crypto/sahara.c626
1 files changed, 621 insertions, 5 deletions
diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c
index 04d3b4309e4c..579f539e5975 100644
--- a/drivers/crypto/sahara.c
+++ b/drivers/crypto/sahara.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Support for SAHARA cryptographic accelerator. 4 * Support for SAHARA cryptographic accelerator.
5 * 5 *
6 * Copyright (c) 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de>
6 * Copyright (c) 2013 Vista Silicon S.L. 7 * Copyright (c) 2013 Vista Silicon S.L.
7 * Author: Javier Martin <javier.martin@vista-silicon.com> 8 * Author: Javier Martin <javier.martin@vista-silicon.com>
8 * 9 *
@@ -15,6 +16,10 @@
15 16
16#include <crypto/algapi.h> 17#include <crypto/algapi.h>
17#include <crypto/aes.h> 18#include <crypto/aes.h>
19#include <crypto/hash.h>
20#include <crypto/internal/hash.h>
21#include <crypto/scatterwalk.h>
22#include <crypto/sha.h>
18 23
19#include <linux/clk.h> 24#include <linux/clk.h>
20#include <linux/crypto.h> 25#include <linux/crypto.h>
@@ -29,6 +34,9 @@
29#include <linux/of_device.h> 34#include <linux/of_device.h>
30#include <linux/platform_device.h> 35#include <linux/platform_device.h>
31 36
37#define SHA_BUFFER_LEN PAGE_SIZE
38#define SAHARA_MAX_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE
39
32#define SAHARA_NAME "sahara" 40#define SAHARA_NAME "sahara"
33#define SAHARA_VERSION_3 3 41#define SAHARA_VERSION_3 3
34#define SAHARA_VERSION_4 4 42#define SAHARA_VERSION_4 4
@@ -53,6 +61,23 @@
53#define SAHARA_HDR_CHA_MDHA (2 << 28) 61#define SAHARA_HDR_CHA_MDHA (2 << 28)
54#define SAHARA_HDR_PARITY_BIT (1 << 31) 62#define SAHARA_HDR_PARITY_BIT (1 << 31)
55 63
64#define SAHARA_HDR_MDHA_SET_MODE_MD_KEY 0x20880000
65#define SAHARA_HDR_MDHA_SET_MODE_HASH 0x208D0000
66#define SAHARA_HDR_MDHA_HASH 0xA0850000
67#define SAHARA_HDR_MDHA_STORE_DIGEST 0x20820000
68#define SAHARA_HDR_MDHA_ALG_SHA1 0
69#define SAHARA_HDR_MDHA_ALG_MD5 1
70#define SAHARA_HDR_MDHA_ALG_SHA256 2
71#define SAHARA_HDR_MDHA_ALG_SHA224 3
72#define SAHARA_HDR_MDHA_PDATA (1 << 2)
73#define SAHARA_HDR_MDHA_HMAC (1 << 3)
74#define SAHARA_HDR_MDHA_INIT (1 << 5)
75#define SAHARA_HDR_MDHA_IPAD (1 << 6)
76#define SAHARA_HDR_MDHA_OPAD (1 << 7)
77#define SAHARA_HDR_MDHA_SWAP (1 << 8)
78#define SAHARA_HDR_MDHA_MAC_FULL (1 << 9)
79#define SAHARA_HDR_MDHA_SSL (1 << 10)
80
56/* SAHARA can only process one request at a time */ 81/* SAHARA can only process one request at a time */
57#define SAHARA_QUEUE_LENGTH 1 82#define SAHARA_QUEUE_LENGTH 1
58 83
@@ -121,15 +146,58 @@ struct sahara_hw_link {
121 146
122struct sahara_ctx { 147struct sahara_ctx {
123 unsigned long flags; 148 unsigned long flags;
149
150 /* AES-specific context */
124 int keylen; 151 int keylen;
125 u8 key[AES_KEYSIZE_128]; 152 u8 key[AES_KEYSIZE_128];
126 struct crypto_ablkcipher *fallback; 153 struct crypto_ablkcipher *fallback;
154
155 /* SHA-specific context */
156 struct crypto_shash *shash_fallback;
127}; 157};
128 158
129struct sahara_aes_reqctx { 159struct sahara_aes_reqctx {
130 unsigned long mode; 160 unsigned long mode;
131}; 161};
132 162
163/*
164 * struct sahara_sha_reqctx - private data per request
165 * @buf: holds data for requests smaller than block_size
166 * @rembuf: used to prepare one block_size-aligned request
167 * @context: hw-specific context for request. Digest is extracted from this
168 * @mode: specifies what type of hw-descriptor needs to be built
169 * @digest_size: length of digest for this request
170 * @context_size: length of hw-context for this request.
171 * Always digest_size + 4
172 * @buf_cnt: number of bytes saved in buf
173 * @sg_in_idx: number of hw links
174 * @in_sg: scatterlist for input data
175 * @in_sg_chain: scatterlists for chained input data
176 * @in_sg_chained: specifies if chained scatterlists are used or not
177 * @total: total number of bytes for transfer
178 * @last: is this the last block
179 * @first: is this the first block
180 * @active: inside a transfer
181 */
182struct sahara_sha_reqctx {
183 u8 buf[SAHARA_MAX_SHA_BLOCK_SIZE];
184 u8 rembuf[SAHARA_MAX_SHA_BLOCK_SIZE];
185 u8 context[SHA256_DIGEST_SIZE + 4];
186 struct mutex mutex;
187 unsigned int mode;
188 unsigned int digest_size;
189 unsigned int context_size;
190 unsigned int buf_cnt;
191 unsigned int sg_in_idx;
192 struct scatterlist *in_sg;
193 struct scatterlist in_sg_chain[2];
194 bool in_sg_chained;
195 size_t total;
196 unsigned int last;
197 unsigned int first;
198 unsigned int active;
199};
200
133struct sahara_dev { 201struct sahara_dev {
134 struct device *device; 202 struct device *device;
135 unsigned int version; 203 unsigned int version;
@@ -154,6 +222,9 @@ struct sahara_dev {
154 u8 *iv_base; 222 u8 *iv_base;
155 dma_addr_t iv_phys_base; 223 dma_addr_t iv_phys_base;
156 224
225 u8 *context_base;
226 dma_addr_t context_phys_base;
227
157 struct sahara_hw_link *hw_link[SAHARA_MAX_HW_LINK]; 228 struct sahara_hw_link *hw_link[SAHARA_MAX_HW_LINK];
158 dma_addr_t hw_phys_link[SAHARA_MAX_HW_LINK]; 229 dma_addr_t hw_phys_link[SAHARA_MAX_HW_LINK];
159 230
@@ -707,6 +778,316 @@ static void sahara_aes_cra_exit(struct crypto_tfm *tfm)
707 ctx->fallback = NULL; 778 ctx->fallback = NULL;
708} 779}
709 780
781static u32 sahara_sha_init_hdr(struct sahara_dev *dev,
782 struct sahara_sha_reqctx *rctx)
783{
784 u32 hdr = 0;
785
786 hdr = rctx->mode;
787
788 if (rctx->first) {
789 hdr |= SAHARA_HDR_MDHA_SET_MODE_HASH;
790 hdr |= SAHARA_HDR_MDHA_INIT;
791 } else {
792 hdr |= SAHARA_HDR_MDHA_SET_MODE_MD_KEY;
793 }
794
795 if (rctx->last)
796 hdr |= SAHARA_HDR_MDHA_PDATA;
797
798 if (hweight_long(hdr) % 2 == 0)
799 hdr |= SAHARA_HDR_PARITY_BIT;
800
801 return hdr;
802}
803
804static int sahara_sha_hw_links_create(struct sahara_dev *dev,
805 struct sahara_sha_reqctx *rctx,
806 int start)
807{
808 struct scatterlist *sg;
809 unsigned int i;
810 int ret;
811
812 dev->in_sg = rctx->in_sg;
813
814 dev->nb_in_sg = sahara_sg_length(dev->in_sg, rctx->total);
815 if ((dev->nb_in_sg) > SAHARA_MAX_HW_LINK) {
816 dev_err(dev->device, "not enough hw links (%d)\n",
817 dev->nb_in_sg + dev->nb_out_sg);
818 return -EINVAL;
819 }
820
821 if (rctx->in_sg_chained) {
822 i = start;
823 sg = dev->in_sg;
824 while (sg) {
825 ret = dma_map_sg(dev->device, sg, 1,
826 DMA_TO_DEVICE);
827 if (!ret)
828 return -EFAULT;
829
830 dev->hw_link[i]->len = sg->length;
831 dev->hw_link[i]->p = sg->dma_address;
832 dev->hw_link[i]->next = dev->hw_phys_link[i + 1];
833 sg = sg_next(sg);
834 i += 1;
835 }
836 dev->hw_link[i-1]->next = 0;
837 } else {
838 sg = dev->in_sg;
839 ret = dma_map_sg(dev->device, dev->in_sg, dev->nb_in_sg,
840 DMA_TO_DEVICE);
841 if (!ret)
842 return -EFAULT;
843
844 for (i = start; i < dev->nb_in_sg + start; i++) {
845 dev->hw_link[i]->len = sg->length;
846 dev->hw_link[i]->p = sg->dma_address;
847 if (i == (dev->nb_in_sg + start - 1)) {
848 dev->hw_link[i]->next = 0;
849 } else {
850 dev->hw_link[i]->next = dev->hw_phys_link[i + 1];
851 sg = sg_next(sg);
852 }
853 }
854 }
855
856 return i;
857}
858
859static int sahara_sha_hw_data_descriptor_create(struct sahara_dev *dev,
860 struct sahara_sha_reqctx *rctx,
861 struct ahash_request *req,
862 int index)
863{
864 unsigned result_len;
865 int i = index;
866
867 if (rctx->first)
868 /* Create initial descriptor: #8*/
869 dev->hw_desc[index]->hdr = sahara_sha_init_hdr(dev, rctx);
870 else
871 /* Create hash descriptor: #10. Must follow #6. */
872 dev->hw_desc[index]->hdr = SAHARA_HDR_MDHA_HASH;
873
874 dev->hw_desc[index]->len1 = rctx->total;
875 if (dev->hw_desc[index]->len1 == 0) {
876 /* if len1 is 0, p1 must be 0, too */
877 dev->hw_desc[index]->p1 = 0;
878 rctx->sg_in_idx = 0;
879 } else {
880 /* Create input links */
881 dev->hw_desc[index]->p1 = dev->hw_phys_link[index];
882 i = sahara_sha_hw_links_create(dev, rctx, index);
883
884 rctx->sg_in_idx = index;
885 if (i < 0)
886 return i;
887 }
888
889 dev->hw_desc[index]->p2 = dev->hw_phys_link[i];
890
891 /* Save the context for the next operation */
892 result_len = rctx->context_size;
893 dev->hw_link[i]->p = dev->context_phys_base;
894
895 dev->hw_link[i]->len = result_len;
896 dev->hw_desc[index]->len2 = result_len;
897
898 dev->hw_link[i]->next = 0;
899
900 return 0;
901}
902
903/*
904 * Load descriptor aka #6
905 *
906 * To load a previously saved context back to the MDHA unit
907 *
908 * p1: Saved Context
909 * p2: NULL
910 *
911 */
912static int sahara_sha_hw_context_descriptor_create(struct sahara_dev *dev,
913 struct sahara_sha_reqctx *rctx,
914 struct ahash_request *req,
915 int index)
916{
917 dev->hw_desc[index]->hdr = sahara_sha_init_hdr(dev, rctx);
918
919 dev->hw_desc[index]->len1 = rctx->context_size;
920 dev->hw_desc[index]->p1 = dev->hw_phys_link[index];
921 dev->hw_desc[index]->len2 = 0;
922 dev->hw_desc[index]->p2 = 0;
923
924 dev->hw_link[index]->len = rctx->context_size;
925 dev->hw_link[index]->p = dev->context_phys_base;
926 dev->hw_link[index]->next = 0;
927
928 return 0;
929}
930
931static int sahara_walk_and_recalc(struct scatterlist *sg, unsigned int nbytes)
932{
933 if (!sg || !sg->length)
934 return nbytes;
935
936 while (nbytes && sg) {
937 if (nbytes <= sg->length) {
938 sg->length = nbytes;
939 sg_mark_end(sg);
940 break;
941 }
942 nbytes -= sg->length;
943 sg = scatterwalk_sg_next(sg);
944 }
945
946 return nbytes;
947}
948
949static int sahara_sha_prepare_request(struct ahash_request *req)
950{
951 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
952 struct sahara_sha_reqctx *rctx = ahash_request_ctx(req);
953 unsigned int hash_later;
954 unsigned int block_size;
955 unsigned int len;
956
957 block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
958
959 /* append bytes from previous operation */
960 len = rctx->buf_cnt + req->nbytes;
961
962 /* only the last transfer can be padded in hardware */
963 if (!rctx->last && (len < block_size)) {
964 /* to few data, save for next operation */
965 scatterwalk_map_and_copy(rctx->buf + rctx->buf_cnt, req->src,
966 0, req->nbytes, 0);
967 rctx->buf_cnt += req->nbytes;
968
969 return 0;
970 }
971
972 /* add data from previous operation first */
973 if (rctx->buf_cnt)
974 memcpy(rctx->rembuf, rctx->buf, rctx->buf_cnt);
975
976 /* data must always be a multiple of block_size */
977 hash_later = rctx->last ? 0 : len & (block_size - 1);
978 if (hash_later) {
979 unsigned int offset = req->nbytes - hash_later;
980 /* Save remaining bytes for later use */
981 scatterwalk_map_and_copy(rctx->buf, req->src, offset,
982 hash_later, 0);
983 }
984
985 /* nbytes should now be multiple of blocksize */
986 req->nbytes = req->nbytes - hash_later;
987
988 sahara_walk_and_recalc(req->src, req->nbytes);
989
990 /* have data from previous operation and current */
991 if (rctx->buf_cnt && req->nbytes) {
992 sg_init_table(rctx->in_sg_chain, 2);
993 sg_set_buf(rctx->in_sg_chain, rctx->rembuf, rctx->buf_cnt);
994
995 scatterwalk_sg_chain(rctx->in_sg_chain, 2, req->src);
996
997 rctx->total = req->nbytes + rctx->buf_cnt;
998 rctx->in_sg = rctx->in_sg_chain;
999
1000 rctx->in_sg_chained = true;
1001 req->src = rctx->in_sg_chain;
1002 /* only data from previous operation */
1003 } else if (rctx->buf_cnt) {
1004 if (req->src)
1005 rctx->in_sg = req->src;
1006 else
1007 rctx->in_sg = rctx->in_sg_chain;
1008 /* buf was copied into rembuf above */
1009 sg_init_one(rctx->in_sg, rctx->rembuf, rctx->buf_cnt);
1010 rctx->total = rctx->buf_cnt;
1011 rctx->in_sg_chained = false;
1012 /* no data from previous operation */
1013 } else {
1014 rctx->in_sg = req->src;
1015 rctx->total = req->nbytes;
1016 req->src = rctx->in_sg;
1017 rctx->in_sg_chained = false;
1018 }
1019
1020 /* on next call, we only have the remaining data in the buffer */
1021 rctx->buf_cnt = hash_later;
1022
1023 return -EINPROGRESS;
1024}
1025
1026static void sahara_sha_unmap_sg(struct sahara_dev *dev,
1027 struct sahara_sha_reqctx *rctx)
1028{
1029 struct scatterlist *sg;
1030
1031 if (rctx->in_sg_chained) {
1032 sg = dev->in_sg;
1033 while (sg) {
1034 dma_unmap_sg(dev->device, sg, 1, DMA_TO_DEVICE);
1035 sg = sg_next(sg);
1036 }
1037 } else {
1038 dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg,
1039 DMA_TO_DEVICE);
1040 }
1041}
1042
1043static int sahara_sha_process(struct ahash_request *req)
1044{
1045 struct sahara_dev *dev = dev_ptr;
1046 struct sahara_sha_reqctx *rctx = ahash_request_ctx(req);
1047 int ret = -EINPROGRESS;
1048
1049 ret = sahara_sha_prepare_request(req);
1050 if (!ret)
1051 return ret;
1052
1053 if (rctx->first) {
1054 sahara_sha_hw_data_descriptor_create(dev, rctx, req, 0);
1055 dev->hw_desc[0]->next = 0;
1056 rctx->first = 0;
1057 } else {
1058 memcpy(dev->context_base, rctx->context, rctx->context_size);
1059
1060 sahara_sha_hw_context_descriptor_create(dev, rctx, req, 0);
1061 dev->hw_desc[0]->next = dev->hw_phys_desc[1];
1062 sahara_sha_hw_data_descriptor_create(dev, rctx, req, 1);
1063 dev->hw_desc[1]->next = 0;
1064 }
1065
1066 sahara_dump_descriptors(dev);
1067 sahara_dump_links(dev);
1068
1069 reinit_completion(&dev->dma_completion);
1070
1071 sahara_write(dev, dev->hw_phys_desc[0], SAHARA_REG_DAR);
1072
1073 ret = wait_for_completion_timeout(&dev->dma_completion,
1074 msecs_to_jiffies(SAHARA_TIMEOUT_MS));
1075 if (!ret) {
1076 dev_err(dev->device, "SHA timeout\n");
1077 return -ETIMEDOUT;
1078 }
1079
1080 if (rctx->sg_in_idx)
1081 sahara_sha_unmap_sg(dev, rctx);
1082
1083 memcpy(rctx->context, dev->context_base, rctx->context_size);
1084
1085 if (req->result)
1086 memcpy(req->result, rctx->context, rctx->digest_size);
1087
1088 return 0;
1089}
1090
710static int sahara_queue_manage(void *data) 1091static int sahara_queue_manage(void *data)
711{ 1092{
712 struct sahara_dev *dev = (struct sahara_dev *)data; 1093 struct sahara_dev *dev = (struct sahara_dev *)data;
@@ -721,10 +1102,18 @@ static int sahara_queue_manage(void *data)
721 mutex_unlock(&dev->queue_mutex); 1102 mutex_unlock(&dev->queue_mutex);
722 1103
723 if (async_req) { 1104 if (async_req) {
724 struct ablkcipher_request *req = 1105 if (crypto_tfm_alg_type(async_req->tfm) ==
725 ablkcipher_request_cast(async_req); 1106 CRYPTO_ALG_TYPE_AHASH) {
1107 struct ahash_request *req =
1108 ahash_request_cast(async_req);
1109
1110 ret = sahara_sha_process(req);
1111 } else {
1112 struct ablkcipher_request *req =
1113 ablkcipher_request_cast(async_req);
726 1114
727 ret = sahara_aes_process(req); 1115 ret = sahara_aes_process(req);
1116 }
728 1117
729 async_req->complete(async_req, ret); 1118 async_req->complete(async_req, ret);
730 1119
@@ -737,6 +1126,136 @@ static int sahara_queue_manage(void *data)
737 return 0; 1126 return 0;
738} 1127}
739 1128
1129static int sahara_sha_enqueue(struct ahash_request *req, int last)
1130{
1131 struct sahara_sha_reqctx *rctx = ahash_request_ctx(req);
1132 struct sahara_dev *dev = dev_ptr;
1133 int ret;
1134
1135 if (!req->nbytes && !last)
1136 return 0;
1137
1138 mutex_lock(&rctx->mutex);
1139 rctx->last = last;
1140
1141 if (!rctx->active) {
1142 rctx->active = 1;
1143 rctx->first = 1;
1144 }
1145
1146 mutex_lock(&dev->queue_mutex);
1147 ret = crypto_enqueue_request(&dev->queue, &req->base);
1148 mutex_unlock(&dev->queue_mutex);
1149
1150 wake_up_process(dev->kthread);
1151 mutex_unlock(&rctx->mutex);
1152
1153 return ret;
1154}
1155
1156static int sahara_sha_init(struct ahash_request *req)
1157{
1158 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
1159 struct sahara_sha_reqctx *rctx = ahash_request_ctx(req);
1160
1161 memset(rctx, 0, sizeof(*rctx));
1162
1163 switch (crypto_ahash_digestsize(tfm)) {
1164 case SHA1_DIGEST_SIZE:
1165 rctx->mode |= SAHARA_HDR_MDHA_ALG_SHA1;
1166 rctx->digest_size = SHA1_DIGEST_SIZE;
1167 break;
1168 case SHA256_DIGEST_SIZE:
1169 rctx->mode |= SAHARA_HDR_MDHA_ALG_SHA256;
1170 rctx->digest_size = SHA256_DIGEST_SIZE;
1171 break;
1172 default:
1173 return -EINVAL;
1174 }
1175
1176 rctx->context_size = rctx->digest_size + 4;
1177 rctx->active = 0;
1178
1179 mutex_init(&rctx->mutex);
1180
1181 return 0;
1182}
1183
1184static int sahara_sha_update(struct ahash_request *req)
1185{
1186 return sahara_sha_enqueue(req, 0);
1187}
1188
1189static int sahara_sha_final(struct ahash_request *req)
1190{
1191 req->nbytes = 0;
1192 return sahara_sha_enqueue(req, 1);
1193}
1194
1195static int sahara_sha_finup(struct ahash_request *req)
1196{
1197 return sahara_sha_enqueue(req, 1);
1198}
1199
1200static int sahara_sha_digest(struct ahash_request *req)
1201{
1202 sahara_sha_init(req);
1203
1204 return sahara_sha_finup(req);
1205}
1206
1207static int sahara_sha_export(struct ahash_request *req, void *out)
1208{
1209 struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
1210 struct sahara_ctx *ctx = crypto_ahash_ctx(ahash);
1211 struct sahara_sha_reqctx *rctx = ahash_request_ctx(req);
1212
1213 memcpy(out, ctx, sizeof(struct sahara_ctx));
1214 memcpy(out + sizeof(struct sahara_sha_reqctx), rctx,
1215 sizeof(struct sahara_sha_reqctx));
1216
1217 return 0;
1218}
1219
1220static int sahara_sha_import(struct ahash_request *req, const void *in)
1221{
1222 struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
1223 struct sahara_ctx *ctx = crypto_ahash_ctx(ahash);
1224 struct sahara_sha_reqctx *rctx = ahash_request_ctx(req);
1225
1226 memcpy(ctx, in, sizeof(struct sahara_ctx));
1227 memcpy(rctx, in + sizeof(struct sahara_sha_reqctx),
1228 sizeof(struct sahara_sha_reqctx));
1229
1230 return 0;
1231}
1232
1233static int sahara_sha_cra_init(struct crypto_tfm *tfm)
1234{
1235 const char *name = crypto_tfm_alg_name(tfm);
1236 struct sahara_ctx *ctx = crypto_tfm_ctx(tfm);
1237
1238 ctx->shash_fallback = crypto_alloc_shash(name, 0,
1239 CRYPTO_ALG_NEED_FALLBACK);
1240 if (IS_ERR(ctx->shash_fallback)) {
1241 pr_err("Error allocating fallback algo %s\n", name);
1242 return PTR_ERR(ctx->shash_fallback);
1243 }
1244 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
1245 sizeof(struct sahara_sha_reqctx) +
1246 SHA_BUFFER_LEN + SHA256_BLOCK_SIZE);
1247
1248 return 0;
1249}
1250
1251static void sahara_sha_cra_exit(struct crypto_tfm *tfm)
1252{
1253 struct sahara_ctx *ctx = crypto_tfm_ctx(tfm);
1254
1255 crypto_free_shash(ctx->shash_fallback);
1256 ctx->shash_fallback = NULL;
1257}
1258
740static struct crypto_alg aes_algs[] = { 1259static struct crypto_alg aes_algs[] = {
741{ 1260{
742 .cra_name = "ecb(aes)", 1261 .cra_name = "ecb(aes)",
@@ -782,6 +1301,60 @@ static struct crypto_alg aes_algs[] = {
782} 1301}
783}; 1302};
784 1303
1304static struct ahash_alg sha_v3_algs[] = {
1305{
1306 .init = sahara_sha_init,
1307 .update = sahara_sha_update,
1308 .final = sahara_sha_final,
1309 .finup = sahara_sha_finup,
1310 .digest = sahara_sha_digest,
1311 .export = sahara_sha_export,
1312 .import = sahara_sha_import,
1313 .halg.digestsize = SHA1_DIGEST_SIZE,
1314 .halg.base = {
1315 .cra_name = "sha1",
1316 .cra_driver_name = "sahara-sha1",
1317 .cra_priority = 300,
1318 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1319 CRYPTO_ALG_ASYNC |
1320 CRYPTO_ALG_NEED_FALLBACK,
1321 .cra_blocksize = SHA1_BLOCK_SIZE,
1322 .cra_ctxsize = sizeof(struct sahara_ctx),
1323 .cra_alignmask = 0,
1324 .cra_module = THIS_MODULE,
1325 .cra_init = sahara_sha_cra_init,
1326 .cra_exit = sahara_sha_cra_exit,
1327 }
1328},
1329};
1330
1331static struct ahash_alg sha_v4_algs[] = {
1332{
1333 .init = sahara_sha_init,
1334 .update = sahara_sha_update,
1335 .final = sahara_sha_final,
1336 .finup = sahara_sha_finup,
1337 .digest = sahara_sha_digest,
1338 .export = sahara_sha_export,
1339 .import = sahara_sha_import,
1340 .halg.digestsize = SHA256_DIGEST_SIZE,
1341 .halg.base = {
1342 .cra_name = "sha256",
1343 .cra_driver_name = "sahara-sha256",
1344 .cra_priority = 300,
1345 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1346 CRYPTO_ALG_ASYNC |
1347 CRYPTO_ALG_NEED_FALLBACK,
1348 .cra_blocksize = SHA256_BLOCK_SIZE,
1349 .cra_ctxsize = sizeof(struct sahara_ctx),
1350 .cra_alignmask = 0,
1351 .cra_module = THIS_MODULE,
1352 .cra_init = sahara_sha_cra_init,
1353 .cra_exit = sahara_sha_cra_exit,
1354 }
1355},
1356};
1357
785static irqreturn_t sahara_irq_handler(int irq, void *data) 1358static irqreturn_t sahara_irq_handler(int irq, void *data)
786{ 1359{
787 struct sahara_dev *dev = (struct sahara_dev *)data; 1360 struct sahara_dev *dev = (struct sahara_dev *)data;
@@ -810,7 +1383,8 @@ static irqreturn_t sahara_irq_handler(int irq, void *data)
810 1383
811static int sahara_register_algs(struct sahara_dev *dev) 1384static int sahara_register_algs(struct sahara_dev *dev)
812{ 1385{
813 int err, i, j; 1386 int err;
1387 unsigned int i, j, k, l;
814 1388
815 for (i = 0; i < ARRAY_SIZE(aes_algs); i++) { 1389 for (i = 0; i < ARRAY_SIZE(aes_algs); i++) {
816 INIT_LIST_HEAD(&aes_algs[i].cra_list); 1390 INIT_LIST_HEAD(&aes_algs[i].cra_list);
@@ -819,8 +1393,29 @@ static int sahara_register_algs(struct sahara_dev *dev)
819 goto err_aes_algs; 1393 goto err_aes_algs;
820 } 1394 }
821 1395
1396 for (k = 0; k < ARRAY_SIZE(sha_v3_algs); k++) {
1397 err = crypto_register_ahash(&sha_v3_algs[k]);
1398 if (err)
1399 goto err_sha_v3_algs;
1400 }
1401
1402 if (dev->version > SAHARA_VERSION_3)
1403 for (l = 0; l < ARRAY_SIZE(sha_v4_algs); l++) {
1404 err = crypto_register_ahash(&sha_v4_algs[l]);
1405 if (err)
1406 goto err_sha_v4_algs;
1407 }
1408
822 return 0; 1409 return 0;
823 1410
1411err_sha_v4_algs:
1412 for (j = 0; j < l; j++)
1413 crypto_unregister_ahash(&sha_v4_algs[j]);
1414
1415err_sha_v3_algs:
1416 for (j = 0; j < k; j++)
1417 crypto_unregister_ahash(&sha_v4_algs[j]);
1418
824err_aes_algs: 1419err_aes_algs:
825 for (j = 0; j < i; j++) 1420 for (j = 0; j < i; j++)
826 crypto_unregister_alg(&aes_algs[j]); 1421 crypto_unregister_alg(&aes_algs[j]);
@@ -830,10 +1425,17 @@ err_aes_algs:
830 1425
831static void sahara_unregister_algs(struct sahara_dev *dev) 1426static void sahara_unregister_algs(struct sahara_dev *dev)
832{ 1427{
833 int i; 1428 unsigned int i;
834 1429
835 for (i = 0; i < ARRAY_SIZE(aes_algs); i++) 1430 for (i = 0; i < ARRAY_SIZE(aes_algs); i++)
836 crypto_unregister_alg(&aes_algs[i]); 1431 crypto_unregister_alg(&aes_algs[i]);
1432
1433 for (i = 0; i < ARRAY_SIZE(sha_v4_algs); i++)
1434 crypto_unregister_ahash(&sha_v3_algs[i]);
1435
1436 if (dev->version > SAHARA_VERSION_3)
1437 for (i = 0; i < ARRAY_SIZE(sha_v4_algs); i++)
1438 crypto_unregister_ahash(&sha_v4_algs[i]);
837} 1439}
838 1440
839static struct platform_device_id sahara_platform_ids[] = { 1441static struct platform_device_id sahara_platform_ids[] = {
@@ -923,6 +1525,16 @@ static int sahara_probe(struct platform_device *pdev)
923 dev->iv_base = dev->key_base + AES_KEYSIZE_128; 1525 dev->iv_base = dev->key_base + AES_KEYSIZE_128;
924 dev->iv_phys_base = dev->key_phys_base + AES_KEYSIZE_128; 1526 dev->iv_phys_base = dev->key_phys_base + AES_KEYSIZE_128;
925 1527
1528 /* Allocate space for context: largest digest + message length field */
1529 dev->context_base = dma_alloc_coherent(&pdev->dev,
1530 SHA256_DIGEST_SIZE + 4,
1531 &dev->context_phys_base, GFP_KERNEL);
1532 if (!dev->context_base) {
1533 dev_err(&pdev->dev, "Could not allocate memory for MDHA context\n");
1534 err = -ENOMEM;
1535 goto err_key;
1536 }
1537
926 /* Allocate space for HW links */ 1538 /* Allocate space for HW links */
927 dev->hw_link[0] = dma_alloc_coherent(&pdev->dev, 1539 dev->hw_link[0] = dma_alloc_coherent(&pdev->dev,
928 SAHARA_MAX_HW_LINK * sizeof(struct sahara_hw_link), 1540 SAHARA_MAX_HW_LINK * sizeof(struct sahara_hw_link),
@@ -1002,6 +1614,9 @@ err_link:
1002 dma_free_coherent(&pdev->dev, 1614 dma_free_coherent(&pdev->dev,
1003 2 * AES_KEYSIZE_128, 1615 2 * AES_KEYSIZE_128,
1004 dev->key_base, dev->key_phys_base); 1616 dev->key_base, dev->key_phys_base);
1617 dma_free_coherent(&pdev->dev,
1618 SHA256_DIGEST_SIZE,
1619 dev->context_base, dev->context_phys_base);
1005err_key: 1620err_key:
1006 dma_free_coherent(&pdev->dev, 1621 dma_free_coherent(&pdev->dev,
1007 SAHARA_MAX_HW_DESC * sizeof(struct sahara_hw_desc), 1622 SAHARA_MAX_HW_DESC * sizeof(struct sahara_hw_desc),
@@ -1051,4 +1666,5 @@ module_platform_driver(sahara_driver);
1051 1666
1052MODULE_LICENSE("GPL"); 1667MODULE_LICENSE("GPL");
1053MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>"); 1668MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
1669MODULE_AUTHOR("Steffen Trumtrar <s.trumtrar@pengutronix.de>");
1054MODULE_DESCRIPTION("SAHARA2 HW crypto accelerator"); 1670MODULE_DESCRIPTION("SAHARA2 HW crypto accelerator");