aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/atmel-aes.c
diff options
context:
space:
mode:
authorCyrille Pitchen <cyrille.pitchen@atmel.com>2016-10-03 08:33:16 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2016-10-20 23:03:39 -0400
commitd52db5188a87dcdf8e5bf024f45543b362a1a85f (patch)
treeb11af2064e8b640cd8307d004361bc298a16bfb6 /drivers/crypto/atmel-aes.c
parentf709dc86bc4f9d8c320ceb9a12ac304756129dd5 (diff)
crypto: atmel-aes - add support to the XTS mode
This patch adds the xts(aes) algorithm, which is supported from hardware version 0x500 and above (sama5d2x). Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/atmel-aes.c')
-rw-r--r--drivers/crypto/atmel-aes.c185
1 files changed, 179 insertions, 6 deletions
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index 1d9e7bd3f377..6b656f4a9378 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -36,6 +36,7 @@
36#include <crypto/scatterwalk.h> 36#include <crypto/scatterwalk.h>
37#include <crypto/algapi.h> 37#include <crypto/algapi.h>
38#include <crypto/aes.h> 38#include <crypto/aes.h>
39#include <crypto/xts.h>
39#include <crypto/internal/aead.h> 40#include <crypto/internal/aead.h>
40#include <linux/platform_data/crypto-atmel.h> 41#include <linux/platform_data/crypto-atmel.h>
41#include <dt-bindings/dma/at91.h> 42#include <dt-bindings/dma/at91.h>
@@ -68,6 +69,7 @@
68#define AES_FLAGS_CFB8 (AES_MR_OPMOD_CFB | AES_MR_CFBS_8b) 69#define AES_FLAGS_CFB8 (AES_MR_OPMOD_CFB | AES_MR_CFBS_8b)
69#define AES_FLAGS_CTR AES_MR_OPMOD_CTR 70#define AES_FLAGS_CTR AES_MR_OPMOD_CTR
70#define AES_FLAGS_GCM AES_MR_OPMOD_GCM 71#define AES_FLAGS_GCM AES_MR_OPMOD_GCM
72#define AES_FLAGS_XTS AES_MR_OPMOD_XTS
71 73
72#define AES_FLAGS_MODE_MASK (AES_FLAGS_OPMODE_MASK | \ 74#define AES_FLAGS_MODE_MASK (AES_FLAGS_OPMODE_MASK | \
73 AES_FLAGS_ENCRYPT | \ 75 AES_FLAGS_ENCRYPT | \
@@ -89,6 +91,7 @@ struct atmel_aes_caps {
89 bool has_cfb64; 91 bool has_cfb64;
90 bool has_ctr32; 92 bool has_ctr32;
91 bool has_gcm; 93 bool has_gcm;
94 bool has_xts;
92 u32 max_burst_size; 95 u32 max_burst_size;
93}; 96};
94 97
@@ -135,6 +138,12 @@ struct atmel_aes_gcm_ctx {
135 atmel_aes_fn_t ghash_resume; 138 atmel_aes_fn_t ghash_resume;
136}; 139};
137 140
141struct atmel_aes_xts_ctx {
142 struct atmel_aes_base_ctx base;
143
144 u32 key2[AES_KEYSIZE_256 / sizeof(u32)];
145};
146
138struct atmel_aes_reqctx { 147struct atmel_aes_reqctx {
139 unsigned long mode; 148 unsigned long mode;
140}; 149};
@@ -282,6 +291,20 @@ static const char *atmel_aes_reg_name(u32 offset, char *tmp, size_t sz)
282 snprintf(tmp, sz, "GCMHR[%u]", (offset - AES_GCMHR(0)) >> 2); 291 snprintf(tmp, sz, "GCMHR[%u]", (offset - AES_GCMHR(0)) >> 2);
283 break; 292 break;
284 293
294 case AES_TWR(0):
295 case AES_TWR(1):
296 case AES_TWR(2):
297 case AES_TWR(3):
298 snprintf(tmp, sz, "TWR[%u]", (offset - AES_TWR(0)) >> 2);
299 break;
300
301 case AES_ALPHAR(0):
302 case AES_ALPHAR(1):
303 case AES_ALPHAR(2):
304 case AES_ALPHAR(3):
305 snprintf(tmp, sz, "ALPHAR[%u]", (offset - AES_ALPHAR(0)) >> 2);
306 break;
307
285 default: 308 default:
286 snprintf(tmp, sz, "0x%02x", offset); 309 snprintf(tmp, sz, "0x%02x", offset);
287 break; 310 break;
@@ -453,15 +476,15 @@ static inline int atmel_aes_complete(struct atmel_aes_dev *dd, int err)
453 return err; 476 return err;
454} 477}
455 478
456static void atmel_aes_write_ctrl(struct atmel_aes_dev *dd, bool use_dma, 479static void atmel_aes_write_ctrl_key(struct atmel_aes_dev *dd, bool use_dma,
457 const u32 *iv) 480 const u32 *iv, const u32 *key, int keylen)
458{ 481{
459 u32 valmr = 0; 482 u32 valmr = 0;
460 483
461 /* MR register must be set before IV registers */ 484 /* MR register must be set before IV registers */
462 if (dd->ctx->keylen == AES_KEYSIZE_128) 485 if (keylen == AES_KEYSIZE_128)
463 valmr |= AES_MR_KEYSIZE_128; 486 valmr |= AES_MR_KEYSIZE_128;
464 else if (dd->ctx->keylen == AES_KEYSIZE_192) 487 else if (keylen == AES_KEYSIZE_192)
465 valmr |= AES_MR_KEYSIZE_192; 488 valmr |= AES_MR_KEYSIZE_192;
466 else 489 else
467 valmr |= AES_MR_KEYSIZE_256; 490 valmr |= AES_MR_KEYSIZE_256;
@@ -478,13 +501,19 @@ static void atmel_aes_write_ctrl(struct atmel_aes_dev *dd, bool use_dma,
478 501
479 atmel_aes_write(dd, AES_MR, valmr); 502 atmel_aes_write(dd, AES_MR, valmr);
480 503
481 atmel_aes_write_n(dd, AES_KEYWR(0), dd->ctx->key, 504 atmel_aes_write_n(dd, AES_KEYWR(0), key, SIZE_IN_WORDS(keylen));
482 SIZE_IN_WORDS(dd->ctx->keylen));
483 505
484 if (iv && (valmr & AES_MR_OPMOD_MASK) != AES_MR_OPMOD_ECB) 506 if (iv && (valmr & AES_MR_OPMOD_MASK) != AES_MR_OPMOD_ECB)
485 atmel_aes_write_block(dd, AES_IVR(0), iv); 507 atmel_aes_write_block(dd, AES_IVR(0), iv);
486} 508}
487 509
510static inline void atmel_aes_write_ctrl(struct atmel_aes_dev *dd, bool use_dma,
511 const u32 *iv)
512
513{
514 atmel_aes_write_ctrl_key(dd, use_dma, iv,
515 dd->ctx->key, dd->ctx->keylen);
516}
488 517
489/* CPU transfer */ 518/* CPU transfer */
490 519
@@ -1769,6 +1798,137 @@ static struct aead_alg aes_gcm_alg = {
1769}; 1798};
1770 1799
1771 1800
1801/* xts functions */
1802
1803static inline struct atmel_aes_xts_ctx *
1804atmel_aes_xts_ctx_cast(struct atmel_aes_base_ctx *ctx)
1805{
1806 return container_of(ctx, struct atmel_aes_xts_ctx, base);
1807}
1808
1809static int atmel_aes_xts_process_data(struct atmel_aes_dev *dd);
1810
1811static int atmel_aes_xts_start(struct atmel_aes_dev *dd)
1812{
1813 struct atmel_aes_xts_ctx *ctx = atmel_aes_xts_ctx_cast(dd->ctx);
1814 struct ablkcipher_request *req = ablkcipher_request_cast(dd->areq);
1815 struct atmel_aes_reqctx *rctx = ablkcipher_request_ctx(req);
1816 unsigned long flags;
1817 int err;
1818
1819 atmel_aes_set_mode(dd, rctx);
1820
1821 err = atmel_aes_hw_init(dd);
1822 if (err)
1823 return atmel_aes_complete(dd, err);
1824
1825 /* Compute the tweak value from req->info with ecb(aes). */
1826 flags = dd->flags;
1827 dd->flags &= ~AES_FLAGS_MODE_MASK;
1828 dd->flags |= (AES_FLAGS_ECB | AES_FLAGS_ENCRYPT);
1829 atmel_aes_write_ctrl_key(dd, false, NULL,
1830 ctx->key2, ctx->base.keylen);
1831 dd->flags = flags;
1832
1833 atmel_aes_write_block(dd, AES_IDATAR(0), req->info);
1834 return atmel_aes_wait_for_data_ready(dd, atmel_aes_xts_process_data);
1835}
1836
1837static int atmel_aes_xts_process_data(struct atmel_aes_dev *dd)
1838{
1839 struct ablkcipher_request *req = ablkcipher_request_cast(dd->areq);
1840 bool use_dma = (req->nbytes >= ATMEL_AES_DMA_THRESHOLD);
1841 u32 tweak[AES_BLOCK_SIZE / sizeof(u32)];
1842 static const u32 one[AES_BLOCK_SIZE / sizeof(u32)] = {cpu_to_le32(1), };
1843 u8 *tweak_bytes = (u8 *)tweak;
1844 int i;
1845
1846 /* Read the computed ciphered tweak value. */
1847 atmel_aes_read_block(dd, AES_ODATAR(0), tweak);
1848 /*
1849 * Hardware quirk:
1850 * the order of the ciphered tweak bytes need to be reversed before
1851 * writing them into the ODATARx registers.
1852 */
1853 for (i = 0; i < AES_BLOCK_SIZE/2; ++i) {
1854 u8 tmp = tweak_bytes[AES_BLOCK_SIZE - 1 - i];
1855
1856 tweak_bytes[AES_BLOCK_SIZE - 1 - i] = tweak_bytes[i];
1857 tweak_bytes[i] = tmp;
1858 }
1859
1860 /* Process the data. */
1861 atmel_aes_write_ctrl(dd, use_dma, NULL);
1862 atmel_aes_write_block(dd, AES_TWR(0), tweak);
1863 atmel_aes_write_block(dd, AES_ALPHAR(0), one);
1864 if (use_dma)
1865 return atmel_aes_dma_start(dd, req->src, req->dst, req->nbytes,
1866 atmel_aes_transfer_complete);
1867
1868 return atmel_aes_cpu_start(dd, req->src, req->dst, req->nbytes,
1869 atmel_aes_transfer_complete);
1870}
1871
1872static int atmel_aes_xts_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
1873 unsigned int keylen)
1874{
1875 struct atmel_aes_xts_ctx *ctx = crypto_ablkcipher_ctx(tfm);
1876 int err;
1877
1878 err = xts_check_key(crypto_ablkcipher_tfm(tfm), key, keylen);
1879 if (err)
1880 return err;
1881
1882 memcpy(ctx->base.key, key, keylen/2);
1883 memcpy(ctx->key2, key + keylen/2, keylen/2);
1884 ctx->base.keylen = keylen/2;
1885
1886 return 0;
1887}
1888
1889static int atmel_aes_xts_encrypt(struct ablkcipher_request *req)
1890{
1891 return atmel_aes_crypt(req, AES_FLAGS_XTS | AES_FLAGS_ENCRYPT);
1892}
1893
1894static int atmel_aes_xts_decrypt(struct ablkcipher_request *req)
1895{
1896 return atmel_aes_crypt(req, AES_FLAGS_XTS);
1897}
1898
1899static int atmel_aes_xts_cra_init(struct crypto_tfm *tfm)
1900{
1901 struct atmel_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
1902
1903 tfm->crt_ablkcipher.reqsize = sizeof(struct atmel_aes_reqctx);
1904 ctx->base.start = atmel_aes_xts_start;
1905
1906 return 0;
1907}
1908
1909static struct crypto_alg aes_xts_alg = {
1910 .cra_name = "xts(aes)",
1911 .cra_driver_name = "atmel-xts-aes",
1912 .cra_priority = ATMEL_AES_PRIORITY,
1913 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
1914 .cra_blocksize = AES_BLOCK_SIZE,
1915 .cra_ctxsize = sizeof(struct atmel_aes_xts_ctx),
1916 .cra_alignmask = 0xf,
1917 .cra_type = &crypto_ablkcipher_type,
1918 .cra_module = THIS_MODULE,
1919 .cra_init = atmel_aes_xts_cra_init,
1920 .cra_exit = atmel_aes_cra_exit,
1921 .cra_u.ablkcipher = {
1922 .min_keysize = 2 * AES_MIN_KEY_SIZE,
1923 .max_keysize = 2 * AES_MAX_KEY_SIZE,
1924 .ivsize = AES_BLOCK_SIZE,
1925 .setkey = atmel_aes_xts_setkey,
1926 .encrypt = atmel_aes_xts_encrypt,
1927 .decrypt = atmel_aes_xts_decrypt,
1928 }
1929};
1930
1931
1772/* Probe functions */ 1932/* Probe functions */
1773 1933
1774static int atmel_aes_buff_init(struct atmel_aes_dev *dd) 1934static int atmel_aes_buff_init(struct atmel_aes_dev *dd)
@@ -1877,6 +2037,9 @@ static void atmel_aes_unregister_algs(struct atmel_aes_dev *dd)
1877{ 2037{
1878 int i; 2038 int i;
1879 2039
2040 if (dd->caps.has_xts)
2041 crypto_unregister_alg(&aes_xts_alg);
2042
1880 if (dd->caps.has_gcm) 2043 if (dd->caps.has_gcm)
1881 crypto_unregister_aead(&aes_gcm_alg); 2044 crypto_unregister_aead(&aes_gcm_alg);
1882 2045
@@ -1909,8 +2072,16 @@ static int atmel_aes_register_algs(struct atmel_aes_dev *dd)
1909 goto err_aes_gcm_alg; 2072 goto err_aes_gcm_alg;
1910 } 2073 }
1911 2074
2075 if (dd->caps.has_xts) {
2076 err = crypto_register_alg(&aes_xts_alg);
2077 if (err)
2078 goto err_aes_xts_alg;
2079 }
2080
1912 return 0; 2081 return 0;
1913 2082
2083err_aes_xts_alg:
2084 crypto_unregister_aead(&aes_gcm_alg);
1914err_aes_gcm_alg: 2085err_aes_gcm_alg:
1915 crypto_unregister_alg(&aes_cfb64_alg); 2086 crypto_unregister_alg(&aes_cfb64_alg);
1916err_aes_cfb64_alg: 2087err_aes_cfb64_alg:
@@ -1928,6 +2099,7 @@ static void atmel_aes_get_cap(struct atmel_aes_dev *dd)
1928 dd->caps.has_cfb64 = 0; 2099 dd->caps.has_cfb64 = 0;
1929 dd->caps.has_ctr32 = 0; 2100 dd->caps.has_ctr32 = 0;
1930 dd->caps.has_gcm = 0; 2101 dd->caps.has_gcm = 0;
2102 dd->caps.has_xts = 0;
1931 dd->caps.max_burst_size = 1; 2103 dd->caps.max_burst_size = 1;
1932 2104
1933 /* keep only major version number */ 2105 /* keep only major version number */
@@ -1937,6 +2109,7 @@ static void atmel_aes_get_cap(struct atmel_aes_dev *dd)
1937 dd->caps.has_cfb64 = 1; 2109 dd->caps.has_cfb64 = 1;
1938 dd->caps.has_ctr32 = 1; 2110 dd->caps.has_ctr32 = 1;
1939 dd->caps.has_gcm = 1; 2111 dd->caps.has_gcm = 1;
2112 dd->caps.has_xts = 1;
1940 dd->caps.max_burst_size = 4; 2113 dd->caps.max_burst_size = 4;
1941 break; 2114 break;
1942 case 0x200: 2115 case 0x200: