Skip to content

Commit 98e87e3

Browse files
chunkeeyherbertx
authored andcommitted
crypto: crypto4xx - add aes-ctr support
This patch adds support for the aes-ctr skcipher. name : ctr(aes) driver : ctr-aes-ppc4xx module : crypto4xx priority : 300 refcnt : 1 selftest : passed internal : no type : skcipher async : yes blocksize : 16 min keysize : 16 max keysize : 32 ivsize : 16 chunksize : 16 walksize : 16 The hardware uses only the last 32-bits as the counter while the kernel tests (aes_ctr_enc_tv_template[4] for example) expect that the whole IV is a counter. To make this work, the driver will fallback if the counter is going to overlow. The aead's crypto4xx_setup_fallback() function is renamed to crypto4xx_aead_setup_fallback. Signed-off-by: Christian Lamparter <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent c4e9065 commit 98e87e3

File tree

4 files changed

+128
-6
lines changed

4 files changed

+128
-6
lines changed

drivers/crypto/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ config CRYPTO_DEV_PPC4XX
302302
select CRYPTO_AEAD
303303
select CRYPTO_AES
304304
select CRYPTO_CCM
305+
select CRYPTO_CTR
305306
select CRYPTO_GCM
306307
select CRYPTO_BLKCIPHER
307308
help

drivers/crypto/amcc/crypto4xx_alg.c

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,85 @@ int crypto4xx_rfc3686_decrypt(struct skcipher_request *req)
240240
ctx->sa_out, ctx->sa_len, 0);
241241
}
242242

243+
static int
244+
crypto4xx_ctr_crypt(struct skcipher_request *req, bool encrypt)
245+
{
246+
struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
247+
struct crypto4xx_ctx *ctx = crypto_skcipher_ctx(cipher);
248+
size_t iv_len = crypto_skcipher_ivsize(cipher);
249+
unsigned int counter = be32_to_cpup((__be32 *)(req->iv + iv_len - 4));
250+
unsigned int nblks = ALIGN(req->cryptlen, AES_BLOCK_SIZE) /
251+
AES_BLOCK_SIZE;
252+
253+
/*
254+
* The hardware uses only the last 32-bits as the counter while the
255+
* kernel tests (aes_ctr_enc_tv_template[4] for example) expect that
256+
* the whole IV is a counter. So fallback if the counter is going to
257+
* overlow.
258+
*/
259+
if (counter + nblks < counter) {
260+
struct skcipher_request *subreq = skcipher_request_ctx(req);
261+
int ret;
262+
263+
skcipher_request_set_tfm(subreq, ctx->sw_cipher.cipher);
264+
skcipher_request_set_callback(subreq, req->base.flags,
265+
NULL, NULL);
266+
skcipher_request_set_crypt(subreq, req->src, req->dst,
267+
req->cryptlen, req->iv);
268+
ret = encrypt ? crypto_skcipher_encrypt(subreq)
269+
: crypto_skcipher_decrypt(subreq);
270+
skcipher_request_zero(subreq);
271+
return ret;
272+
}
273+
274+
return encrypt ? crypto4xx_encrypt_iv(req)
275+
: crypto4xx_decrypt_iv(req);
276+
}
277+
278+
static int crypto4xx_sk_setup_fallback(struct crypto4xx_ctx *ctx,
279+
struct crypto_skcipher *cipher,
280+
const u8 *key,
281+
unsigned int keylen)
282+
{
283+
int rc;
284+
285+
crypto_skcipher_clear_flags(ctx->sw_cipher.cipher,
286+
CRYPTO_TFM_REQ_MASK);
287+
crypto_skcipher_set_flags(ctx->sw_cipher.cipher,
288+
crypto_skcipher_get_flags(cipher) & CRYPTO_TFM_REQ_MASK);
289+
rc = crypto_skcipher_setkey(ctx->sw_cipher.cipher, key, keylen);
290+
crypto_skcipher_clear_flags(cipher, CRYPTO_TFM_RES_MASK);
291+
crypto_skcipher_set_flags(cipher,
292+
crypto_skcipher_get_flags(ctx->sw_cipher.cipher) &
293+
CRYPTO_TFM_RES_MASK);
294+
295+
return rc;
296+
}
297+
298+
int crypto4xx_setkey_aes_ctr(struct crypto_skcipher *cipher,
299+
const u8 *key, unsigned int keylen)
300+
{
301+
struct crypto4xx_ctx *ctx = crypto_skcipher_ctx(cipher);
302+
int rc;
303+
304+
rc = crypto4xx_sk_setup_fallback(ctx, cipher, key, keylen);
305+
if (rc)
306+
return rc;
307+
308+
return crypto4xx_setkey_aes(cipher, key, keylen,
309+
CRYPTO_MODE_CTR, CRYPTO_FEEDBACK_MODE_NO_FB);
310+
}
311+
312+
int crypto4xx_encrypt_ctr(struct skcipher_request *req)
313+
{
314+
return crypto4xx_ctr_crypt(req, true);
315+
}
316+
317+
int crypto4xx_decrypt_ctr(struct skcipher_request *req)
318+
{
319+
return crypto4xx_ctr_crypt(req, false);
320+
}
321+
243322
static inline bool crypto4xx_aead_need_fallback(struct aead_request *req,
244323
bool is_ccm, bool decrypt)
245324
{
@@ -282,10 +361,10 @@ static int crypto4xx_aead_fallback(struct aead_request *req,
282361
crypto_aead_encrypt(subreq);
283362
}
284363

285-
static int crypto4xx_setup_fallback(struct crypto4xx_ctx *ctx,
286-
struct crypto_aead *cipher,
287-
const u8 *key,
288-
unsigned int keylen)
364+
static int crypto4xx_aead_setup_fallback(struct crypto4xx_ctx *ctx,
365+
struct crypto_aead *cipher,
366+
const u8 *key,
367+
unsigned int keylen)
289368
{
290369
int rc;
291370

@@ -313,7 +392,7 @@ int crypto4xx_setkey_aes_ccm(struct crypto_aead *cipher, const u8 *key,
313392
struct dynamic_sa_ctl *sa;
314393
int rc = 0;
315394

316-
rc = crypto4xx_setup_fallback(ctx, cipher, key, keylen);
395+
rc = crypto4xx_aead_setup_fallback(ctx, cipher, key, keylen);
317396
if (rc)
318397
return rc;
319398

@@ -472,7 +551,7 @@ int crypto4xx_setkey_aes_gcm(struct crypto_aead *cipher,
472551
return -EINVAL;
473552
}
474553

475-
rc = crypto4xx_setup_fallback(ctx, cipher, key, keylen);
554+
rc = crypto4xx_aead_setup_fallback(ctx, cipher, key, keylen);
476555
if (rc)
477556
return rc;
478557

drivers/crypto/amcc/crypto4xx_core.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,19 @@ static int crypto4xx_sk_init(struct crypto_skcipher *sk)
941941
struct crypto4xx_alg *amcc_alg;
942942
struct crypto4xx_ctx *ctx = crypto_skcipher_ctx(sk);
943943

944+
if (alg->base.cra_flags & CRYPTO_ALG_NEED_FALLBACK) {
945+
ctx->sw_cipher.cipher =
946+
crypto_alloc_skcipher(alg->base.cra_name, 0,
947+
CRYPTO_ALG_NEED_FALLBACK |
948+
CRYPTO_ALG_ASYNC);
949+
if (IS_ERR(ctx->sw_cipher.cipher))
950+
return PTR_ERR(ctx->sw_cipher.cipher);
951+
952+
crypto_skcipher_set_reqsize(sk,
953+
sizeof(struct skcipher_request) + 32 +
954+
crypto_skcipher_reqsize(ctx->sw_cipher.cipher));
955+
}
956+
944957
amcc_alg = container_of(alg, struct crypto4xx_alg, alg.u.cipher);
945958
crypto4xx_ctx_init(amcc_alg, ctx);
946959
return 0;
@@ -956,6 +969,8 @@ static void crypto4xx_sk_exit(struct crypto_skcipher *sk)
956969
struct crypto4xx_ctx *ctx = crypto_skcipher_ctx(sk);
957970

958971
crypto4xx_common_exit(ctx);
972+
if (ctx->sw_cipher.cipher)
973+
crypto_free_skcipher(ctx->sw_cipher.cipher);
959974
}
960975

961976
static int crypto4xx_aead_init(struct crypto_aead *tfm)
@@ -1145,6 +1160,28 @@ static struct crypto4xx_alg_common crypto4xx_alg[] = {
11451160
.init = crypto4xx_sk_init,
11461161
.exit = crypto4xx_sk_exit,
11471162
} },
1163+
{ .type = CRYPTO_ALG_TYPE_SKCIPHER, .u.cipher = {
1164+
.base = {
1165+
.cra_name = "ctr(aes)",
1166+
.cra_driver_name = "ctr-aes-ppc4xx",
1167+
.cra_priority = CRYPTO4XX_CRYPTO_PRIORITY,
1168+
.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
1169+
CRYPTO_ALG_NEED_FALLBACK |
1170+
CRYPTO_ALG_ASYNC |
1171+
CRYPTO_ALG_KERN_DRIVER_ONLY,
1172+
.cra_blocksize = AES_BLOCK_SIZE,
1173+
.cra_ctxsize = sizeof(struct crypto4xx_ctx),
1174+
.cra_module = THIS_MODULE,
1175+
},
1176+
.min_keysize = AES_MIN_KEY_SIZE,
1177+
.max_keysize = AES_MAX_KEY_SIZE,
1178+
.ivsize = AES_IV_SIZE,
1179+
.setkey = crypto4xx_setkey_aes_ctr,
1180+
.encrypt = crypto4xx_encrypt_ctr,
1181+
.decrypt = crypto4xx_decrypt_ctr,
1182+
.init = crypto4xx_sk_init,
1183+
.exit = crypto4xx_sk_exit,
1184+
} },
11481185
{ .type = CRYPTO_ALG_TYPE_SKCIPHER, .u.cipher = {
11491186
.base = {
11501187
.cra_name = "rfc3686(ctr(aes))",

drivers/crypto/amcc/crypto4xx_core.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ struct crypto4xx_ctx {
128128
__le32 iv_nonce;
129129
u32 sa_len;
130130
union {
131+
struct crypto_skcipher *cipher;
131132
struct crypto_aead *aead;
132133
} sw_cipher;
133134
};
@@ -163,12 +164,16 @@ int crypto4xx_setkey_aes_cbc(struct crypto_skcipher *cipher,
163164
const u8 *key, unsigned int keylen);
164165
int crypto4xx_setkey_aes_cfb(struct crypto_skcipher *cipher,
165166
const u8 *key, unsigned int keylen);
167+
int crypto4xx_setkey_aes_ctr(struct crypto_skcipher *cipher,
168+
const u8 *key, unsigned int keylen);
166169
int crypto4xx_setkey_aes_ecb(struct crypto_skcipher *cipher,
167170
const u8 *key, unsigned int keylen);
168171
int crypto4xx_setkey_aes_ofb(struct crypto_skcipher *cipher,
169172
const u8 *key, unsigned int keylen);
170173
int crypto4xx_setkey_rfc3686(struct crypto_skcipher *cipher,
171174
const u8 *key, unsigned int keylen);
175+
int crypto4xx_encrypt_ctr(struct skcipher_request *req);
176+
int crypto4xx_decrypt_ctr(struct skcipher_request *req);
172177
int crypto4xx_encrypt_iv(struct skcipher_request *req);
173178
int crypto4xx_decrypt_iv(struct skcipher_request *req);
174179
int crypto4xx_encrypt_noiv(struct skcipher_request *req);

0 commit comments

Comments
 (0)