164d85cc9SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2*10cb823bSAditya Srivastava /*
36148c1adSKent Yoder * AES XCBC routines supporting the Power 7+ Nest Accelerators driver
46148c1adSKent Yoder *
56148c1adSKent Yoder * Copyright (C) 2011-2012 International Business Machines Inc.
66148c1adSKent Yoder *
76148c1adSKent Yoder * Author: Kent Yoder <yoder1@us.ibm.com>
86148c1adSKent Yoder */
96148c1adSKent Yoder
106148c1adSKent Yoder #include <crypto/internal/hash.h>
116148c1adSKent Yoder #include <crypto/aes.h>
126148c1adSKent Yoder #include <crypto/algapi.h>
136148c1adSKent Yoder #include <linux/module.h>
146148c1adSKent Yoder #include <linux/types.h>
156148c1adSKent Yoder #include <linux/crypto.h>
166148c1adSKent Yoder #include <asm/vio.h>
176148c1adSKent Yoder
186148c1adSKent Yoder #include "nx_csbcpb.h"
196148c1adSKent Yoder #include "nx.h"
206148c1adSKent Yoder
216148c1adSKent Yoder
226148c1adSKent Yoder struct xcbc_state {
236148c1adSKent Yoder u8 state[AES_BLOCK_SIZE];
246148c1adSKent Yoder unsigned int count;
256148c1adSKent Yoder u8 buffer[AES_BLOCK_SIZE];
266148c1adSKent Yoder };
276148c1adSKent Yoder
nx_xcbc_set_key(struct crypto_shash * desc,const u8 * in_key,unsigned int key_len)286148c1adSKent Yoder static int nx_xcbc_set_key(struct crypto_shash *desc,
296148c1adSKent Yoder const u8 *in_key,
306148c1adSKent Yoder unsigned int key_len)
316148c1adSKent Yoder {
326148c1adSKent Yoder struct nx_crypto_ctx *nx_ctx = crypto_shash_ctx(desc);
33030f4e96SHerbert Xu struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
346148c1adSKent Yoder
356148c1adSKent Yoder switch (key_len) {
366148c1adSKent Yoder case AES_KEYSIZE_128:
376148c1adSKent Yoder nx_ctx->ap = &nx_ctx->props[NX_PROPS_AES_128];
386148c1adSKent Yoder break;
396148c1adSKent Yoder default:
406148c1adSKent Yoder return -EINVAL;
416148c1adSKent Yoder }
426148c1adSKent Yoder
43030f4e96SHerbert Xu memcpy(csbcpb->cpb.aes_xcbc.key, in_key, key_len);
446148c1adSKent Yoder
456148c1adSKent Yoder return 0;
466148c1adSKent Yoder }
476148c1adSKent Yoder
4841e3173dSMarcelo Cerri /*
4941e3173dSMarcelo Cerri * Based on RFC 3566, for a zero-length message:
5041e3173dSMarcelo Cerri *
5141e3173dSMarcelo Cerri * n = 1
5241e3173dSMarcelo Cerri * K1 = E(K, 0x01010101010101010101010101010101)
5341e3173dSMarcelo Cerri * K3 = E(K, 0x03030303030303030303030303030303)
5441e3173dSMarcelo Cerri * E[0] = 0x00000000000000000000000000000000
5541e3173dSMarcelo Cerri * M[1] = 0x80000000000000000000000000000000 (0 length message with padding)
5641e3173dSMarcelo Cerri * E[1] = (K1, M[1] ^ E[0] ^ K3)
5741e3173dSMarcelo Cerri * Tag = M[1]
5841e3173dSMarcelo Cerri */
nx_xcbc_empty(struct shash_desc * desc,u8 * out)5941e3173dSMarcelo Cerri static int nx_xcbc_empty(struct shash_desc *desc, u8 *out)
6041e3173dSMarcelo Cerri {
6141e3173dSMarcelo Cerri struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(&desc->tfm->base);
6241e3173dSMarcelo Cerri struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
6341e3173dSMarcelo Cerri struct nx_sg *in_sg, *out_sg;
6441e3173dSMarcelo Cerri u8 keys[2][AES_BLOCK_SIZE];
6541e3173dSMarcelo Cerri u8 key[32];
6641e3173dSMarcelo Cerri int rc = 0;
675313231aSLeonidas S. Barbosa int len;
6841e3173dSMarcelo Cerri
6941e3173dSMarcelo Cerri /* Change to ECB mode */
7041e3173dSMarcelo Cerri csbcpb->cpb.hdr.mode = NX_MODE_AES_ECB;
7141e3173dSMarcelo Cerri memcpy(key, csbcpb->cpb.aes_xcbc.key, AES_BLOCK_SIZE);
7241e3173dSMarcelo Cerri memcpy(csbcpb->cpb.aes_ecb.key, key, AES_BLOCK_SIZE);
7341e3173dSMarcelo Cerri NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT;
7441e3173dSMarcelo Cerri
7541e3173dSMarcelo Cerri /* K1 and K3 base patterns */
7641e3173dSMarcelo Cerri memset(keys[0], 0x01, sizeof(keys[0]));
7741e3173dSMarcelo Cerri memset(keys[1], 0x03, sizeof(keys[1]));
7841e3173dSMarcelo Cerri
795313231aSLeonidas S. Barbosa len = sizeof(keys);
8041e3173dSMarcelo Cerri /* Generate K1 and K3 encrypting the patterns */
815313231aSLeonidas S. Barbosa in_sg = nx_build_sg_list(nx_ctx->in_sg, (u8 *) keys, &len,
8241e3173dSMarcelo Cerri nx_ctx->ap->sglen);
835313231aSLeonidas S. Barbosa
845313231aSLeonidas S. Barbosa if (len != sizeof(keys))
855313231aSLeonidas S. Barbosa return -EINVAL;
865313231aSLeonidas S. Barbosa
875313231aSLeonidas S. Barbosa out_sg = nx_build_sg_list(nx_ctx->out_sg, (u8 *) keys, &len,
8841e3173dSMarcelo Cerri nx_ctx->ap->sglen);
895313231aSLeonidas S. Barbosa
905313231aSLeonidas S. Barbosa if (len != sizeof(keys))
915313231aSLeonidas S. Barbosa return -EINVAL;
925313231aSLeonidas S. Barbosa
9341e3173dSMarcelo Cerri nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) * sizeof(struct nx_sg);
9441e3173dSMarcelo Cerri nx_ctx->op.outlen = (nx_ctx->out_sg - out_sg) * sizeof(struct nx_sg);
9541e3173dSMarcelo Cerri
9675f22228SEric Biggers rc = nx_hcall_sync(nx_ctx, &nx_ctx->op, 0);
9741e3173dSMarcelo Cerri if (rc)
9841e3173dSMarcelo Cerri goto out;
9941e3173dSMarcelo Cerri atomic_inc(&(nx_ctx->stats->aes_ops));
10041e3173dSMarcelo Cerri
10141e3173dSMarcelo Cerri /* XOr K3 with the padding for a 0 length message */
10241e3173dSMarcelo Cerri keys[1][0] ^= 0x80;
10341e3173dSMarcelo Cerri
1045313231aSLeonidas S. Barbosa len = sizeof(keys[1]);
1055313231aSLeonidas S. Barbosa
10641e3173dSMarcelo Cerri /* Encrypt the final result */
10741e3173dSMarcelo Cerri memcpy(csbcpb->cpb.aes_ecb.key, keys[0], AES_BLOCK_SIZE);
1085313231aSLeonidas S. Barbosa in_sg = nx_build_sg_list(nx_ctx->in_sg, (u8 *) keys[1], &len,
10941e3173dSMarcelo Cerri nx_ctx->ap->sglen);
1105313231aSLeonidas S. Barbosa
1115313231aSLeonidas S. Barbosa if (len != sizeof(keys[1]))
1125313231aSLeonidas S. Barbosa return -EINVAL;
1135313231aSLeonidas S. Barbosa
1145313231aSLeonidas S. Barbosa len = AES_BLOCK_SIZE;
1155313231aSLeonidas S. Barbosa out_sg = nx_build_sg_list(nx_ctx->out_sg, out, &len,
11641e3173dSMarcelo Cerri nx_ctx->ap->sglen);
1175313231aSLeonidas S. Barbosa
1185313231aSLeonidas S. Barbosa if (len != AES_BLOCK_SIZE)
1195313231aSLeonidas S. Barbosa return -EINVAL;
1205313231aSLeonidas S. Barbosa
12141e3173dSMarcelo Cerri nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) * sizeof(struct nx_sg);
12241e3173dSMarcelo Cerri nx_ctx->op.outlen = (nx_ctx->out_sg - out_sg) * sizeof(struct nx_sg);
12341e3173dSMarcelo Cerri
12475f22228SEric Biggers rc = nx_hcall_sync(nx_ctx, &nx_ctx->op, 0);
12541e3173dSMarcelo Cerri if (rc)
12641e3173dSMarcelo Cerri goto out;
12741e3173dSMarcelo Cerri atomic_inc(&(nx_ctx->stats->aes_ops));
12841e3173dSMarcelo Cerri
12941e3173dSMarcelo Cerri out:
13041e3173dSMarcelo Cerri /* Restore XCBC mode */
13141e3173dSMarcelo Cerri csbcpb->cpb.hdr.mode = NX_MODE_AES_XCBC_MAC;
13241e3173dSMarcelo Cerri memcpy(csbcpb->cpb.aes_xcbc.key, key, AES_BLOCK_SIZE);
13341e3173dSMarcelo Cerri NX_CPB_FDM(csbcpb) &= ~NX_FDM_ENDE_ENCRYPT;
13441e3173dSMarcelo Cerri
13541e3173dSMarcelo Cerri return rc;
13641e3173dSMarcelo Cerri }
13741e3173dSMarcelo Cerri
nx_crypto_ctx_aes_xcbc_init2(struct crypto_tfm * tfm)138030f4e96SHerbert Xu static int nx_crypto_ctx_aes_xcbc_init2(struct crypto_tfm *tfm)
1396148c1adSKent Yoder {
140030f4e96SHerbert Xu struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(tfm);
1416148c1adSKent Yoder struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
142030f4e96SHerbert Xu int err;
143030f4e96SHerbert Xu
144030f4e96SHerbert Xu err = nx_crypto_ctx_aes_xcbc_init(tfm);
145030f4e96SHerbert Xu if (err)
146030f4e96SHerbert Xu return err;
1476148c1adSKent Yoder
1486148c1adSKent Yoder nx_ctx_init(nx_ctx, HCOP_FC_AES);
1496148c1adSKent Yoder
1506148c1adSKent Yoder NX_CPB_SET_KEY_SIZE(csbcpb, NX_KS_AES_128);
1516148c1adSKent Yoder csbcpb->cpb.hdr.mode = NX_MODE_AES_XCBC_MAC;
1526148c1adSKent Yoder
153030f4e96SHerbert Xu return 0;
154030f4e96SHerbert Xu }
1556148c1adSKent Yoder
nx_xcbc_init(struct shash_desc * desc)156030f4e96SHerbert Xu static int nx_xcbc_init(struct shash_desc *desc)
157030f4e96SHerbert Xu {
158030f4e96SHerbert Xu struct xcbc_state *sctx = shash_desc_ctx(desc);
1595313231aSLeonidas S. Barbosa
160030f4e96SHerbert Xu memset(sctx, 0, sizeof *sctx);
1616148c1adSKent Yoder
1626148c1adSKent Yoder return 0;
1636148c1adSKent Yoder }
1646148c1adSKent Yoder
nx_xcbc_update(struct shash_desc * desc,const u8 * data,unsigned int len)1656148c1adSKent Yoder static int nx_xcbc_update(struct shash_desc *desc,
1666148c1adSKent Yoder const u8 *data,
1676148c1adSKent Yoder unsigned int len)
1686148c1adSKent Yoder {
1696148c1adSKent Yoder struct xcbc_state *sctx = shash_desc_ctx(desc);
1706148c1adSKent Yoder struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(&desc->tfm->base);
1716148c1adSKent Yoder struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
1726148c1adSKent Yoder struct nx_sg *in_sg;
173030f4e96SHerbert Xu struct nx_sg *out_sg;
1745313231aSLeonidas S. Barbosa u32 to_process = 0, leftover, total;
1755313231aSLeonidas S. Barbosa unsigned int max_sg_len;
176c849163bSMarcelo Cerri unsigned long irq_flags;
1776148c1adSKent Yoder int rc = 0;
1785313231aSLeonidas S. Barbosa int data_len;
1796148c1adSKent Yoder
180c849163bSMarcelo Cerri spin_lock_irqsave(&nx_ctx->lock, irq_flags);
181c849163bSMarcelo Cerri
1829d6f1a82SFionnuala Gunter
1839d6f1a82SFionnuala Gunter total = sctx->count + len;
1846148c1adSKent Yoder
1856148c1adSKent Yoder /* 2 cases for total data len:
1866148c1adSKent Yoder * 1: <= AES_BLOCK_SIZE: copy into state, return 0
1876148c1adSKent Yoder * 2: > AES_BLOCK_SIZE: process X blocks, copy in leftover
1886148c1adSKent Yoder */
1899d6f1a82SFionnuala Gunter if (total <= AES_BLOCK_SIZE) {
1906148c1adSKent Yoder memcpy(sctx->buffer + sctx->count, data, len);
1916148c1adSKent Yoder sctx->count += len;
1926148c1adSKent Yoder goto out;
1936148c1adSKent Yoder }
1946148c1adSKent Yoder
1959d6f1a82SFionnuala Gunter in_sg = nx_ctx->in_sg;
1965313231aSLeonidas S. Barbosa max_sg_len = min_t(u64, nx_driver.of.max_sg_len/sizeof(struct nx_sg),
1979d6f1a82SFionnuala Gunter nx_ctx->ap->sglen);
1985313231aSLeonidas S. Barbosa max_sg_len = min_t(u64, max_sg_len,
1995313231aSLeonidas S. Barbosa nx_ctx->ap->databytelen/NX_PAGE_SIZE);
2009d6f1a82SFionnuala Gunter
201030f4e96SHerbert Xu data_len = AES_BLOCK_SIZE;
202030f4e96SHerbert Xu out_sg = nx_build_sg_list(nx_ctx->out_sg, (u8 *)sctx->state,
203030f4e96SHerbert Xu &len, nx_ctx->ap->sglen);
204030f4e96SHerbert Xu
205030f4e96SHerbert Xu if (data_len != AES_BLOCK_SIZE) {
206030f4e96SHerbert Xu rc = -EINVAL;
207030f4e96SHerbert Xu goto out;
208030f4e96SHerbert Xu }
209030f4e96SHerbert Xu
210030f4e96SHerbert Xu nx_ctx->op.outlen = (nx_ctx->out_sg - out_sg) * sizeof(struct nx_sg);
211030f4e96SHerbert Xu
2129d6f1a82SFionnuala Gunter do {
2135313231aSLeonidas S. Barbosa to_process = total - to_process;
2149d6f1a82SFionnuala Gunter to_process = to_process & ~(AES_BLOCK_SIZE - 1);
2155313231aSLeonidas S. Barbosa
2169d6f1a82SFionnuala Gunter leftover = total - to_process;
2176148c1adSKent Yoder
2189d6f1a82SFionnuala Gunter /* the hardware will not accept a 0 byte operation for this
2199d6f1a82SFionnuala Gunter * algorithm and the operation MUST be finalized to be correct.
2209d6f1a82SFionnuala Gunter * So if we happen to get an update that falls on a block sized
2219d6f1a82SFionnuala Gunter * boundary, we must save off the last block to finalize with
2229d6f1a82SFionnuala Gunter * later. */
2236148c1adSKent Yoder if (!leftover) {
2246148c1adSKent Yoder to_process -= AES_BLOCK_SIZE;
2256148c1adSKent Yoder leftover = AES_BLOCK_SIZE;
2266148c1adSKent Yoder }
2276148c1adSKent Yoder
2286148c1adSKent Yoder if (sctx->count) {
2295313231aSLeonidas S. Barbosa data_len = sctx->count;
2309d6f1a82SFionnuala Gunter in_sg = nx_build_sg_list(nx_ctx->in_sg,
2319d6f1a82SFionnuala Gunter (u8 *) sctx->buffer,
2325313231aSLeonidas S. Barbosa &data_len,
2339d6f1a82SFionnuala Gunter max_sg_len);
234030f4e96SHerbert Xu if (data_len != sctx->count) {
235030f4e96SHerbert Xu rc = -EINVAL;
236030f4e96SHerbert Xu goto out;
237030f4e96SHerbert Xu }
2389d6f1a82SFionnuala Gunter }
2395313231aSLeonidas S. Barbosa
2405313231aSLeonidas S. Barbosa data_len = to_process - sctx->count;
2419d6f1a82SFionnuala Gunter in_sg = nx_build_sg_list(in_sg,
2429d6f1a82SFionnuala Gunter (u8 *) data,
2435313231aSLeonidas S. Barbosa &data_len,
2449d6f1a82SFionnuala Gunter max_sg_len);
2455313231aSLeonidas S. Barbosa
246030f4e96SHerbert Xu if (data_len != to_process - sctx->count) {
247030f4e96SHerbert Xu rc = -EINVAL;
248030f4e96SHerbert Xu goto out;
249030f4e96SHerbert Xu }
2505313231aSLeonidas S. Barbosa
2516148c1adSKent Yoder nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) *
2526148c1adSKent Yoder sizeof(struct nx_sg);
2539d6f1a82SFionnuala Gunter
2549d6f1a82SFionnuala Gunter /* we've hit the nx chip previously and we're updating again,
2559d6f1a82SFionnuala Gunter * so copy over the partial digest */
2569d6f1a82SFionnuala Gunter if (NX_CPB_FDM(csbcpb) & NX_FDM_CONTINUATION) {
2579d6f1a82SFionnuala Gunter memcpy(csbcpb->cpb.aes_xcbc.cv,
2589d6f1a82SFionnuala Gunter csbcpb->cpb.aes_xcbc.out_cv_mac,
2599d6f1a82SFionnuala Gunter AES_BLOCK_SIZE);
2606148c1adSKent Yoder }
2616148c1adSKent Yoder
2626148c1adSKent Yoder NX_CPB_FDM(csbcpb) |= NX_FDM_INTERMEDIATE;
2636148c1adSKent Yoder if (!nx_ctx->op.inlen || !nx_ctx->op.outlen) {
2646148c1adSKent Yoder rc = -EINVAL;
2656148c1adSKent Yoder goto out;
2666148c1adSKent Yoder }
2676148c1adSKent Yoder
26875f22228SEric Biggers rc = nx_hcall_sync(nx_ctx, &nx_ctx->op, 0);
2696148c1adSKent Yoder if (rc)
2706148c1adSKent Yoder goto out;
2716148c1adSKent Yoder
2726148c1adSKent Yoder atomic_inc(&(nx_ctx->stats->aes_ops));
2736148c1adSKent Yoder
2746148c1adSKent Yoder /* everything after the first update is continuation */
2756148c1adSKent Yoder NX_CPB_FDM(csbcpb) |= NX_FDM_CONTINUATION;
2769d6f1a82SFionnuala Gunter
2779d6f1a82SFionnuala Gunter total -= to_process;
2789d6f1a82SFionnuala Gunter data += to_process - sctx->count;
2799d6f1a82SFionnuala Gunter sctx->count = 0;
2809d6f1a82SFionnuala Gunter in_sg = nx_ctx->in_sg;
2819d6f1a82SFionnuala Gunter } while (leftover > AES_BLOCK_SIZE);
2829d6f1a82SFionnuala Gunter
2839d6f1a82SFionnuala Gunter /* copy the leftover back into the state struct */
2849d6f1a82SFionnuala Gunter memcpy(sctx->buffer, data, leftover);
2859d6f1a82SFionnuala Gunter sctx->count = leftover;
2869d6f1a82SFionnuala Gunter
2876148c1adSKent Yoder out:
288c849163bSMarcelo Cerri spin_unlock_irqrestore(&nx_ctx->lock, irq_flags);
2896148c1adSKent Yoder return rc;
2906148c1adSKent Yoder }
2916148c1adSKent Yoder
nx_xcbc_final(struct shash_desc * desc,u8 * out)2926148c1adSKent Yoder static int nx_xcbc_final(struct shash_desc *desc, u8 *out)
2936148c1adSKent Yoder {
2946148c1adSKent Yoder struct xcbc_state *sctx = shash_desc_ctx(desc);
2956148c1adSKent Yoder struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(&desc->tfm->base);
2966148c1adSKent Yoder struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
2976148c1adSKent Yoder struct nx_sg *in_sg, *out_sg;
298c849163bSMarcelo Cerri unsigned long irq_flags;
2996148c1adSKent Yoder int rc = 0;
3005313231aSLeonidas S. Barbosa int len;
3016148c1adSKent Yoder
302c849163bSMarcelo Cerri spin_lock_irqsave(&nx_ctx->lock, irq_flags);
303c849163bSMarcelo Cerri
3046148c1adSKent Yoder if (NX_CPB_FDM(csbcpb) & NX_FDM_CONTINUATION) {
3056148c1adSKent Yoder /* we've hit the nx chip previously, now we're finalizing,
3066148c1adSKent Yoder * so copy over the partial digest */
3076148c1adSKent Yoder memcpy(csbcpb->cpb.aes_xcbc.cv,
3086148c1adSKent Yoder csbcpb->cpb.aes_xcbc.out_cv_mac, AES_BLOCK_SIZE);
3096148c1adSKent Yoder } else if (sctx->count == 0) {
31041e3173dSMarcelo Cerri /*
31141e3173dSMarcelo Cerri * we've never seen an update, so this is a 0 byte op. The
31241e3173dSMarcelo Cerri * hardware cannot handle a 0 byte op, so just ECB to
31341e3173dSMarcelo Cerri * generate the hash.
31441e3173dSMarcelo Cerri */
31541e3173dSMarcelo Cerri rc = nx_xcbc_empty(desc, out);
3166148c1adSKent Yoder goto out;
3176148c1adSKent Yoder }
3186148c1adSKent Yoder
3196148c1adSKent Yoder /* final is represented by continuing the operation and indicating that
3206148c1adSKent Yoder * this is not an intermediate operation */
3216148c1adSKent Yoder NX_CPB_FDM(csbcpb) &= ~NX_FDM_INTERMEDIATE;
3226148c1adSKent Yoder
3235313231aSLeonidas S. Barbosa len = sctx->count;
3246148c1adSKent Yoder in_sg = nx_build_sg_list(nx_ctx->in_sg, (u8 *)sctx->buffer,
3255313231aSLeonidas S. Barbosa &len, nx_ctx->ap->sglen);
3265313231aSLeonidas S. Barbosa
327030f4e96SHerbert Xu if (len != sctx->count) {
328030f4e96SHerbert Xu rc = -EINVAL;
329030f4e96SHerbert Xu goto out;
330030f4e96SHerbert Xu }
3315313231aSLeonidas S. Barbosa
3325313231aSLeonidas S. Barbosa len = AES_BLOCK_SIZE;
3335313231aSLeonidas S. Barbosa out_sg = nx_build_sg_list(nx_ctx->out_sg, out, &len,
3346148c1adSKent Yoder nx_ctx->ap->sglen);
3356148c1adSKent Yoder
336030f4e96SHerbert Xu if (len != AES_BLOCK_SIZE) {
337030f4e96SHerbert Xu rc = -EINVAL;
338030f4e96SHerbert Xu goto out;
339030f4e96SHerbert Xu }
3405313231aSLeonidas S. Barbosa
3416148c1adSKent Yoder nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) * sizeof(struct nx_sg);
3426148c1adSKent Yoder nx_ctx->op.outlen = (nx_ctx->out_sg - out_sg) * sizeof(struct nx_sg);
3436148c1adSKent Yoder
3446148c1adSKent Yoder if (!nx_ctx->op.outlen) {
3456148c1adSKent Yoder rc = -EINVAL;
3466148c1adSKent Yoder goto out;
3476148c1adSKent Yoder }
3486148c1adSKent Yoder
34975f22228SEric Biggers rc = nx_hcall_sync(nx_ctx, &nx_ctx->op, 0);
3506148c1adSKent Yoder if (rc)
3516148c1adSKent Yoder goto out;
3526148c1adSKent Yoder
3536148c1adSKent Yoder atomic_inc(&(nx_ctx->stats->aes_ops));
3546148c1adSKent Yoder
3556148c1adSKent Yoder memcpy(out, csbcpb->cpb.aes_xcbc.out_cv_mac, AES_BLOCK_SIZE);
3566148c1adSKent Yoder out:
357c849163bSMarcelo Cerri spin_unlock_irqrestore(&nx_ctx->lock, irq_flags);
3586148c1adSKent Yoder return rc;
3596148c1adSKent Yoder }
3606148c1adSKent Yoder
3616148c1adSKent Yoder struct shash_alg nx_shash_aes_xcbc_alg = {
3626148c1adSKent Yoder .digestsize = AES_BLOCK_SIZE,
3636148c1adSKent Yoder .init = nx_xcbc_init,
3646148c1adSKent Yoder .update = nx_xcbc_update,
3656148c1adSKent Yoder .final = nx_xcbc_final,
3666148c1adSKent Yoder .setkey = nx_xcbc_set_key,
3676148c1adSKent Yoder .descsize = sizeof(struct xcbc_state),
3686148c1adSKent Yoder .statesize = sizeof(struct xcbc_state),
3696148c1adSKent Yoder .base = {
3706148c1adSKent Yoder .cra_name = "xcbc(aes)",
3716148c1adSKent Yoder .cra_driver_name = "xcbc-aes-nx",
3726148c1adSKent Yoder .cra_priority = 300,
3736148c1adSKent Yoder .cra_blocksize = AES_BLOCK_SIZE,
3746148c1adSKent Yoder .cra_module = THIS_MODULE,
3756148c1adSKent Yoder .cra_ctxsize = sizeof(struct nx_crypto_ctx),
376030f4e96SHerbert Xu .cra_init = nx_crypto_ctx_aes_xcbc_init2,
3776148c1adSKent Yoder .cra_exit = nx_crypto_ctx_exit,
3786148c1adSKent Yoder }
3796148c1adSKent Yoder };
380