Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: ti - Add support for AES-XTS in DTHEv2 driver

Add support for XTS mode of operation for AES algorithm in the AES
Engine of the DTHEv2 hardware cryptographic engine.

Signed-off-by: T Pratham <t-pratham@ti.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

T Pratham and committed by
Herbert Xu
4fbfd7b2 85e1a7ec

+142 -8
+1
drivers/crypto/ti/Kconfig
··· 6 6 select CRYPTO_SKCIPHER 7 7 select CRYPTO_ECB 8 8 select CRYPTO_CBC 9 + select CRYPTO_XTS 9 10 help 10 11 This enables support for the TI DTHE V2 hw cryptography engine 11 12 which can be found on TI K3 SOCs. Selecting this enables use
+132 -7
drivers/crypto/ti/dthev2-aes.c
··· 25 25 26 26 // AES Engine 27 27 #define DTHE_P_AES_BASE 0x7000 28 + 28 29 #define DTHE_P_AES_KEY1_0 0x0038 29 30 #define DTHE_P_AES_KEY1_1 0x003C 30 31 #define DTHE_P_AES_KEY1_2 0x0030 ··· 34 33 #define DTHE_P_AES_KEY1_5 0x002C 35 34 #define DTHE_P_AES_KEY1_6 0x0020 36 35 #define DTHE_P_AES_KEY1_7 0x0024 36 + 37 + #define DTHE_P_AES_KEY2_0 0x0018 38 + #define DTHE_P_AES_KEY2_1 0x001C 39 + #define DTHE_P_AES_KEY2_2 0x0010 40 + #define DTHE_P_AES_KEY2_3 0x0014 41 + #define DTHE_P_AES_KEY2_4 0x0008 42 + #define DTHE_P_AES_KEY2_5 0x000C 43 + #define DTHE_P_AES_KEY2_6 0x0000 44 + #define DTHE_P_AES_KEY2_7 0x0004 45 + 37 46 #define DTHE_P_AES_IV_IN_0 0x0040 38 47 #define DTHE_P_AES_IV_IN_1 0x0044 39 48 #define DTHE_P_AES_IV_IN_2 0x0048 ··· 63 52 enum aes_ctrl_mode_masks { 64 53 AES_CTRL_ECB_MASK = 0x00, 65 54 AES_CTRL_CBC_MASK = BIT(5), 55 + AES_CTRL_XTS_MASK = BIT(12) | BIT(11), 66 56 }; 67 57 68 58 #define DTHE_AES_CTRL_MODE_CLEAR_MASK ~GENMASK(28, 5) ··· 100 88 return 0; 101 89 } 102 90 91 + static int dthe_cipher_xts_init_tfm(struct crypto_skcipher *tfm) 92 + { 93 + struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); 94 + struct dthe_data *dev_data = dthe_get_dev(ctx); 95 + 96 + ctx->dev_data = dev_data; 97 + ctx->keylen = 0; 98 + 99 + ctx->skcipher_fb = crypto_alloc_sync_skcipher("xts(aes)", 0, 100 + CRYPTO_ALG_NEED_FALLBACK); 101 + if (IS_ERR(ctx->skcipher_fb)) { 102 + dev_err(dev_data->dev, "fallback driver xts(aes) couldn't be loaded\n"); 103 + return PTR_ERR(ctx->skcipher_fb); 104 + } 105 + 106 + return 0; 107 + } 108 + 109 + static void dthe_cipher_xts_exit_tfm(struct crypto_skcipher *tfm) 110 + { 111 + struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); 112 + 113 + crypto_free_sync_skcipher(ctx->skcipher_fb); 114 + } 115 + 103 116 static int dthe_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen) 104 117 { 105 118 struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); ··· 156 119 return dthe_aes_setkey(tfm, key, keylen); 157 120 } 158 121 122 + static int dthe_aes_xts_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen) 123 + { 124 + struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); 125 + 126 + if (keylen != 2 * AES_KEYSIZE_128 && 127 + keylen != 2 * AES_KEYSIZE_192 && 128 + keylen != 2 * AES_KEYSIZE_256) 129 + return -EINVAL; 130 + 131 + ctx->aes_mode = DTHE_AES_XTS; 132 + ctx->keylen = keylen / 2; 133 + memcpy(ctx->key, key, keylen); 134 + 135 + crypto_sync_skcipher_clear_flags(ctx->skcipher_fb, CRYPTO_TFM_REQ_MASK); 136 + crypto_sync_skcipher_set_flags(ctx->skcipher_fb, 137 + crypto_skcipher_get_flags(tfm) & 138 + CRYPTO_TFM_REQ_MASK); 139 + 140 + return crypto_sync_skcipher_setkey(ctx->skcipher_fb, key, keylen); 141 + } 142 + 159 143 static void dthe_aes_set_ctrl_key(struct dthe_tfm_ctx *ctx, 160 144 struct dthe_aes_req_ctx *rctx, 161 145 u32 *iv_in) ··· 199 141 writel_relaxed(ctx->key[7], aes_base_reg + DTHE_P_AES_KEY1_7); 200 142 } 201 143 144 + if (ctx->aes_mode == DTHE_AES_XTS) { 145 + size_t key2_offset = ctx->keylen / sizeof(u32); 146 + 147 + writel_relaxed(ctx->key[key2_offset + 0], aes_base_reg + DTHE_P_AES_KEY2_0); 148 + writel_relaxed(ctx->key[key2_offset + 1], aes_base_reg + DTHE_P_AES_KEY2_1); 149 + writel_relaxed(ctx->key[key2_offset + 2], aes_base_reg + DTHE_P_AES_KEY2_2); 150 + writel_relaxed(ctx->key[key2_offset + 3], aes_base_reg + DTHE_P_AES_KEY2_3); 151 + 152 + if (ctx->keylen > AES_KEYSIZE_128) { 153 + writel_relaxed(ctx->key[key2_offset + 4], aes_base_reg + DTHE_P_AES_KEY2_4); 154 + writel_relaxed(ctx->key[key2_offset + 5], aes_base_reg + DTHE_P_AES_KEY2_5); 155 + } 156 + if (ctx->keylen == AES_KEYSIZE_256) { 157 + writel_relaxed(ctx->key[key2_offset + 6], aes_base_reg + DTHE_P_AES_KEY2_6); 158 + writel_relaxed(ctx->key[key2_offset + 7], aes_base_reg + DTHE_P_AES_KEY2_7); 159 + } 160 + } 161 + 202 162 if (rctx->enc) 203 163 ctrl_val |= DTHE_AES_CTRL_DIR_ENC; 204 164 ··· 235 159 break; 236 160 case DTHE_AES_CBC: 237 161 ctrl_val |= AES_CTRL_CBC_MASK; 162 + break; 163 + case DTHE_AES_XTS: 164 + ctrl_val |= AES_CTRL_XTS_MASK; 238 165 break; 239 166 } 240 167 ··· 394 315 local_bh_disable(); 395 316 crypto_finalize_skcipher_request(dev_data->engine, req, ret); 396 317 local_bh_enable(); 397 - return ret; 318 + return 0; 398 319 } 399 320 400 321 static int dthe_aes_crypt(struct skcipher_request *req) 401 322 { 402 323 struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req)); 324 + struct dthe_aes_req_ctx *rctx = skcipher_request_ctx(req); 403 325 struct dthe_data *dev_data = dthe_get_dev(ctx); 404 326 struct crypto_engine *engine; 405 327 406 328 /* 407 - * If data is not a multiple of AES_BLOCK_SIZE, need to return -EINVAL 408 - * If data length input is zero, no need to do any operation. 329 + * If data is not a multiple of AES_BLOCK_SIZE: 330 + * - need to return -EINVAL for ECB, CBC as they are block ciphers 331 + * - need to fallback to software as H/W doesn't support Ciphertext Stealing for XTS 409 332 */ 410 - if (req->cryptlen % AES_BLOCK_SIZE) 411 - return -EINVAL; 333 + if (req->cryptlen % AES_BLOCK_SIZE) { 334 + if (ctx->aes_mode == DTHE_AES_XTS) { 335 + SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, ctx->skcipher_fb); 412 336 413 - if (req->cryptlen == 0) 337 + skcipher_request_set_callback(subreq, skcipher_request_flags(req), 338 + req->base.complete, req->base.data); 339 + skcipher_request_set_crypt(subreq, req->src, req->dst, 340 + req->cryptlen, req->iv); 341 + 342 + return rctx->enc ? crypto_skcipher_encrypt(subreq) : 343 + crypto_skcipher_decrypt(subreq); 344 + } 345 + return -EINVAL; 346 + } 347 + 348 + /* 349 + * If data length input is zero, no need to do any operation. 350 + * Except for XTS mode, where data length should be non-zero. 351 + */ 352 + if (req->cryptlen == 0) { 353 + if (ctx->aes_mode == DTHE_AES_XTS) 354 + return -EINVAL; 414 355 return 0; 356 + } 415 357 416 358 engine = dev_data->engine; 417 359 return crypto_transfer_skcipher_request_to_engine(engine, req); ··· 499 399 .cra_module = THIS_MODULE, 500 400 }, 501 401 .op.do_one_request = dthe_aes_run, 502 - } /* CBC AES */ 402 + }, /* CBC AES */ 403 + { 404 + .base.init = dthe_cipher_xts_init_tfm, 405 + .base.exit = dthe_cipher_xts_exit_tfm, 406 + .base.setkey = dthe_aes_xts_setkey, 407 + .base.encrypt = dthe_aes_encrypt, 408 + .base.decrypt = dthe_aes_decrypt, 409 + .base.min_keysize = AES_MIN_KEY_SIZE * 2, 410 + .base.max_keysize = AES_MAX_KEY_SIZE * 2, 411 + .base.ivsize = AES_IV_SIZE, 412 + .base.base = { 413 + .cra_name = "xts(aes)", 414 + .cra_driver_name = "xts-aes-dthev2", 415 + .cra_priority = 299, 416 + .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | 417 + CRYPTO_ALG_ASYNC | 418 + CRYPTO_ALG_KERN_DRIVER_ONLY | 419 + CRYPTO_ALG_NEED_FALLBACK, 420 + .cra_alignmask = AES_BLOCK_SIZE - 1, 421 + .cra_blocksize = AES_BLOCK_SIZE, 422 + .cra_ctxsize = sizeof(struct dthe_tfm_ctx), 423 + .cra_reqsize = sizeof(struct dthe_aes_req_ctx), 424 + .cra_module = THIS_MODULE, 425 + }, 426 + .op.do_one_request = dthe_aes_run, 427 + }, /* XTS AES */ 503 428 }; 504 429 505 430 int dthe_register_aes_algs(void)
+9 -1
drivers/crypto/ti/dthev2-common.h
··· 27 27 28 28 #define DTHE_REG_SIZE 4 29 29 #define DTHE_DMA_TIMEOUT_MS 2000 30 + /* 31 + * Size of largest possible key (of all algorithms) to be stored in dthe_tfm_ctx 32 + * This is currently the keysize of XTS-AES-256 which is 512 bits (64 bytes) 33 + */ 34 + #define DTHE_MAX_KEYSIZE (AES_MAX_KEY_SIZE * 2) 30 35 31 36 enum dthe_aes_mode { 32 37 DTHE_AES_ECB = 0, 33 38 DTHE_AES_CBC, 39 + DTHE_AES_XTS, 34 40 }; 35 41 36 42 /* Driver specific struct definitions */ ··· 79 73 * @keylen: AES key length 80 74 * @key: AES key 81 75 * @aes_mode: AES mode 76 + * @skcipher_fb: Fallback crypto skcipher handle for AES-XTS mode 82 77 */ 83 78 struct dthe_tfm_ctx { 84 79 struct dthe_data *dev_data; 85 80 unsigned int keylen; 86 - u32 key[AES_KEYSIZE_256 / sizeof(u32)]; 81 + u32 key[DTHE_MAX_KEYSIZE / sizeof(u32)]; 87 82 enum dthe_aes_mode aes_mode; 83 + struct crypto_sync_skcipher *skcipher_fb; 88 84 }; 89 85 90 86 /**