1 // SPDX-License-Identifier: GPL-2.0-only
3 * AES CBC routines supporting the Power 7+ Nest Accelerators driver
5 * Copyright (C) 2011-2012 International Business Machines Inc.
7 * Author: Kent Yoder <yoder1@us.ibm.com>
10 #include <crypto/aes.h>
11 #include <crypto/algapi.h>
12 #include <linux/module.h>
13 #include <linux/types.h>
14 #include <linux/crypto.h>
17 #include "nx_csbcpb.h"
21 static int cbc_aes_nx_set_key(struct crypto_skcipher
*tfm
,
25 struct nx_crypto_ctx
*nx_ctx
= crypto_skcipher_ctx(tfm
);
26 struct nx_csbcpb
*csbcpb
= nx_ctx
->csbcpb
;
28 nx_ctx_init(nx_ctx
, HCOP_FC_AES
);
32 NX_CPB_SET_KEY_SIZE(csbcpb
, NX_KS_AES_128
);
33 nx_ctx
->ap
= &nx_ctx
->props
[NX_PROPS_AES_128
];
36 NX_CPB_SET_KEY_SIZE(csbcpb
, NX_KS_AES_192
);
37 nx_ctx
->ap
= &nx_ctx
->props
[NX_PROPS_AES_192
];
40 NX_CPB_SET_KEY_SIZE(csbcpb
, NX_KS_AES_256
);
41 nx_ctx
->ap
= &nx_ctx
->props
[NX_PROPS_AES_256
];
47 csbcpb
->cpb
.hdr
.mode
= NX_MODE_AES_CBC
;
48 memcpy(csbcpb
->cpb
.aes_cbc
.key
, in_key
, key_len
);
53 static int cbc_aes_nx_crypt(struct skcipher_request
*req
,
56 struct crypto_skcipher
*tfm
= crypto_skcipher_reqtfm(req
);
57 struct nx_crypto_ctx
*nx_ctx
= crypto_skcipher_ctx(tfm
);
58 struct nx_csbcpb
*csbcpb
= nx_ctx
->csbcpb
;
59 unsigned long irq_flags
;
60 unsigned int processed
= 0, to_process
;
63 spin_lock_irqsave(&nx_ctx
->lock
, irq_flags
);
66 NX_CPB_FDM(csbcpb
) |= NX_FDM_ENDE_ENCRYPT
;
68 NX_CPB_FDM(csbcpb
) &= ~NX_FDM_ENDE_ENCRYPT
;
71 to_process
= req
->cryptlen
- processed
;
73 rc
= nx_build_sg_lists(nx_ctx
, req
->iv
, req
->dst
, req
->src
,
74 &to_process
, processed
,
75 csbcpb
->cpb
.aes_cbc
.iv
);
79 if (!nx_ctx
->op
.inlen
|| !nx_ctx
->op
.outlen
) {
84 rc
= nx_hcall_sync(nx_ctx
, &nx_ctx
->op
,
85 req
->base
.flags
& CRYPTO_TFM_REQ_MAY_SLEEP
);
89 memcpy(req
->iv
, csbcpb
->cpb
.aes_cbc
.cv
, AES_BLOCK_SIZE
);
90 atomic_inc(&(nx_ctx
->stats
->aes_ops
));
91 atomic64_add(csbcpb
->csb
.processed_byte_count
,
92 &(nx_ctx
->stats
->aes_bytes
));
94 processed
+= to_process
;
95 } while (processed
< req
->cryptlen
);
97 spin_unlock_irqrestore(&nx_ctx
->lock
, irq_flags
);
101 static int cbc_aes_nx_encrypt(struct skcipher_request
*req
)
103 return cbc_aes_nx_crypt(req
, 1);
106 static int cbc_aes_nx_decrypt(struct skcipher_request
*req
)
108 return cbc_aes_nx_crypt(req
, 0);
111 struct skcipher_alg nx_cbc_aes_alg
= {
112 .base
.cra_name
= "cbc(aes)",
113 .base
.cra_driver_name
= "cbc-aes-nx",
114 .base
.cra_priority
= 300,
115 .base
.cra_blocksize
= AES_BLOCK_SIZE
,
116 .base
.cra_ctxsize
= sizeof(struct nx_crypto_ctx
),
117 .base
.cra_alignmask
= 0xf,
118 .base
.cra_module
= THIS_MODULE
,
119 .init
= nx_crypto_ctx_aes_cbc_init
,
120 .exit
= nx_crypto_ctx_skcipher_exit
,
121 .min_keysize
= AES_MIN_KEY_SIZE
,
122 .max_keysize
= AES_MAX_KEY_SIZE
,
123 .ivsize
= AES_BLOCK_SIZE
,
124 .setkey
= cbc_aes_nx_set_key
,
125 .encrypt
= cbc_aes_nx_encrypt
,
126 .decrypt
= cbc_aes_nx_decrypt
,