aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/omap-sham.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/crypto/omap-sham.c')
-rw-r--r--drivers/crypto/omap-sham.c183
1 files changed, 173 insertions, 10 deletions
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index fab0af488b83..edff981edfb1 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -83,6 +83,8 @@
83#define SHA_REG_MODE_ALGO_MASK (3 << 1) 83#define SHA_REG_MODE_ALGO_MASK (3 << 1)
84#define SHA_REG_MODE_ALGO_MD5_128 (0 << 1) 84#define SHA_REG_MODE_ALGO_MD5_128 (0 << 1)
85#define SHA_REG_MODE_ALGO_SHA1_160 (1 << 1) 85#define SHA_REG_MODE_ALGO_SHA1_160 (1 << 1)
86#define SHA_REG_MODE_ALGO_SHA2_224 (2 << 1)
87#define SHA_REG_MODE_ALGO_SHA2_256 (3 << 1)
86 88
87#define SHA_REG_LENGTH 0x48 89#define SHA_REG_LENGTH 0x48
88 90
@@ -121,6 +123,10 @@
121 << (FLAGS_MODE_SHIFT - 1)) 123 << (FLAGS_MODE_SHIFT - 1))
122#define FLAGS_MODE_SHA1 (SHA_REG_MODE_ALGO_SHA1_160 \ 124#define FLAGS_MODE_SHA1 (SHA_REG_MODE_ALGO_SHA1_160 \
123 << (FLAGS_MODE_SHIFT - 1)) 125 << (FLAGS_MODE_SHIFT - 1))
126#define FLAGS_MODE_SHA224 (SHA_REG_MODE_ALGO_SHA2_224 \
127 << (FLAGS_MODE_SHIFT - 1))
128#define FLAGS_MODE_SHA256 (SHA_REG_MODE_ALGO_SHA2_256 \
129 << (FLAGS_MODE_SHIFT - 1))
124#define FLAGS_HMAC 20 130#define FLAGS_HMAC 20
125#define FLAGS_ERROR 21 131#define FLAGS_ERROR 21
126 132
@@ -173,7 +179,15 @@ struct omap_sham_ctx {
173 179
174#define OMAP_SHAM_QUEUE_LENGTH 1 180#define OMAP_SHAM_QUEUE_LENGTH 1
175 181
182struct omap_sham_algs_info {
183 struct ahash_alg *algs_list;
184 unsigned int size;
185 unsigned int registered;
186};
187
176struct omap_sham_pdata { 188struct omap_sham_pdata {
189 struct omap_sham_algs_info *algs_info;
190 unsigned int algs_info_size;
177 unsigned long flags; 191 unsigned long flags;
178 int digest_size; 192 int digest_size;
179 193
@@ -322,6 +336,12 @@ static void omap_sham_copy_ready_hash(struct ahash_request *req)
322 big_endian = 1; 336 big_endian = 1;
323 d = SHA1_DIGEST_SIZE / sizeof(u32); 337 d = SHA1_DIGEST_SIZE / sizeof(u32);
324 break; 338 break;
339 case FLAGS_MODE_SHA224:
340 d = SHA224_DIGEST_SIZE / sizeof(u32);
341 break;
342 case FLAGS_MODE_SHA256:
343 d = SHA256_DIGEST_SIZE / sizeof(u32);
344 break;
325 default: 345 default:
326 d = 0; 346 d = 0;
327 } 347 }
@@ -780,6 +800,12 @@ static int omap_sham_init(struct ahash_request *req)
780 case SHA1_DIGEST_SIZE: 800 case SHA1_DIGEST_SIZE:
781 ctx->flags |= FLAGS_MODE_SHA1; 801 ctx->flags |= FLAGS_MODE_SHA1;
782 break; 802 break;
803 case SHA224_DIGEST_SIZE:
804 ctx->flags |= FLAGS_MODE_SHA224;
805 break;
806 case SHA256_DIGEST_SIZE:
807 ctx->flags |= FLAGS_MODE_SHA256;
808 break;
783 } 809 }
784 810
785 ctx->bufcnt = 0; 811 ctx->bufcnt = 0;
@@ -1173,6 +1199,16 @@ static int omap_sham_cra_sha1_init(struct crypto_tfm *tfm)
1173 return omap_sham_cra_init_alg(tfm, "sha1"); 1199 return omap_sham_cra_init_alg(tfm, "sha1");
1174} 1200}
1175 1201
1202static int omap_sham_cra_sha224_init(struct crypto_tfm *tfm)
1203{
1204 return omap_sham_cra_init_alg(tfm, "sha224");
1205}
1206
1207static int omap_sham_cra_sha256_init(struct crypto_tfm *tfm)
1208{
1209 return omap_sham_cra_init_alg(tfm, "sha256");
1210}
1211
1176static int omap_sham_cra_md5_init(struct crypto_tfm *tfm) 1212static int omap_sham_cra_md5_init(struct crypto_tfm *tfm)
1177{ 1213{
1178 return omap_sham_cra_init_alg(tfm, "md5"); 1214 return omap_sham_cra_init_alg(tfm, "md5");
@@ -1191,7 +1227,7 @@ static void omap_sham_cra_exit(struct crypto_tfm *tfm)
1191 } 1227 }
1192} 1228}
1193 1229
1194static struct ahash_alg algs[] = { 1230static struct ahash_alg algs_sha1_md5[] = {
1195{ 1231{
1196 .init = omap_sham_init, 1232 .init = omap_sham_init,
1197 .update = omap_sham_update, 1233 .update = omap_sham_update,
@@ -1290,6 +1326,102 @@ static struct ahash_alg algs[] = {
1290} 1326}
1291}; 1327};
1292 1328
1329/* OMAP4 has some algs in addition to what OMAP2 has */
1330static struct ahash_alg algs_sha224_sha256[] = {
1331{
1332 .init = omap_sham_init,
1333 .update = omap_sham_update,
1334 .final = omap_sham_final,
1335 .finup = omap_sham_finup,
1336 .digest = omap_sham_digest,
1337 .halg.digestsize = SHA224_DIGEST_SIZE,
1338 .halg.base = {
1339 .cra_name = "sha224",
1340 .cra_driver_name = "omap-sha224",
1341 .cra_priority = 100,
1342 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1343 CRYPTO_ALG_ASYNC |
1344 CRYPTO_ALG_NEED_FALLBACK,
1345 .cra_blocksize = SHA224_BLOCK_SIZE,
1346 .cra_ctxsize = sizeof(struct omap_sham_ctx),
1347 .cra_alignmask = 0,
1348 .cra_module = THIS_MODULE,
1349 .cra_init = omap_sham_cra_init,
1350 .cra_exit = omap_sham_cra_exit,
1351 }
1352},
1353{
1354 .init = omap_sham_init,
1355 .update = omap_sham_update,
1356 .final = omap_sham_final,
1357 .finup = omap_sham_finup,
1358 .digest = omap_sham_digest,
1359 .halg.digestsize = SHA256_DIGEST_SIZE,
1360 .halg.base = {
1361 .cra_name = "sha256",
1362 .cra_driver_name = "omap-sha256",
1363 .cra_priority = 100,
1364 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1365 CRYPTO_ALG_ASYNC |
1366 CRYPTO_ALG_NEED_FALLBACK,
1367 .cra_blocksize = SHA256_BLOCK_SIZE,
1368 .cra_ctxsize = sizeof(struct omap_sham_ctx),
1369 .cra_alignmask = 0,
1370 .cra_module = THIS_MODULE,
1371 .cra_init = omap_sham_cra_init,
1372 .cra_exit = omap_sham_cra_exit,
1373 }
1374},
1375{
1376 .init = omap_sham_init,
1377 .update = omap_sham_update,
1378 .final = omap_sham_final,
1379 .finup = omap_sham_finup,
1380 .digest = omap_sham_digest,
1381 .setkey = omap_sham_setkey,
1382 .halg.digestsize = SHA224_DIGEST_SIZE,
1383 .halg.base = {
1384 .cra_name = "hmac(sha224)",
1385 .cra_driver_name = "omap-hmac-sha224",
1386 .cra_priority = 100,
1387 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1388 CRYPTO_ALG_ASYNC |
1389 CRYPTO_ALG_NEED_FALLBACK,
1390 .cra_blocksize = SHA224_BLOCK_SIZE,
1391 .cra_ctxsize = sizeof(struct omap_sham_ctx) +
1392 sizeof(struct omap_sham_hmac_ctx),
1393 .cra_alignmask = OMAP_ALIGN_MASK,
1394 .cra_module = THIS_MODULE,
1395 .cra_init = omap_sham_cra_sha224_init,
1396 .cra_exit = omap_sham_cra_exit,
1397 }
1398},
1399{
1400 .init = omap_sham_init,
1401 .update = omap_sham_update,
1402 .final = omap_sham_final,
1403 .finup = omap_sham_finup,
1404 .digest = omap_sham_digest,
1405 .setkey = omap_sham_setkey,
1406 .halg.digestsize = SHA256_DIGEST_SIZE,
1407 .halg.base = {
1408 .cra_name = "hmac(sha256)",
1409 .cra_driver_name = "omap-hmac-sha256",
1410 .cra_priority = 100,
1411 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1412 CRYPTO_ALG_ASYNC |
1413 CRYPTO_ALG_NEED_FALLBACK,
1414 .cra_blocksize = SHA256_BLOCK_SIZE,
1415 .cra_ctxsize = sizeof(struct omap_sham_ctx) +
1416 sizeof(struct omap_sham_hmac_ctx),
1417 .cra_alignmask = OMAP_ALIGN_MASK,
1418 .cra_module = THIS_MODULE,
1419 .cra_init = omap_sham_cra_sha256_init,
1420 .cra_exit = omap_sham_cra_exit,
1421 }
1422},
1423};
1424
1293static void omap_sham_done_task(unsigned long data) 1425static void omap_sham_done_task(unsigned long data)
1294{ 1426{
1295 struct omap_sham_dev *dd = (struct omap_sham_dev *)data; 1427 struct omap_sham_dev *dd = (struct omap_sham_dev *)data;
@@ -1364,7 +1496,16 @@ static irqreturn_t omap_sham_irq_omap4(int irq, void *dev_id)
1364 return omap_sham_irq_common(dd); 1496 return omap_sham_irq_common(dd);
1365} 1497}
1366 1498
1499static struct omap_sham_algs_info omap_sham_algs_info_omap2[] = {
1500 {
1501 .algs_list = algs_sha1_md5,
1502 .size = ARRAY_SIZE(algs_sha1_md5),
1503 },
1504};
1505
1367static const struct omap_sham_pdata omap_sham_pdata_omap2 = { 1506static const struct omap_sham_pdata omap_sham_pdata_omap2 = {
1507 .algs_info = omap_sham_algs_info_omap2,
1508 .algs_info_size = ARRAY_SIZE(omap_sham_algs_info_omap2),
1368 .flags = BIT(FLAGS_BE32_SHA1), 1509 .flags = BIT(FLAGS_BE32_SHA1),
1369 .digest_size = SHA1_DIGEST_SIZE, 1510 .digest_size = SHA1_DIGEST_SIZE,
1370 .copy_hash = omap_sham_copy_hash_omap2, 1511 .copy_hash = omap_sham_copy_hash_omap2,
@@ -1385,7 +1526,20 @@ static const struct omap_sham_pdata omap_sham_pdata_omap2 = {
1385}; 1526};
1386 1527
1387#ifdef CONFIG_OF 1528#ifdef CONFIG_OF
1529static struct omap_sham_algs_info omap_sham_algs_info_omap4[] = {
1530 {
1531 .algs_list = algs_sha1_md5,
1532 .size = ARRAY_SIZE(algs_sha1_md5),
1533 },
1534 {
1535 .algs_list = algs_sha224_sha256,
1536 .size = ARRAY_SIZE(algs_sha224_sha256),
1537 },
1538};
1539
1388static const struct omap_sham_pdata omap_sham_pdata_omap4 = { 1540static const struct omap_sham_pdata omap_sham_pdata_omap4 = {
1541 .algs_info = omap_sham_algs_info_omap4,
1542 .algs_info_size = ARRAY_SIZE(omap_sham_algs_info_omap4),
1389 .flags = BIT(FLAGS_AUTO_XOR), 1543 .flags = BIT(FLAGS_AUTO_XOR),
1390 .digest_size = SHA256_DIGEST_SIZE, 1544 .digest_size = SHA256_DIGEST_SIZE,
1391 .copy_hash = omap_sham_copy_hash_omap4, 1545 .copy_hash = omap_sham_copy_hash_omap4,
@@ -1570,17 +1724,24 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
1570 list_add_tail(&dd->list, &sham.dev_list); 1724 list_add_tail(&dd->list, &sham.dev_list);
1571 spin_unlock(&sham.lock); 1725 spin_unlock(&sham.lock);
1572 1726
1573 for (i = 0; i < ARRAY_SIZE(algs); i++) { 1727 for (i = 0; i < dd->pdata->algs_info_size; i++) {
1574 err = crypto_register_ahash(&algs[i]); 1728 for (j = 0; j < dd->pdata->algs_info[i].size; j++) {
1575 if (err) 1729 err = crypto_register_ahash(
1576 goto err_algs; 1730 &dd->pdata->algs_info[i].algs_list[j]);
1731 if (err)
1732 goto err_algs;
1733
1734 dd->pdata->algs_info[i].registered++;
1735 }
1577 } 1736 }
1578 1737
1579 return 0; 1738 return 0;
1580 1739
1581err_algs: 1740err_algs:
1582 for (j = 0; j < i; j++) 1741 for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
1583 crypto_unregister_ahash(&algs[j]); 1742 for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--)
1743 crypto_unregister_ahash(
1744 &dd->pdata->algs_info[i].algs_list[j]);
1584 pm_runtime_disable(dev); 1745 pm_runtime_disable(dev);
1585 dma_release_channel(dd->dma_lch); 1746 dma_release_channel(dd->dma_lch);
1586dma_err: 1747dma_err:
@@ -1597,7 +1758,7 @@ data_err:
1597static int __devexit omap_sham_remove(struct platform_device *pdev) 1758static int __devexit omap_sham_remove(struct platform_device *pdev)
1598{ 1759{
1599 static struct omap_sham_dev *dd; 1760 static struct omap_sham_dev *dd;
1600 int i; 1761 int i, j;
1601 1762
1602 dd = platform_get_drvdata(pdev); 1763 dd = platform_get_drvdata(pdev);
1603 if (!dd) 1764 if (!dd)
@@ -1605,8 +1766,10 @@ static int __devexit omap_sham_remove(struct platform_device *pdev)
1605 spin_lock(&sham.lock); 1766 spin_lock(&sham.lock);
1606 list_del(&dd->list); 1767 list_del(&dd->list);
1607 spin_unlock(&sham.lock); 1768 spin_unlock(&sham.lock);
1608 for (i = 0; i < ARRAY_SIZE(algs); i++) 1769 for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
1609 crypto_unregister_ahash(&algs[i]); 1770 for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--)
1771 crypto_unregister_ahash(
1772 &dd->pdata->algs_info[i].algs_list[j]);
1610 tasklet_kill(&dd->done_task); 1773 tasklet_kill(&dd->done_task);
1611 pm_runtime_disable(&pdev->dev); 1774 pm_runtime_disable(&pdev->dev);
1612 dma_release_channel(dd->dma_lch); 1775 dma_release_channel(dd->dma_lch);