diff options
Diffstat (limited to 'drivers/crypto/omap-sham.c')
-rw-r--r-- | drivers/crypto/omap-sham.c | 183 |
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 | ||
182 | struct omap_sham_algs_info { | ||
183 | struct ahash_alg *algs_list; | ||
184 | unsigned int size; | ||
185 | unsigned int registered; | ||
186 | }; | ||
187 | |||
176 | struct omap_sham_pdata { | 188 | struct 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 | ||
1202 | static int omap_sham_cra_sha224_init(struct crypto_tfm *tfm) | ||
1203 | { | ||
1204 | return omap_sham_cra_init_alg(tfm, "sha224"); | ||
1205 | } | ||
1206 | |||
1207 | static int omap_sham_cra_sha256_init(struct crypto_tfm *tfm) | ||
1208 | { | ||
1209 | return omap_sham_cra_init_alg(tfm, "sha256"); | ||
1210 | } | ||
1211 | |||
1176 | static int omap_sham_cra_md5_init(struct crypto_tfm *tfm) | 1212 | static 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 | ||
1194 | static struct ahash_alg algs[] = { | 1230 | static 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 */ | ||
1330 | static 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 | |||
1293 | static void omap_sham_done_task(unsigned long data) | 1425 | static 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 | ||
1499 | static 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 | |||
1367 | static const struct omap_sham_pdata omap_sham_pdata_omap2 = { | 1506 | static 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 |
1529 | static 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 | |||
1388 | static const struct omap_sham_pdata omap_sham_pdata_omap4 = { | 1540 | static 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 | ||
1581 | err_algs: | 1740 | err_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); |
1586 | dma_err: | 1747 | dma_err: |
@@ -1597,7 +1758,7 @@ data_err: | |||
1597 | static int __devexit omap_sham_remove(struct platform_device *pdev) | 1758 | static 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); |