162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2017 Marvell 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Antoine Tenart <antoine.tenart@free-electrons.com> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <asm/unaligned.h> 962306a36Sopenharmony_ci#include <linux/device.h> 1062306a36Sopenharmony_ci#include <linux/dma-mapping.h> 1162306a36Sopenharmony_ci#include <linux/dmapool.h> 1262306a36Sopenharmony_ci#include <crypto/aead.h> 1362306a36Sopenharmony_ci#include <crypto/aes.h> 1462306a36Sopenharmony_ci#include <crypto/authenc.h> 1562306a36Sopenharmony_ci#include <crypto/chacha.h> 1662306a36Sopenharmony_ci#include <crypto/ctr.h> 1762306a36Sopenharmony_ci#include <crypto/internal/des.h> 1862306a36Sopenharmony_ci#include <crypto/gcm.h> 1962306a36Sopenharmony_ci#include <crypto/ghash.h> 2062306a36Sopenharmony_ci#include <crypto/poly1305.h> 2162306a36Sopenharmony_ci#include <crypto/sha1.h> 2262306a36Sopenharmony_ci#include <crypto/sha2.h> 2362306a36Sopenharmony_ci#include <crypto/sm3.h> 2462306a36Sopenharmony_ci#include <crypto/sm4.h> 2562306a36Sopenharmony_ci#include <crypto/xts.h> 2662306a36Sopenharmony_ci#include <crypto/skcipher.h> 2762306a36Sopenharmony_ci#include <crypto/internal/aead.h> 2862306a36Sopenharmony_ci#include <crypto/internal/skcipher.h> 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#include "safexcel.h" 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cienum safexcel_cipher_direction { 3362306a36Sopenharmony_ci SAFEXCEL_ENCRYPT, 3462306a36Sopenharmony_ci SAFEXCEL_DECRYPT, 3562306a36Sopenharmony_ci}; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cienum safexcel_cipher_alg { 3862306a36Sopenharmony_ci SAFEXCEL_DES, 3962306a36Sopenharmony_ci SAFEXCEL_3DES, 4062306a36Sopenharmony_ci SAFEXCEL_AES, 4162306a36Sopenharmony_ci SAFEXCEL_CHACHA20, 4262306a36Sopenharmony_ci SAFEXCEL_SM4, 4362306a36Sopenharmony_ci}; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistruct safexcel_cipher_ctx { 4662306a36Sopenharmony_ci struct safexcel_context base; 4762306a36Sopenharmony_ci struct safexcel_crypto_priv *priv; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci u32 mode; 5062306a36Sopenharmony_ci enum safexcel_cipher_alg alg; 5162306a36Sopenharmony_ci u8 aead; /* !=0=AEAD, 2=IPSec ESP AEAD, 3=IPsec ESP GMAC */ 5262306a36Sopenharmony_ci u8 xcm; /* 0=authenc, 1=GCM, 2 reserved for CCM */ 5362306a36Sopenharmony_ci u8 aadskip; 5462306a36Sopenharmony_ci u8 blocksz; 5562306a36Sopenharmony_ci u32 ivmask; 5662306a36Sopenharmony_ci u32 ctrinit; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci __le32 key[16]; 5962306a36Sopenharmony_ci u32 nonce; 6062306a36Sopenharmony_ci unsigned int key_len, xts; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci /* All the below is AEAD specific */ 6362306a36Sopenharmony_ci u32 hash_alg; 6462306a36Sopenharmony_ci u32 state_sz; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci struct crypto_aead *fback; 6762306a36Sopenharmony_ci}; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistruct safexcel_cipher_req { 7062306a36Sopenharmony_ci enum safexcel_cipher_direction direction; 7162306a36Sopenharmony_ci /* Number of result descriptors associated to the request */ 7262306a36Sopenharmony_ci unsigned int rdescs; 7362306a36Sopenharmony_ci bool needs_inv; 7462306a36Sopenharmony_ci int nr_src, nr_dst; 7562306a36Sopenharmony_ci}; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic int safexcel_skcipher_iv(struct safexcel_cipher_ctx *ctx, u8 *iv, 7862306a36Sopenharmony_ci struct safexcel_command_desc *cdesc) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { 8162306a36Sopenharmony_ci cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 8262306a36Sopenharmony_ci /* 32 bit nonce */ 8362306a36Sopenharmony_ci cdesc->control_data.token[0] = ctx->nonce; 8462306a36Sopenharmony_ci /* 64 bit IV part */ 8562306a36Sopenharmony_ci memcpy(&cdesc->control_data.token[1], iv, 8); 8662306a36Sopenharmony_ci /* 32 bit counter, start at 0 or 1 (big endian!) */ 8762306a36Sopenharmony_ci cdesc->control_data.token[3] = 8862306a36Sopenharmony_ci (__force u32)cpu_to_be32(ctx->ctrinit); 8962306a36Sopenharmony_ci return 4; 9062306a36Sopenharmony_ci } 9162306a36Sopenharmony_ci if (ctx->alg == SAFEXCEL_CHACHA20) { 9262306a36Sopenharmony_ci cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 9362306a36Sopenharmony_ci /* 96 bit nonce part */ 9462306a36Sopenharmony_ci memcpy(&cdesc->control_data.token[0], &iv[4], 12); 9562306a36Sopenharmony_ci /* 32 bit counter */ 9662306a36Sopenharmony_ci cdesc->control_data.token[3] = *(u32 *)iv; 9762306a36Sopenharmony_ci return 4; 9862306a36Sopenharmony_ci } 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci cdesc->control_data.options |= ctx->ivmask; 10162306a36Sopenharmony_ci memcpy(cdesc->control_data.token, iv, ctx->blocksz); 10262306a36Sopenharmony_ci return ctx->blocksz / sizeof(u32); 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistatic void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 10662306a36Sopenharmony_ci struct safexcel_command_desc *cdesc, 10762306a36Sopenharmony_ci struct safexcel_token *atoken, 10862306a36Sopenharmony_ci u32 length) 10962306a36Sopenharmony_ci{ 11062306a36Sopenharmony_ci struct safexcel_token *token; 11162306a36Sopenharmony_ci int ivlen; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci ivlen = safexcel_skcipher_iv(ctx, iv, cdesc); 11462306a36Sopenharmony_ci if (ivlen == 4) { 11562306a36Sopenharmony_ci /* No space in cdesc, instruction moves to atoken */ 11662306a36Sopenharmony_ci cdesc->additional_cdata_size = 1; 11762306a36Sopenharmony_ci token = atoken; 11862306a36Sopenharmony_ci } else { 11962306a36Sopenharmony_ci /* Everything fits in cdesc */ 12062306a36Sopenharmony_ci token = (struct safexcel_token *)(cdesc->control_data.token + 2); 12162306a36Sopenharmony_ci /* Need to pad with NOP */ 12262306a36Sopenharmony_ci eip197_noop_token(&token[1]); 12362306a36Sopenharmony_ci } 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci token->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 12662306a36Sopenharmony_ci token->packet_length = length; 12762306a36Sopenharmony_ci token->stat = EIP197_TOKEN_STAT_LAST_PACKET | 12862306a36Sopenharmony_ci EIP197_TOKEN_STAT_LAST_HASH; 12962306a36Sopenharmony_ci token->instructions = EIP197_TOKEN_INS_LAST | 13062306a36Sopenharmony_ci EIP197_TOKEN_INS_TYPE_CRYPTO | 13162306a36Sopenharmony_ci EIP197_TOKEN_INS_TYPE_OUTPUT; 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cistatic void safexcel_aead_iv(struct safexcel_cipher_ctx *ctx, u8 *iv, 13562306a36Sopenharmony_ci struct safexcel_command_desc *cdesc) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD || 13862306a36Sopenharmony_ci ctx->aead & EIP197_AEAD_TYPE_IPSEC_ESP) { /* _ESP and _ESP_GMAC */ 13962306a36Sopenharmony_ci /* 32 bit nonce */ 14062306a36Sopenharmony_ci cdesc->control_data.token[0] = ctx->nonce; 14162306a36Sopenharmony_ci /* 64 bit IV part */ 14262306a36Sopenharmony_ci memcpy(&cdesc->control_data.token[1], iv, 8); 14362306a36Sopenharmony_ci /* 32 bit counter, start at 0 or 1 (big endian!) */ 14462306a36Sopenharmony_ci cdesc->control_data.token[3] = 14562306a36Sopenharmony_ci (__force u32)cpu_to_be32(ctx->ctrinit); 14662306a36Sopenharmony_ci return; 14762306a36Sopenharmony_ci } 14862306a36Sopenharmony_ci if (ctx->xcm == EIP197_XCM_MODE_GCM || ctx->alg == SAFEXCEL_CHACHA20) { 14962306a36Sopenharmony_ci /* 96 bit IV part */ 15062306a36Sopenharmony_ci memcpy(&cdesc->control_data.token[0], iv, 12); 15162306a36Sopenharmony_ci /* 32 bit counter, start at 0 or 1 (big endian!) */ 15262306a36Sopenharmony_ci cdesc->control_data.token[3] = 15362306a36Sopenharmony_ci (__force u32)cpu_to_be32(ctx->ctrinit); 15462306a36Sopenharmony_ci return; 15562306a36Sopenharmony_ci } 15662306a36Sopenharmony_ci /* CBC */ 15762306a36Sopenharmony_ci memcpy(cdesc->control_data.token, iv, ctx->blocksz); 15862306a36Sopenharmony_ci} 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_cistatic void safexcel_aead_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 16162306a36Sopenharmony_ci struct safexcel_command_desc *cdesc, 16262306a36Sopenharmony_ci struct safexcel_token *atoken, 16362306a36Sopenharmony_ci enum safexcel_cipher_direction direction, 16462306a36Sopenharmony_ci u32 cryptlen, u32 assoclen, u32 digestsize) 16562306a36Sopenharmony_ci{ 16662306a36Sopenharmony_ci struct safexcel_token *aadref; 16762306a36Sopenharmony_ci int atoksize = 2; /* Start with minimum size */ 16862306a36Sopenharmony_ci int assocadj = assoclen - ctx->aadskip, aadalign; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci /* Always 4 dwords of embedded IV for AEAD modes */ 17162306a36Sopenharmony_ci cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci if (direction == SAFEXCEL_DECRYPT) 17462306a36Sopenharmony_ci cryptlen -= digestsize; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM)) { 17762306a36Sopenharmony_ci /* Construct IV block B0 for the CBC-MAC */ 17862306a36Sopenharmony_ci u8 *final_iv = (u8 *)cdesc->control_data.token; 17962306a36Sopenharmony_ci u8 *cbcmaciv = (u8 *)&atoken[1]; 18062306a36Sopenharmony_ci __le32 *aadlen = (__le32 *)&atoken[5]; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 18362306a36Sopenharmony_ci /* Length + nonce */ 18462306a36Sopenharmony_ci cdesc->control_data.token[0] = ctx->nonce; 18562306a36Sopenharmony_ci /* Fixup flags byte */ 18662306a36Sopenharmony_ci *(__le32 *)cbcmaciv = 18762306a36Sopenharmony_ci cpu_to_le32(ctx->nonce | 18862306a36Sopenharmony_ci ((assocadj > 0) << 6) | 18962306a36Sopenharmony_ci ((digestsize - 2) << 2)); 19062306a36Sopenharmony_ci /* 64 bit IV part */ 19162306a36Sopenharmony_ci memcpy(&cdesc->control_data.token[1], iv, 8); 19262306a36Sopenharmony_ci memcpy(cbcmaciv + 4, iv, 8); 19362306a36Sopenharmony_ci /* Start counter at 0 */ 19462306a36Sopenharmony_ci cdesc->control_data.token[3] = 0; 19562306a36Sopenharmony_ci /* Message length */ 19662306a36Sopenharmony_ci *(__be32 *)(cbcmaciv + 12) = cpu_to_be32(cryptlen); 19762306a36Sopenharmony_ci } else { 19862306a36Sopenharmony_ci /* Variable length IV part */ 19962306a36Sopenharmony_ci memcpy(final_iv, iv, 15 - iv[0]); 20062306a36Sopenharmony_ci memcpy(cbcmaciv, iv, 15 - iv[0]); 20162306a36Sopenharmony_ci /* Start variable length counter at 0 */ 20262306a36Sopenharmony_ci memset(final_iv + 15 - iv[0], 0, iv[0] + 1); 20362306a36Sopenharmony_ci memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1); 20462306a36Sopenharmony_ci /* fixup flags byte */ 20562306a36Sopenharmony_ci cbcmaciv[0] |= ((assocadj > 0) << 6) | 20662306a36Sopenharmony_ci ((digestsize - 2) << 2); 20762306a36Sopenharmony_ci /* insert lower 2 bytes of message length */ 20862306a36Sopenharmony_ci cbcmaciv[14] = cryptlen >> 8; 20962306a36Sopenharmony_ci cbcmaciv[15] = cryptlen & 255; 21062306a36Sopenharmony_ci } 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 21362306a36Sopenharmony_ci atoken->packet_length = AES_BLOCK_SIZE + 21462306a36Sopenharmony_ci ((assocadj > 0) << 1); 21562306a36Sopenharmony_ci atoken->stat = 0; 21662306a36Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN | 21762306a36Sopenharmony_ci EIP197_TOKEN_INS_TYPE_HASH; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci if (likely(assocadj)) { 22062306a36Sopenharmony_ci *aadlen = cpu_to_le32((assocadj >> 8) | 22162306a36Sopenharmony_ci (assocadj & 255) << 8); 22262306a36Sopenharmony_ci atoken += 6; 22362306a36Sopenharmony_ci atoksize += 7; 22462306a36Sopenharmony_ci } else { 22562306a36Sopenharmony_ci atoken += 5; 22662306a36Sopenharmony_ci atoksize += 6; 22762306a36Sopenharmony_ci } 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci /* Process AAD data */ 23062306a36Sopenharmony_ci aadref = atoken; 23162306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 23262306a36Sopenharmony_ci atoken->packet_length = assocadj; 23362306a36Sopenharmony_ci atoken->stat = 0; 23462306a36Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 23562306a36Sopenharmony_ci atoken++; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci /* For CCM only, align AAD data towards hash engine */ 23862306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 23962306a36Sopenharmony_ci aadalign = (assocadj + 2) & 15; 24062306a36Sopenharmony_ci atoken->packet_length = assocadj && aadalign ? 24162306a36Sopenharmony_ci 16 - aadalign : 24262306a36Sopenharmony_ci 0; 24362306a36Sopenharmony_ci if (likely(cryptlen)) { 24462306a36Sopenharmony_ci atoken->stat = 0; 24562306a36Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 24662306a36Sopenharmony_ci } else { 24762306a36Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 24862306a36Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_LAST | 24962306a36Sopenharmony_ci EIP197_TOKEN_INS_TYPE_HASH; 25062306a36Sopenharmony_ci } 25162306a36Sopenharmony_ci } else { 25262306a36Sopenharmony_ci safexcel_aead_iv(ctx, iv, cdesc); 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci /* Process AAD data */ 25562306a36Sopenharmony_ci aadref = atoken; 25662306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 25762306a36Sopenharmony_ci atoken->packet_length = assocadj; 25862306a36Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 25962306a36Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_LAST | 26062306a36Sopenharmony_ci EIP197_TOKEN_INS_TYPE_HASH; 26162306a36Sopenharmony_ci } 26262306a36Sopenharmony_ci atoken++; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 26562306a36Sopenharmony_ci /* For ESP mode (and not GMAC), skip over the IV */ 26662306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 26762306a36Sopenharmony_ci atoken->packet_length = EIP197_AEAD_IPSEC_IV_SIZE; 26862306a36Sopenharmony_ci atoken->stat = 0; 26962306a36Sopenharmony_ci atoken->instructions = 0; 27062306a36Sopenharmony_ci atoken++; 27162306a36Sopenharmony_ci atoksize++; 27262306a36Sopenharmony_ci } else if (unlikely(ctx->alg == SAFEXCEL_CHACHA20 && 27362306a36Sopenharmony_ci direction == SAFEXCEL_DECRYPT)) { 27462306a36Sopenharmony_ci /* Poly-chacha decryption needs a dummy NOP here ... */ 27562306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 27662306a36Sopenharmony_ci atoken->packet_length = 16; /* According to Op Manual */ 27762306a36Sopenharmony_ci atoken->stat = 0; 27862306a36Sopenharmony_ci atoken->instructions = 0; 27962306a36Sopenharmony_ci atoken++; 28062306a36Sopenharmony_ci atoksize++; 28162306a36Sopenharmony_ci } 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci if (ctx->xcm) { 28462306a36Sopenharmony_ci /* For GCM and CCM, obtain enc(Y0) */ 28562306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES; 28662306a36Sopenharmony_ci atoken->packet_length = 0; 28762306a36Sopenharmony_ci atoken->stat = 0; 28862306a36Sopenharmony_ci atoken->instructions = AES_BLOCK_SIZE; 28962306a36Sopenharmony_ci atoken++; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 29262306a36Sopenharmony_ci atoken->packet_length = AES_BLOCK_SIZE; 29362306a36Sopenharmony_ci atoken->stat = 0; 29462306a36Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | 29562306a36Sopenharmony_ci EIP197_TOKEN_INS_TYPE_CRYPTO; 29662306a36Sopenharmony_ci atoken++; 29762306a36Sopenharmony_ci atoksize += 2; 29862306a36Sopenharmony_ci } 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci if (likely(cryptlen || ctx->alg == SAFEXCEL_CHACHA20)) { 30162306a36Sopenharmony_ci /* Fixup stat field for AAD direction instruction */ 30262306a36Sopenharmony_ci aadref->stat = 0; 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci /* Process crypto data */ 30562306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 30662306a36Sopenharmony_ci atoken->packet_length = cryptlen; 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci if (unlikely(ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) { 30962306a36Sopenharmony_ci /* Fixup instruction field for AAD dir instruction */ 31062306a36Sopenharmony_ci aadref->instructions = EIP197_TOKEN_INS_TYPE_HASH; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci /* Do not send to crypt engine in case of GMAC */ 31362306a36Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_LAST | 31462306a36Sopenharmony_ci EIP197_TOKEN_INS_TYPE_HASH | 31562306a36Sopenharmony_ci EIP197_TOKEN_INS_TYPE_OUTPUT; 31662306a36Sopenharmony_ci } else { 31762306a36Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_LAST | 31862306a36Sopenharmony_ci EIP197_TOKEN_INS_TYPE_CRYPTO | 31962306a36Sopenharmony_ci EIP197_TOKEN_INS_TYPE_HASH | 32062306a36Sopenharmony_ci EIP197_TOKEN_INS_TYPE_OUTPUT; 32162306a36Sopenharmony_ci } 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci cryptlen &= 15; 32462306a36Sopenharmony_ci if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM && cryptlen)) { 32562306a36Sopenharmony_ci atoken->stat = 0; 32662306a36Sopenharmony_ci /* For CCM only, pad crypto data to the hash engine */ 32762306a36Sopenharmony_ci atoken++; 32862306a36Sopenharmony_ci atoksize++; 32962306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 33062306a36Sopenharmony_ci atoken->packet_length = 16 - cryptlen; 33162306a36Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 33262306a36Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 33362306a36Sopenharmony_ci } else { 33462306a36Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 33562306a36Sopenharmony_ci } 33662306a36Sopenharmony_ci atoken++; 33762306a36Sopenharmony_ci atoksize++; 33862306a36Sopenharmony_ci } 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci if (direction == SAFEXCEL_ENCRYPT) { 34162306a36Sopenharmony_ci /* Append ICV */ 34262306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 34362306a36Sopenharmony_ci atoken->packet_length = digestsize; 34462306a36Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 34562306a36Sopenharmony_ci EIP197_TOKEN_STAT_LAST_PACKET; 34662306a36Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | 34762306a36Sopenharmony_ci EIP197_TOKEN_INS_INSERT_HASH_DIGEST; 34862306a36Sopenharmony_ci } else { 34962306a36Sopenharmony_ci /* Extract ICV */ 35062306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_RETRIEVE; 35162306a36Sopenharmony_ci atoken->packet_length = digestsize; 35262306a36Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 35362306a36Sopenharmony_ci EIP197_TOKEN_STAT_LAST_PACKET; 35462306a36Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST; 35562306a36Sopenharmony_ci atoken++; 35662306a36Sopenharmony_ci atoksize++; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci /* Verify ICV */ 35962306a36Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_VERIFY; 36062306a36Sopenharmony_ci atoken->packet_length = digestsize | 36162306a36Sopenharmony_ci EIP197_TOKEN_HASH_RESULT_VERIFY; 36262306a36Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 36362306a36Sopenharmony_ci EIP197_TOKEN_STAT_LAST_PACKET; 36462306a36Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT; 36562306a36Sopenharmony_ci } 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci /* Fixup length of the token in the command descriptor */ 36862306a36Sopenharmony_ci cdesc->additional_cdata_size = atoksize; 36962306a36Sopenharmony_ci} 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_cistatic int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm, 37262306a36Sopenharmony_ci const u8 *key, unsigned int len) 37362306a36Sopenharmony_ci{ 37462306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 37562306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 37662306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 37762306a36Sopenharmony_ci struct crypto_aes_ctx aes; 37862306a36Sopenharmony_ci int ret, i; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci ret = aes_expandkey(&aes, key, len); 38162306a36Sopenharmony_ci if (ret) 38262306a36Sopenharmony_ci return ret; 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 38562306a36Sopenharmony_ci for (i = 0; i < len / sizeof(u32); i++) { 38662306a36Sopenharmony_ci if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 38762306a36Sopenharmony_ci ctx->base.needs_inv = true; 38862306a36Sopenharmony_ci break; 38962306a36Sopenharmony_ci } 39062306a36Sopenharmony_ci } 39162306a36Sopenharmony_ci } 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci for (i = 0; i < len / sizeof(u32); i++) 39462306a36Sopenharmony_ci ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci ctx->key_len = len; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 39962306a36Sopenharmony_ci return 0; 40062306a36Sopenharmony_ci} 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_cistatic int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key, 40362306a36Sopenharmony_ci unsigned int len) 40462306a36Sopenharmony_ci{ 40562306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 40662306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 40762306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 40862306a36Sopenharmony_ci struct crypto_authenc_keys keys; 40962306a36Sopenharmony_ci struct crypto_aes_ctx aes; 41062306a36Sopenharmony_ci int err = -EINVAL, i; 41162306a36Sopenharmony_ci const char *alg; 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci if (unlikely(crypto_authenc_extractkeys(&keys, key, len))) 41462306a36Sopenharmony_ci goto badkey; 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { 41762306a36Sopenharmony_ci /* Must have at least space for the nonce here */ 41862306a36Sopenharmony_ci if (unlikely(keys.enckeylen < CTR_RFC3686_NONCE_SIZE)) 41962306a36Sopenharmony_ci goto badkey; 42062306a36Sopenharmony_ci /* last 4 bytes of key are the nonce! */ 42162306a36Sopenharmony_ci ctx->nonce = *(u32 *)(keys.enckey + keys.enckeylen - 42262306a36Sopenharmony_ci CTR_RFC3686_NONCE_SIZE); 42362306a36Sopenharmony_ci /* exclude the nonce here */ 42462306a36Sopenharmony_ci keys.enckeylen -= CTR_RFC3686_NONCE_SIZE; 42562306a36Sopenharmony_ci } 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci /* Encryption key */ 42862306a36Sopenharmony_ci switch (ctx->alg) { 42962306a36Sopenharmony_ci case SAFEXCEL_DES: 43062306a36Sopenharmony_ci err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen); 43162306a36Sopenharmony_ci if (unlikely(err)) 43262306a36Sopenharmony_ci goto badkey; 43362306a36Sopenharmony_ci break; 43462306a36Sopenharmony_ci case SAFEXCEL_3DES: 43562306a36Sopenharmony_ci err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen); 43662306a36Sopenharmony_ci if (unlikely(err)) 43762306a36Sopenharmony_ci goto badkey; 43862306a36Sopenharmony_ci break; 43962306a36Sopenharmony_ci case SAFEXCEL_AES: 44062306a36Sopenharmony_ci err = aes_expandkey(&aes, keys.enckey, keys.enckeylen); 44162306a36Sopenharmony_ci if (unlikely(err)) 44262306a36Sopenharmony_ci goto badkey; 44362306a36Sopenharmony_ci break; 44462306a36Sopenharmony_ci case SAFEXCEL_SM4: 44562306a36Sopenharmony_ci if (unlikely(keys.enckeylen != SM4_KEY_SIZE)) 44662306a36Sopenharmony_ci goto badkey; 44762306a36Sopenharmony_ci break; 44862306a36Sopenharmony_ci default: 44962306a36Sopenharmony_ci dev_err(priv->dev, "aead: unsupported cipher algorithm\n"); 45062306a36Sopenharmony_ci goto badkey; 45162306a36Sopenharmony_ci } 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 45462306a36Sopenharmony_ci for (i = 0; i < keys.enckeylen / sizeof(u32); i++) { 45562306a36Sopenharmony_ci if (le32_to_cpu(ctx->key[i]) != 45662306a36Sopenharmony_ci ((u32 *)keys.enckey)[i]) { 45762306a36Sopenharmony_ci ctx->base.needs_inv = true; 45862306a36Sopenharmony_ci break; 45962306a36Sopenharmony_ci } 46062306a36Sopenharmony_ci } 46162306a36Sopenharmony_ci } 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci /* Auth key */ 46462306a36Sopenharmony_ci switch (ctx->hash_alg) { 46562306a36Sopenharmony_ci case CONTEXT_CONTROL_CRYPTO_ALG_SHA1: 46662306a36Sopenharmony_ci alg = "safexcel-sha1"; 46762306a36Sopenharmony_ci break; 46862306a36Sopenharmony_ci case CONTEXT_CONTROL_CRYPTO_ALG_SHA224: 46962306a36Sopenharmony_ci alg = "safexcel-sha224"; 47062306a36Sopenharmony_ci break; 47162306a36Sopenharmony_ci case CONTEXT_CONTROL_CRYPTO_ALG_SHA256: 47262306a36Sopenharmony_ci alg = "safexcel-sha256"; 47362306a36Sopenharmony_ci break; 47462306a36Sopenharmony_ci case CONTEXT_CONTROL_CRYPTO_ALG_SHA384: 47562306a36Sopenharmony_ci alg = "safexcel-sha384"; 47662306a36Sopenharmony_ci break; 47762306a36Sopenharmony_ci case CONTEXT_CONTROL_CRYPTO_ALG_SHA512: 47862306a36Sopenharmony_ci alg = "safexcel-sha512"; 47962306a36Sopenharmony_ci break; 48062306a36Sopenharmony_ci case CONTEXT_CONTROL_CRYPTO_ALG_SM3: 48162306a36Sopenharmony_ci alg = "safexcel-sm3"; 48262306a36Sopenharmony_ci break; 48362306a36Sopenharmony_ci default: 48462306a36Sopenharmony_ci dev_err(priv->dev, "aead: unsupported hash algorithm\n"); 48562306a36Sopenharmony_ci goto badkey; 48662306a36Sopenharmony_ci } 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci if (safexcel_hmac_setkey(&ctx->base, keys.authkey, keys.authkeylen, 48962306a36Sopenharmony_ci alg, ctx->state_sz)) 49062306a36Sopenharmony_ci goto badkey; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci /* Now copy the keys into the context */ 49362306a36Sopenharmony_ci for (i = 0; i < keys.enckeylen / sizeof(u32); i++) 49462306a36Sopenharmony_ci ctx->key[i] = cpu_to_le32(((u32 *)keys.enckey)[i]); 49562306a36Sopenharmony_ci ctx->key_len = keys.enckeylen; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci memzero_explicit(&keys, sizeof(keys)); 49862306a36Sopenharmony_ci return 0; 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_cibadkey: 50162306a36Sopenharmony_ci memzero_explicit(&keys, sizeof(keys)); 50262306a36Sopenharmony_ci return err; 50362306a36Sopenharmony_ci} 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_cistatic int safexcel_context_control(struct safexcel_cipher_ctx *ctx, 50662306a36Sopenharmony_ci struct crypto_async_request *async, 50762306a36Sopenharmony_ci struct safexcel_cipher_req *sreq, 50862306a36Sopenharmony_ci struct safexcel_command_desc *cdesc) 50962306a36Sopenharmony_ci{ 51062306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 51162306a36Sopenharmony_ci int ctrl_size = ctx->key_len / sizeof(u32); 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci cdesc->control_data.control1 = ctx->mode; 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci if (ctx->aead) { 51662306a36Sopenharmony_ci /* Take in account the ipad+opad digests */ 51762306a36Sopenharmony_ci if (ctx->xcm) { 51862306a36Sopenharmony_ci ctrl_size += ctx->state_sz / sizeof(u32); 51962306a36Sopenharmony_ci cdesc->control_data.control0 = 52062306a36Sopenharmony_ci CONTEXT_CONTROL_KEY_EN | 52162306a36Sopenharmony_ci CONTEXT_CONTROL_DIGEST_XCM | 52262306a36Sopenharmony_ci ctx->hash_alg | 52362306a36Sopenharmony_ci CONTEXT_CONTROL_SIZE(ctrl_size); 52462306a36Sopenharmony_ci } else if (ctx->alg == SAFEXCEL_CHACHA20) { 52562306a36Sopenharmony_ci /* Chacha20-Poly1305 */ 52662306a36Sopenharmony_ci cdesc->control_data.control0 = 52762306a36Sopenharmony_ci CONTEXT_CONTROL_KEY_EN | 52862306a36Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 | 52962306a36Sopenharmony_ci (sreq->direction == SAFEXCEL_ENCRYPT ? 53062306a36Sopenharmony_ci CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT : 53162306a36Sopenharmony_ci CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN) | 53262306a36Sopenharmony_ci ctx->hash_alg | 53362306a36Sopenharmony_ci CONTEXT_CONTROL_SIZE(ctrl_size); 53462306a36Sopenharmony_ci return 0; 53562306a36Sopenharmony_ci } else { 53662306a36Sopenharmony_ci ctrl_size += ctx->state_sz / sizeof(u32) * 2; 53762306a36Sopenharmony_ci cdesc->control_data.control0 = 53862306a36Sopenharmony_ci CONTEXT_CONTROL_KEY_EN | 53962306a36Sopenharmony_ci CONTEXT_CONTROL_DIGEST_HMAC | 54062306a36Sopenharmony_ci ctx->hash_alg | 54162306a36Sopenharmony_ci CONTEXT_CONTROL_SIZE(ctrl_size); 54262306a36Sopenharmony_ci } 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci if (sreq->direction == SAFEXCEL_ENCRYPT && 54562306a36Sopenharmony_ci (ctx->xcm == EIP197_XCM_MODE_CCM || 54662306a36Sopenharmony_ci ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) 54762306a36Sopenharmony_ci cdesc->control_data.control0 |= 54862306a36Sopenharmony_ci CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT; 54962306a36Sopenharmony_ci else if (sreq->direction == SAFEXCEL_ENCRYPT) 55062306a36Sopenharmony_ci cdesc->control_data.control0 |= 55162306a36Sopenharmony_ci CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT; 55262306a36Sopenharmony_ci else if (ctx->xcm == EIP197_XCM_MODE_CCM) 55362306a36Sopenharmony_ci cdesc->control_data.control0 |= 55462306a36Sopenharmony_ci CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN; 55562306a36Sopenharmony_ci else 55662306a36Sopenharmony_ci cdesc->control_data.control0 |= 55762306a36Sopenharmony_ci CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN; 55862306a36Sopenharmony_ci } else { 55962306a36Sopenharmony_ci if (sreq->direction == SAFEXCEL_ENCRYPT) 56062306a36Sopenharmony_ci cdesc->control_data.control0 = 56162306a36Sopenharmony_ci CONTEXT_CONTROL_TYPE_CRYPTO_OUT | 56262306a36Sopenharmony_ci CONTEXT_CONTROL_KEY_EN | 56362306a36Sopenharmony_ci CONTEXT_CONTROL_SIZE(ctrl_size); 56462306a36Sopenharmony_ci else 56562306a36Sopenharmony_ci cdesc->control_data.control0 = 56662306a36Sopenharmony_ci CONTEXT_CONTROL_TYPE_CRYPTO_IN | 56762306a36Sopenharmony_ci CONTEXT_CONTROL_KEY_EN | 56862306a36Sopenharmony_ci CONTEXT_CONTROL_SIZE(ctrl_size); 56962306a36Sopenharmony_ci } 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci if (ctx->alg == SAFEXCEL_DES) { 57262306a36Sopenharmony_ci cdesc->control_data.control0 |= 57362306a36Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_DES; 57462306a36Sopenharmony_ci } else if (ctx->alg == SAFEXCEL_3DES) { 57562306a36Sopenharmony_ci cdesc->control_data.control0 |= 57662306a36Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_3DES; 57762306a36Sopenharmony_ci } else if (ctx->alg == SAFEXCEL_AES) { 57862306a36Sopenharmony_ci switch (ctx->key_len >> ctx->xts) { 57962306a36Sopenharmony_ci case AES_KEYSIZE_128: 58062306a36Sopenharmony_ci cdesc->control_data.control0 |= 58162306a36Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_AES128; 58262306a36Sopenharmony_ci break; 58362306a36Sopenharmony_ci case AES_KEYSIZE_192: 58462306a36Sopenharmony_ci cdesc->control_data.control0 |= 58562306a36Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_AES192; 58662306a36Sopenharmony_ci break; 58762306a36Sopenharmony_ci case AES_KEYSIZE_256: 58862306a36Sopenharmony_ci cdesc->control_data.control0 |= 58962306a36Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_AES256; 59062306a36Sopenharmony_ci break; 59162306a36Sopenharmony_ci default: 59262306a36Sopenharmony_ci dev_err(priv->dev, "aes keysize not supported: %u\n", 59362306a36Sopenharmony_ci ctx->key_len >> ctx->xts); 59462306a36Sopenharmony_ci return -EINVAL; 59562306a36Sopenharmony_ci } 59662306a36Sopenharmony_ci } else if (ctx->alg == SAFEXCEL_CHACHA20) { 59762306a36Sopenharmony_ci cdesc->control_data.control0 |= 59862306a36Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20; 59962306a36Sopenharmony_ci } else if (ctx->alg == SAFEXCEL_SM4) { 60062306a36Sopenharmony_ci cdesc->control_data.control0 |= 60162306a36Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_SM4; 60262306a36Sopenharmony_ci } 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci return 0; 60562306a36Sopenharmony_ci} 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_cistatic int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring, 60862306a36Sopenharmony_ci struct crypto_async_request *async, 60962306a36Sopenharmony_ci struct scatterlist *src, 61062306a36Sopenharmony_ci struct scatterlist *dst, 61162306a36Sopenharmony_ci unsigned int cryptlen, 61262306a36Sopenharmony_ci struct safexcel_cipher_req *sreq, 61362306a36Sopenharmony_ci bool *should_complete, int *ret) 61462306a36Sopenharmony_ci{ 61562306a36Sopenharmony_ci struct skcipher_request *areq = skcipher_request_cast(async); 61662306a36Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq); 61762306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(skcipher); 61862306a36Sopenharmony_ci struct safexcel_result_desc *rdesc; 61962306a36Sopenharmony_ci int ndesc = 0; 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci *ret = 0; 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci if (unlikely(!sreq->rdescs)) 62462306a36Sopenharmony_ci return 0; 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci while (sreq->rdescs--) { 62762306a36Sopenharmony_ci rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr); 62862306a36Sopenharmony_ci if (IS_ERR(rdesc)) { 62962306a36Sopenharmony_ci dev_err(priv->dev, 63062306a36Sopenharmony_ci "cipher: result: could not retrieve the result descriptor\n"); 63162306a36Sopenharmony_ci *ret = PTR_ERR(rdesc); 63262306a36Sopenharmony_ci break; 63362306a36Sopenharmony_ci } 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci if (likely(!*ret)) 63662306a36Sopenharmony_ci *ret = safexcel_rdesc_check_errors(priv, rdesc); 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci ndesc++; 63962306a36Sopenharmony_ci } 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci safexcel_complete(priv, ring); 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci if (src == dst) { 64462306a36Sopenharmony_ci if (sreq->nr_src > 0) 64562306a36Sopenharmony_ci dma_unmap_sg(priv->dev, src, sreq->nr_src, 64662306a36Sopenharmony_ci DMA_BIDIRECTIONAL); 64762306a36Sopenharmony_ci } else { 64862306a36Sopenharmony_ci if (sreq->nr_src > 0) 64962306a36Sopenharmony_ci dma_unmap_sg(priv->dev, src, sreq->nr_src, 65062306a36Sopenharmony_ci DMA_TO_DEVICE); 65162306a36Sopenharmony_ci if (sreq->nr_dst > 0) 65262306a36Sopenharmony_ci dma_unmap_sg(priv->dev, dst, sreq->nr_dst, 65362306a36Sopenharmony_ci DMA_FROM_DEVICE); 65462306a36Sopenharmony_ci } 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci /* 65762306a36Sopenharmony_ci * Update IV in req from last crypto output word for CBC modes 65862306a36Sopenharmony_ci */ 65962306a36Sopenharmony_ci if ((!ctx->aead) && (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) && 66062306a36Sopenharmony_ci (sreq->direction == SAFEXCEL_ENCRYPT)) { 66162306a36Sopenharmony_ci /* For encrypt take the last output word */ 66262306a36Sopenharmony_ci sg_pcopy_to_buffer(dst, sreq->nr_dst, areq->iv, 66362306a36Sopenharmony_ci crypto_skcipher_ivsize(skcipher), 66462306a36Sopenharmony_ci (cryptlen - 66562306a36Sopenharmony_ci crypto_skcipher_ivsize(skcipher))); 66662306a36Sopenharmony_ci } 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci *should_complete = true; 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci return ndesc; 67162306a36Sopenharmony_ci} 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_cistatic int safexcel_send_req(struct crypto_async_request *base, int ring, 67462306a36Sopenharmony_ci struct safexcel_cipher_req *sreq, 67562306a36Sopenharmony_ci struct scatterlist *src, struct scatterlist *dst, 67662306a36Sopenharmony_ci unsigned int cryptlen, unsigned int assoclen, 67762306a36Sopenharmony_ci unsigned int digestsize, u8 *iv, int *commands, 67862306a36Sopenharmony_ci int *results) 67962306a36Sopenharmony_ci{ 68062306a36Sopenharmony_ci struct skcipher_request *areq = skcipher_request_cast(base); 68162306a36Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq); 68262306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 68362306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 68462306a36Sopenharmony_ci struct safexcel_command_desc *cdesc; 68562306a36Sopenharmony_ci struct safexcel_command_desc *first_cdesc = NULL; 68662306a36Sopenharmony_ci struct safexcel_result_desc *rdesc, *first_rdesc = NULL; 68762306a36Sopenharmony_ci struct scatterlist *sg; 68862306a36Sopenharmony_ci unsigned int totlen; 68962306a36Sopenharmony_ci unsigned int totlen_src = cryptlen + assoclen; 69062306a36Sopenharmony_ci unsigned int totlen_dst = totlen_src; 69162306a36Sopenharmony_ci struct safexcel_token *atoken; 69262306a36Sopenharmony_ci int n_cdesc = 0, n_rdesc = 0; 69362306a36Sopenharmony_ci int queued, i, ret = 0; 69462306a36Sopenharmony_ci bool first = true; 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_ci sreq->nr_src = sg_nents_for_len(src, totlen_src); 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci if (ctx->aead) { 69962306a36Sopenharmony_ci /* 70062306a36Sopenharmony_ci * AEAD has auth tag appended to output for encrypt and 70162306a36Sopenharmony_ci * removed from the output for decrypt! 70262306a36Sopenharmony_ci */ 70362306a36Sopenharmony_ci if (sreq->direction == SAFEXCEL_DECRYPT) 70462306a36Sopenharmony_ci totlen_dst -= digestsize; 70562306a36Sopenharmony_ci else 70662306a36Sopenharmony_ci totlen_dst += digestsize; 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci memcpy(ctx->base.ctxr->data + ctx->key_len / sizeof(u32), 70962306a36Sopenharmony_ci &ctx->base.ipad, ctx->state_sz); 71062306a36Sopenharmony_ci if (!ctx->xcm) 71162306a36Sopenharmony_ci memcpy(ctx->base.ctxr->data + (ctx->key_len + 71262306a36Sopenharmony_ci ctx->state_sz) / sizeof(u32), &ctx->base.opad, 71362306a36Sopenharmony_ci ctx->state_sz); 71462306a36Sopenharmony_ci } else if ((ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) && 71562306a36Sopenharmony_ci (sreq->direction == SAFEXCEL_DECRYPT)) { 71662306a36Sopenharmony_ci /* 71762306a36Sopenharmony_ci * Save IV from last crypto input word for CBC modes in decrypt 71862306a36Sopenharmony_ci * direction. Need to do this first in case of inplace operation 71962306a36Sopenharmony_ci * as it will be overwritten. 72062306a36Sopenharmony_ci */ 72162306a36Sopenharmony_ci sg_pcopy_to_buffer(src, sreq->nr_src, areq->iv, 72262306a36Sopenharmony_ci crypto_skcipher_ivsize(skcipher), 72362306a36Sopenharmony_ci (totlen_src - 72462306a36Sopenharmony_ci crypto_skcipher_ivsize(skcipher))); 72562306a36Sopenharmony_ci } 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_ci sreq->nr_dst = sg_nents_for_len(dst, totlen_dst); 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci /* 73062306a36Sopenharmony_ci * Remember actual input length, source buffer length may be 73162306a36Sopenharmony_ci * updated in case of inline operation below. 73262306a36Sopenharmony_ci */ 73362306a36Sopenharmony_ci totlen = totlen_src; 73462306a36Sopenharmony_ci queued = totlen_src; 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci if (src == dst) { 73762306a36Sopenharmony_ci sreq->nr_src = max(sreq->nr_src, sreq->nr_dst); 73862306a36Sopenharmony_ci sreq->nr_dst = sreq->nr_src; 73962306a36Sopenharmony_ci if (unlikely((totlen_src || totlen_dst) && 74062306a36Sopenharmony_ci (sreq->nr_src <= 0))) { 74162306a36Sopenharmony_ci dev_err(priv->dev, "In-place buffer not large enough (need %d bytes)!", 74262306a36Sopenharmony_ci max(totlen_src, totlen_dst)); 74362306a36Sopenharmony_ci return -EINVAL; 74462306a36Sopenharmony_ci } 74562306a36Sopenharmony_ci if (sreq->nr_src > 0 && 74662306a36Sopenharmony_ci !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL)) 74762306a36Sopenharmony_ci return -EIO; 74862306a36Sopenharmony_ci } else { 74962306a36Sopenharmony_ci if (unlikely(totlen_src && (sreq->nr_src <= 0))) { 75062306a36Sopenharmony_ci dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!", 75162306a36Sopenharmony_ci totlen_src); 75262306a36Sopenharmony_ci return -EINVAL; 75362306a36Sopenharmony_ci } 75462306a36Sopenharmony_ci 75562306a36Sopenharmony_ci if (sreq->nr_src > 0 && 75662306a36Sopenharmony_ci !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE)) 75762306a36Sopenharmony_ci return -EIO; 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) { 76062306a36Sopenharmony_ci dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!", 76162306a36Sopenharmony_ci totlen_dst); 76262306a36Sopenharmony_ci ret = -EINVAL; 76362306a36Sopenharmony_ci goto unmap; 76462306a36Sopenharmony_ci } 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci if (sreq->nr_dst > 0 && 76762306a36Sopenharmony_ci !dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE)) { 76862306a36Sopenharmony_ci ret = -EIO; 76962306a36Sopenharmony_ci goto unmap; 77062306a36Sopenharmony_ci } 77162306a36Sopenharmony_ci } 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_ci memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len); 77462306a36Sopenharmony_ci 77562306a36Sopenharmony_ci if (!totlen) { 77662306a36Sopenharmony_ci /* 77762306a36Sopenharmony_ci * The EIP97 cannot deal with zero length input packets! 77862306a36Sopenharmony_ci * So stuff a dummy command descriptor indicating a 1 byte 77962306a36Sopenharmony_ci * (dummy) input packet, using the context record as source. 78062306a36Sopenharmony_ci */ 78162306a36Sopenharmony_ci first_cdesc = safexcel_add_cdesc(priv, ring, 78262306a36Sopenharmony_ci 1, 1, ctx->base.ctxr_dma, 78362306a36Sopenharmony_ci 1, 1, ctx->base.ctxr_dma, 78462306a36Sopenharmony_ci &atoken); 78562306a36Sopenharmony_ci if (IS_ERR(first_cdesc)) { 78662306a36Sopenharmony_ci /* No space left in the command descriptor ring */ 78762306a36Sopenharmony_ci ret = PTR_ERR(first_cdesc); 78862306a36Sopenharmony_ci goto cdesc_rollback; 78962306a36Sopenharmony_ci } 79062306a36Sopenharmony_ci n_cdesc = 1; 79162306a36Sopenharmony_ci goto skip_cdesc; 79262306a36Sopenharmony_ci } 79362306a36Sopenharmony_ci 79462306a36Sopenharmony_ci /* command descriptors */ 79562306a36Sopenharmony_ci for_each_sg(src, sg, sreq->nr_src, i) { 79662306a36Sopenharmony_ci int len = sg_dma_len(sg); 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci /* Do not overflow the request */ 79962306a36Sopenharmony_ci if (queued < len) 80062306a36Sopenharmony_ci len = queued; 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_ci cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc, 80362306a36Sopenharmony_ci !(queued - len), 80462306a36Sopenharmony_ci sg_dma_address(sg), len, totlen, 80562306a36Sopenharmony_ci ctx->base.ctxr_dma, &atoken); 80662306a36Sopenharmony_ci if (IS_ERR(cdesc)) { 80762306a36Sopenharmony_ci /* No space left in the command descriptor ring */ 80862306a36Sopenharmony_ci ret = PTR_ERR(cdesc); 80962306a36Sopenharmony_ci goto cdesc_rollback; 81062306a36Sopenharmony_ci } 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_ci if (!n_cdesc) 81362306a36Sopenharmony_ci first_cdesc = cdesc; 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ci n_cdesc++; 81662306a36Sopenharmony_ci queued -= len; 81762306a36Sopenharmony_ci if (!queued) 81862306a36Sopenharmony_ci break; 81962306a36Sopenharmony_ci } 82062306a36Sopenharmony_ciskip_cdesc: 82162306a36Sopenharmony_ci /* Add context control words and token to first command descriptor */ 82262306a36Sopenharmony_ci safexcel_context_control(ctx, base, sreq, first_cdesc); 82362306a36Sopenharmony_ci if (ctx->aead) 82462306a36Sopenharmony_ci safexcel_aead_token(ctx, iv, first_cdesc, atoken, 82562306a36Sopenharmony_ci sreq->direction, cryptlen, 82662306a36Sopenharmony_ci assoclen, digestsize); 82762306a36Sopenharmony_ci else 82862306a36Sopenharmony_ci safexcel_skcipher_token(ctx, iv, first_cdesc, atoken, 82962306a36Sopenharmony_ci cryptlen); 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_ci /* result descriptors */ 83262306a36Sopenharmony_ci for_each_sg(dst, sg, sreq->nr_dst, i) { 83362306a36Sopenharmony_ci bool last = (i == sreq->nr_dst - 1); 83462306a36Sopenharmony_ci u32 len = sg_dma_len(sg); 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci /* only allow the part of the buffer we know we need */ 83762306a36Sopenharmony_ci if (len > totlen_dst) 83862306a36Sopenharmony_ci len = totlen_dst; 83962306a36Sopenharmony_ci if (unlikely(!len)) 84062306a36Sopenharmony_ci break; 84162306a36Sopenharmony_ci totlen_dst -= len; 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_ci /* skip over AAD space in buffer - not written */ 84462306a36Sopenharmony_ci if (assoclen) { 84562306a36Sopenharmony_ci if (assoclen >= len) { 84662306a36Sopenharmony_ci assoclen -= len; 84762306a36Sopenharmony_ci continue; 84862306a36Sopenharmony_ci } 84962306a36Sopenharmony_ci rdesc = safexcel_add_rdesc(priv, ring, first, last, 85062306a36Sopenharmony_ci sg_dma_address(sg) + 85162306a36Sopenharmony_ci assoclen, 85262306a36Sopenharmony_ci len - assoclen); 85362306a36Sopenharmony_ci assoclen = 0; 85462306a36Sopenharmony_ci } else { 85562306a36Sopenharmony_ci rdesc = safexcel_add_rdesc(priv, ring, first, last, 85662306a36Sopenharmony_ci sg_dma_address(sg), 85762306a36Sopenharmony_ci len); 85862306a36Sopenharmony_ci } 85962306a36Sopenharmony_ci if (IS_ERR(rdesc)) { 86062306a36Sopenharmony_ci /* No space left in the result descriptor ring */ 86162306a36Sopenharmony_ci ret = PTR_ERR(rdesc); 86262306a36Sopenharmony_ci goto rdesc_rollback; 86362306a36Sopenharmony_ci } 86462306a36Sopenharmony_ci if (first) { 86562306a36Sopenharmony_ci first_rdesc = rdesc; 86662306a36Sopenharmony_ci first = false; 86762306a36Sopenharmony_ci } 86862306a36Sopenharmony_ci n_rdesc++; 86962306a36Sopenharmony_ci } 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci if (unlikely(first)) { 87262306a36Sopenharmony_ci /* 87362306a36Sopenharmony_ci * Special case: AEAD decrypt with only AAD data. 87462306a36Sopenharmony_ci * In this case there is NO output data from the engine, 87562306a36Sopenharmony_ci * but the engine still needs a result descriptor! 87662306a36Sopenharmony_ci * Create a dummy one just for catching the result token. 87762306a36Sopenharmony_ci */ 87862306a36Sopenharmony_ci rdesc = safexcel_add_rdesc(priv, ring, true, true, 0, 0); 87962306a36Sopenharmony_ci if (IS_ERR(rdesc)) { 88062306a36Sopenharmony_ci /* No space left in the result descriptor ring */ 88162306a36Sopenharmony_ci ret = PTR_ERR(rdesc); 88262306a36Sopenharmony_ci goto rdesc_rollback; 88362306a36Sopenharmony_ci } 88462306a36Sopenharmony_ci first_rdesc = rdesc; 88562306a36Sopenharmony_ci n_rdesc = 1; 88662306a36Sopenharmony_ci } 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_ci safexcel_rdr_req_set(priv, ring, first_rdesc, base); 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_ci *commands = n_cdesc; 89162306a36Sopenharmony_ci *results = n_rdesc; 89262306a36Sopenharmony_ci return 0; 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_cirdesc_rollback: 89562306a36Sopenharmony_ci for (i = 0; i < n_rdesc; i++) 89662306a36Sopenharmony_ci safexcel_ring_rollback_wptr(priv, &priv->ring[ring].rdr); 89762306a36Sopenharmony_cicdesc_rollback: 89862306a36Sopenharmony_ci for (i = 0; i < n_cdesc; i++) 89962306a36Sopenharmony_ci safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr); 90062306a36Sopenharmony_ciunmap: 90162306a36Sopenharmony_ci if (src == dst) { 90262306a36Sopenharmony_ci if (sreq->nr_src > 0) 90362306a36Sopenharmony_ci dma_unmap_sg(priv->dev, src, sreq->nr_src, 90462306a36Sopenharmony_ci DMA_BIDIRECTIONAL); 90562306a36Sopenharmony_ci } else { 90662306a36Sopenharmony_ci if (sreq->nr_src > 0) 90762306a36Sopenharmony_ci dma_unmap_sg(priv->dev, src, sreq->nr_src, 90862306a36Sopenharmony_ci DMA_TO_DEVICE); 90962306a36Sopenharmony_ci if (sreq->nr_dst > 0) 91062306a36Sopenharmony_ci dma_unmap_sg(priv->dev, dst, sreq->nr_dst, 91162306a36Sopenharmony_ci DMA_FROM_DEVICE); 91262306a36Sopenharmony_ci } 91362306a36Sopenharmony_ci 91462306a36Sopenharmony_ci return ret; 91562306a36Sopenharmony_ci} 91662306a36Sopenharmony_ci 91762306a36Sopenharmony_cistatic int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv, 91862306a36Sopenharmony_ci int ring, 91962306a36Sopenharmony_ci struct crypto_async_request *base, 92062306a36Sopenharmony_ci struct safexcel_cipher_req *sreq, 92162306a36Sopenharmony_ci bool *should_complete, int *ret) 92262306a36Sopenharmony_ci{ 92362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 92462306a36Sopenharmony_ci struct safexcel_result_desc *rdesc; 92562306a36Sopenharmony_ci int ndesc = 0, enq_ret; 92662306a36Sopenharmony_ci 92762306a36Sopenharmony_ci *ret = 0; 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_ci if (unlikely(!sreq->rdescs)) 93062306a36Sopenharmony_ci return 0; 93162306a36Sopenharmony_ci 93262306a36Sopenharmony_ci while (sreq->rdescs--) { 93362306a36Sopenharmony_ci rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr); 93462306a36Sopenharmony_ci if (IS_ERR(rdesc)) { 93562306a36Sopenharmony_ci dev_err(priv->dev, 93662306a36Sopenharmony_ci "cipher: invalidate: could not retrieve the result descriptor\n"); 93762306a36Sopenharmony_ci *ret = PTR_ERR(rdesc); 93862306a36Sopenharmony_ci break; 93962306a36Sopenharmony_ci } 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci if (likely(!*ret)) 94262306a36Sopenharmony_ci *ret = safexcel_rdesc_check_errors(priv, rdesc); 94362306a36Sopenharmony_ci 94462306a36Sopenharmony_ci ndesc++; 94562306a36Sopenharmony_ci } 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_ci safexcel_complete(priv, ring); 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_ci if (ctx->base.exit_inv) { 95062306a36Sopenharmony_ci dma_pool_free(priv->context_pool, ctx->base.ctxr, 95162306a36Sopenharmony_ci ctx->base.ctxr_dma); 95262306a36Sopenharmony_ci 95362306a36Sopenharmony_ci *should_complete = true; 95462306a36Sopenharmony_ci 95562306a36Sopenharmony_ci return ndesc; 95662306a36Sopenharmony_ci } 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci ring = safexcel_select_ring(priv); 95962306a36Sopenharmony_ci ctx->base.ring = ring; 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_ci spin_lock_bh(&priv->ring[ring].queue_lock); 96262306a36Sopenharmony_ci enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, base); 96362306a36Sopenharmony_ci spin_unlock_bh(&priv->ring[ring].queue_lock); 96462306a36Sopenharmony_ci 96562306a36Sopenharmony_ci if (enq_ret != -EINPROGRESS) 96662306a36Sopenharmony_ci *ret = enq_ret; 96762306a36Sopenharmony_ci 96862306a36Sopenharmony_ci queue_work(priv->ring[ring].workqueue, 96962306a36Sopenharmony_ci &priv->ring[ring].work_data.work); 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci *should_complete = false; 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci return ndesc; 97462306a36Sopenharmony_ci} 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_cistatic int safexcel_skcipher_handle_result(struct safexcel_crypto_priv *priv, 97762306a36Sopenharmony_ci int ring, 97862306a36Sopenharmony_ci struct crypto_async_request *async, 97962306a36Sopenharmony_ci bool *should_complete, int *ret) 98062306a36Sopenharmony_ci{ 98162306a36Sopenharmony_ci struct skcipher_request *req = skcipher_request_cast(async); 98262306a36Sopenharmony_ci struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 98362306a36Sopenharmony_ci int err; 98462306a36Sopenharmony_ci 98562306a36Sopenharmony_ci if (sreq->needs_inv) { 98662306a36Sopenharmony_ci sreq->needs_inv = false; 98762306a36Sopenharmony_ci err = safexcel_handle_inv_result(priv, ring, async, sreq, 98862306a36Sopenharmony_ci should_complete, ret); 98962306a36Sopenharmony_ci } else { 99062306a36Sopenharmony_ci err = safexcel_handle_req_result(priv, ring, async, req->src, 99162306a36Sopenharmony_ci req->dst, req->cryptlen, sreq, 99262306a36Sopenharmony_ci should_complete, ret); 99362306a36Sopenharmony_ci } 99462306a36Sopenharmony_ci 99562306a36Sopenharmony_ci return err; 99662306a36Sopenharmony_ci} 99762306a36Sopenharmony_ci 99862306a36Sopenharmony_cistatic int safexcel_aead_handle_result(struct safexcel_crypto_priv *priv, 99962306a36Sopenharmony_ci int ring, 100062306a36Sopenharmony_ci struct crypto_async_request *async, 100162306a36Sopenharmony_ci bool *should_complete, int *ret) 100262306a36Sopenharmony_ci{ 100362306a36Sopenharmony_ci struct aead_request *req = aead_request_cast(async); 100462306a36Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 100562306a36Sopenharmony_ci struct safexcel_cipher_req *sreq = aead_request_ctx(req); 100662306a36Sopenharmony_ci int err; 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_ci if (sreq->needs_inv) { 100962306a36Sopenharmony_ci sreq->needs_inv = false; 101062306a36Sopenharmony_ci err = safexcel_handle_inv_result(priv, ring, async, sreq, 101162306a36Sopenharmony_ci should_complete, ret); 101262306a36Sopenharmony_ci } else { 101362306a36Sopenharmony_ci err = safexcel_handle_req_result(priv, ring, async, req->src, 101462306a36Sopenharmony_ci req->dst, 101562306a36Sopenharmony_ci req->cryptlen + crypto_aead_authsize(tfm), 101662306a36Sopenharmony_ci sreq, should_complete, ret); 101762306a36Sopenharmony_ci } 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_ci return err; 102062306a36Sopenharmony_ci} 102162306a36Sopenharmony_ci 102262306a36Sopenharmony_cistatic int safexcel_cipher_send_inv(struct crypto_async_request *base, 102362306a36Sopenharmony_ci int ring, int *commands, int *results) 102462306a36Sopenharmony_ci{ 102562306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 102662306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 102762306a36Sopenharmony_ci int ret; 102862306a36Sopenharmony_ci 102962306a36Sopenharmony_ci ret = safexcel_invalidate_cache(base, priv, ctx->base.ctxr_dma, ring); 103062306a36Sopenharmony_ci if (unlikely(ret)) 103162306a36Sopenharmony_ci return ret; 103262306a36Sopenharmony_ci 103362306a36Sopenharmony_ci *commands = 1; 103462306a36Sopenharmony_ci *results = 1; 103562306a36Sopenharmony_ci 103662306a36Sopenharmony_ci return 0; 103762306a36Sopenharmony_ci} 103862306a36Sopenharmony_ci 103962306a36Sopenharmony_cistatic int safexcel_skcipher_send(struct crypto_async_request *async, int ring, 104062306a36Sopenharmony_ci int *commands, int *results) 104162306a36Sopenharmony_ci{ 104262306a36Sopenharmony_ci struct skcipher_request *req = skcipher_request_cast(async); 104362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 104462306a36Sopenharmony_ci struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 104562306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 104662306a36Sopenharmony_ci int ret; 104762306a36Sopenharmony_ci 104862306a36Sopenharmony_ci BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv); 104962306a36Sopenharmony_ci 105062306a36Sopenharmony_ci if (sreq->needs_inv) { 105162306a36Sopenharmony_ci ret = safexcel_cipher_send_inv(async, ring, commands, results); 105262306a36Sopenharmony_ci } else { 105362306a36Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 105462306a36Sopenharmony_ci u8 input_iv[AES_BLOCK_SIZE]; 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_ci /* 105762306a36Sopenharmony_ci * Save input IV in case of CBC decrypt mode 105862306a36Sopenharmony_ci * Will be overwritten with output IV prior to use! 105962306a36Sopenharmony_ci */ 106062306a36Sopenharmony_ci memcpy(input_iv, req->iv, crypto_skcipher_ivsize(skcipher)); 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_ci ret = safexcel_send_req(async, ring, sreq, req->src, 106362306a36Sopenharmony_ci req->dst, req->cryptlen, 0, 0, input_iv, 106462306a36Sopenharmony_ci commands, results); 106562306a36Sopenharmony_ci } 106662306a36Sopenharmony_ci 106762306a36Sopenharmony_ci sreq->rdescs = *results; 106862306a36Sopenharmony_ci return ret; 106962306a36Sopenharmony_ci} 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_cistatic int safexcel_aead_send(struct crypto_async_request *async, int ring, 107262306a36Sopenharmony_ci int *commands, int *results) 107362306a36Sopenharmony_ci{ 107462306a36Sopenharmony_ci struct aead_request *req = aead_request_cast(async); 107562306a36Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 107662306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 107762306a36Sopenharmony_ci struct safexcel_cipher_req *sreq = aead_request_ctx(req); 107862306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 107962306a36Sopenharmony_ci int ret; 108062306a36Sopenharmony_ci 108162306a36Sopenharmony_ci BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv); 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_ci if (sreq->needs_inv) 108462306a36Sopenharmony_ci ret = safexcel_cipher_send_inv(async, ring, commands, results); 108562306a36Sopenharmony_ci else 108662306a36Sopenharmony_ci ret = safexcel_send_req(async, ring, sreq, req->src, req->dst, 108762306a36Sopenharmony_ci req->cryptlen, req->assoclen, 108862306a36Sopenharmony_ci crypto_aead_authsize(tfm), req->iv, 108962306a36Sopenharmony_ci commands, results); 109062306a36Sopenharmony_ci sreq->rdescs = *results; 109162306a36Sopenharmony_ci return ret; 109262306a36Sopenharmony_ci} 109362306a36Sopenharmony_ci 109462306a36Sopenharmony_cistatic int safexcel_cipher_exit_inv(struct crypto_tfm *tfm, 109562306a36Sopenharmony_ci struct crypto_async_request *base, 109662306a36Sopenharmony_ci struct safexcel_cipher_req *sreq, 109762306a36Sopenharmony_ci struct crypto_wait *result) 109862306a36Sopenharmony_ci{ 109962306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 110062306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 110162306a36Sopenharmony_ci int ring = ctx->base.ring; 110262306a36Sopenharmony_ci int err; 110362306a36Sopenharmony_ci 110462306a36Sopenharmony_ci ctx = crypto_tfm_ctx(base->tfm); 110562306a36Sopenharmony_ci ctx->base.exit_inv = true; 110662306a36Sopenharmony_ci sreq->needs_inv = true; 110762306a36Sopenharmony_ci 110862306a36Sopenharmony_ci spin_lock_bh(&priv->ring[ring].queue_lock); 110962306a36Sopenharmony_ci crypto_enqueue_request(&priv->ring[ring].queue, base); 111062306a36Sopenharmony_ci spin_unlock_bh(&priv->ring[ring].queue_lock); 111162306a36Sopenharmony_ci 111262306a36Sopenharmony_ci queue_work(priv->ring[ring].workqueue, 111362306a36Sopenharmony_ci &priv->ring[ring].work_data.work); 111462306a36Sopenharmony_ci 111562306a36Sopenharmony_ci err = crypto_wait_req(-EINPROGRESS, result); 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_ci if (err) { 111862306a36Sopenharmony_ci dev_warn(priv->dev, 111962306a36Sopenharmony_ci "cipher: sync: invalidate: completion error %d\n", 112062306a36Sopenharmony_ci err); 112162306a36Sopenharmony_ci return err; 112262306a36Sopenharmony_ci } 112362306a36Sopenharmony_ci 112462306a36Sopenharmony_ci return 0; 112562306a36Sopenharmony_ci} 112662306a36Sopenharmony_ci 112762306a36Sopenharmony_cistatic int safexcel_skcipher_exit_inv(struct crypto_tfm *tfm) 112862306a36Sopenharmony_ci{ 112962306a36Sopenharmony_ci EIP197_REQUEST_ON_STACK(req, skcipher, EIP197_SKCIPHER_REQ_SIZE); 113062306a36Sopenharmony_ci struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 113162306a36Sopenharmony_ci DECLARE_CRYPTO_WAIT(result); 113262306a36Sopenharmony_ci 113362306a36Sopenharmony_ci memset(req, 0, sizeof(struct skcipher_request)); 113462306a36Sopenharmony_ci 113562306a36Sopenharmony_ci skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 113662306a36Sopenharmony_ci crypto_req_done, &result); 113762306a36Sopenharmony_ci skcipher_request_set_tfm(req, __crypto_skcipher_cast(tfm)); 113862306a36Sopenharmony_ci 113962306a36Sopenharmony_ci return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result); 114062306a36Sopenharmony_ci} 114162306a36Sopenharmony_ci 114262306a36Sopenharmony_cistatic int safexcel_aead_exit_inv(struct crypto_tfm *tfm) 114362306a36Sopenharmony_ci{ 114462306a36Sopenharmony_ci EIP197_REQUEST_ON_STACK(req, aead, EIP197_AEAD_REQ_SIZE); 114562306a36Sopenharmony_ci struct safexcel_cipher_req *sreq = aead_request_ctx(req); 114662306a36Sopenharmony_ci DECLARE_CRYPTO_WAIT(result); 114762306a36Sopenharmony_ci 114862306a36Sopenharmony_ci memset(req, 0, sizeof(struct aead_request)); 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_ci aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 115162306a36Sopenharmony_ci crypto_req_done, &result); 115262306a36Sopenharmony_ci aead_request_set_tfm(req, __crypto_aead_cast(tfm)); 115362306a36Sopenharmony_ci 115462306a36Sopenharmony_ci return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result); 115562306a36Sopenharmony_ci} 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_cistatic int safexcel_queue_req(struct crypto_async_request *base, 115862306a36Sopenharmony_ci struct safexcel_cipher_req *sreq, 115962306a36Sopenharmony_ci enum safexcel_cipher_direction dir) 116062306a36Sopenharmony_ci{ 116162306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 116262306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 116362306a36Sopenharmony_ci int ret, ring; 116462306a36Sopenharmony_ci 116562306a36Sopenharmony_ci sreq->needs_inv = false; 116662306a36Sopenharmony_ci sreq->direction = dir; 116762306a36Sopenharmony_ci 116862306a36Sopenharmony_ci if (ctx->base.ctxr) { 116962306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.needs_inv) { 117062306a36Sopenharmony_ci sreq->needs_inv = true; 117162306a36Sopenharmony_ci ctx->base.needs_inv = false; 117262306a36Sopenharmony_ci } 117362306a36Sopenharmony_ci } else { 117462306a36Sopenharmony_ci ctx->base.ring = safexcel_select_ring(priv); 117562306a36Sopenharmony_ci ctx->base.ctxr = dma_pool_zalloc(priv->context_pool, 117662306a36Sopenharmony_ci EIP197_GFP_FLAGS(*base), 117762306a36Sopenharmony_ci &ctx->base.ctxr_dma); 117862306a36Sopenharmony_ci if (!ctx->base.ctxr) 117962306a36Sopenharmony_ci return -ENOMEM; 118062306a36Sopenharmony_ci } 118162306a36Sopenharmony_ci 118262306a36Sopenharmony_ci ring = ctx->base.ring; 118362306a36Sopenharmony_ci 118462306a36Sopenharmony_ci spin_lock_bh(&priv->ring[ring].queue_lock); 118562306a36Sopenharmony_ci ret = crypto_enqueue_request(&priv->ring[ring].queue, base); 118662306a36Sopenharmony_ci spin_unlock_bh(&priv->ring[ring].queue_lock); 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_ci queue_work(priv->ring[ring].workqueue, 118962306a36Sopenharmony_ci &priv->ring[ring].work_data.work); 119062306a36Sopenharmony_ci 119162306a36Sopenharmony_ci return ret; 119262306a36Sopenharmony_ci} 119362306a36Sopenharmony_ci 119462306a36Sopenharmony_cistatic int safexcel_encrypt(struct skcipher_request *req) 119562306a36Sopenharmony_ci{ 119662306a36Sopenharmony_ci return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 119762306a36Sopenharmony_ci SAFEXCEL_ENCRYPT); 119862306a36Sopenharmony_ci} 119962306a36Sopenharmony_ci 120062306a36Sopenharmony_cistatic int safexcel_decrypt(struct skcipher_request *req) 120162306a36Sopenharmony_ci{ 120262306a36Sopenharmony_ci return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 120362306a36Sopenharmony_ci SAFEXCEL_DECRYPT); 120462306a36Sopenharmony_ci} 120562306a36Sopenharmony_ci 120662306a36Sopenharmony_cistatic int safexcel_skcipher_cra_init(struct crypto_tfm *tfm) 120762306a36Sopenharmony_ci{ 120862306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 120962306a36Sopenharmony_ci struct safexcel_alg_template *tmpl = 121062306a36Sopenharmony_ci container_of(tfm->__crt_alg, struct safexcel_alg_template, 121162306a36Sopenharmony_ci alg.skcipher.base); 121262306a36Sopenharmony_ci 121362306a36Sopenharmony_ci crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), 121462306a36Sopenharmony_ci sizeof(struct safexcel_cipher_req)); 121562306a36Sopenharmony_ci 121662306a36Sopenharmony_ci ctx->base.priv = tmpl->priv; 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_ci ctx->base.send = safexcel_skcipher_send; 121962306a36Sopenharmony_ci ctx->base.handle_result = safexcel_skcipher_handle_result; 122062306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD; 122162306a36Sopenharmony_ci ctx->ctrinit = 1; 122262306a36Sopenharmony_ci return 0; 122362306a36Sopenharmony_ci} 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_cistatic int safexcel_cipher_cra_exit(struct crypto_tfm *tfm) 122662306a36Sopenharmony_ci{ 122762306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 122862306a36Sopenharmony_ci 122962306a36Sopenharmony_ci memzero_explicit(ctx->key, sizeof(ctx->key)); 123062306a36Sopenharmony_ci 123162306a36Sopenharmony_ci /* context not allocated, skip invalidation */ 123262306a36Sopenharmony_ci if (!ctx->base.ctxr) 123362306a36Sopenharmony_ci return -ENOMEM; 123462306a36Sopenharmony_ci 123562306a36Sopenharmony_ci memzero_explicit(ctx->base.ctxr->data, sizeof(ctx->base.ctxr->data)); 123662306a36Sopenharmony_ci return 0; 123762306a36Sopenharmony_ci} 123862306a36Sopenharmony_ci 123962306a36Sopenharmony_cistatic void safexcel_skcipher_cra_exit(struct crypto_tfm *tfm) 124062306a36Sopenharmony_ci{ 124162306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 124262306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 124362306a36Sopenharmony_ci int ret; 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_ci if (safexcel_cipher_cra_exit(tfm)) 124662306a36Sopenharmony_ci return; 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE) { 124962306a36Sopenharmony_ci ret = safexcel_skcipher_exit_inv(tfm); 125062306a36Sopenharmony_ci if (ret) 125162306a36Sopenharmony_ci dev_warn(priv->dev, "skcipher: invalidation error %d\n", 125262306a36Sopenharmony_ci ret); 125362306a36Sopenharmony_ci } else { 125462306a36Sopenharmony_ci dma_pool_free(priv->context_pool, ctx->base.ctxr, 125562306a36Sopenharmony_ci ctx->base.ctxr_dma); 125662306a36Sopenharmony_ci } 125762306a36Sopenharmony_ci} 125862306a36Sopenharmony_ci 125962306a36Sopenharmony_cistatic void safexcel_aead_cra_exit(struct crypto_tfm *tfm) 126062306a36Sopenharmony_ci{ 126162306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 126262306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 126362306a36Sopenharmony_ci int ret; 126462306a36Sopenharmony_ci 126562306a36Sopenharmony_ci if (safexcel_cipher_cra_exit(tfm)) 126662306a36Sopenharmony_ci return; 126762306a36Sopenharmony_ci 126862306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE) { 126962306a36Sopenharmony_ci ret = safexcel_aead_exit_inv(tfm); 127062306a36Sopenharmony_ci if (ret) 127162306a36Sopenharmony_ci dev_warn(priv->dev, "aead: invalidation error %d\n", 127262306a36Sopenharmony_ci ret); 127362306a36Sopenharmony_ci } else { 127462306a36Sopenharmony_ci dma_pool_free(priv->context_pool, ctx->base.ctxr, 127562306a36Sopenharmony_ci ctx->base.ctxr_dma); 127662306a36Sopenharmony_ci } 127762306a36Sopenharmony_ci} 127862306a36Sopenharmony_ci 127962306a36Sopenharmony_cistatic int safexcel_skcipher_aes_ecb_cra_init(struct crypto_tfm *tfm) 128062306a36Sopenharmony_ci{ 128162306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 128262306a36Sopenharmony_ci 128362306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 128462306a36Sopenharmony_ci ctx->alg = SAFEXCEL_AES; 128562306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 128662306a36Sopenharmony_ci ctx->blocksz = 0; 128762306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 128862306a36Sopenharmony_ci return 0; 128962306a36Sopenharmony_ci} 129062306a36Sopenharmony_ci 129162306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ecb_aes = { 129262306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 129362306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES, 129462306a36Sopenharmony_ci .alg.skcipher = { 129562306a36Sopenharmony_ci .setkey = safexcel_skcipher_aes_setkey, 129662306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 129762306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 129862306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 129962306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 130062306a36Sopenharmony_ci .base = { 130162306a36Sopenharmony_ci .cra_name = "ecb(aes)", 130262306a36Sopenharmony_ci .cra_driver_name = "safexcel-ecb-aes", 130362306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 130462306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 130562306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 130662306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 130762306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 130862306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 130962306a36Sopenharmony_ci .cra_alignmask = 0, 131062306a36Sopenharmony_ci .cra_init = safexcel_skcipher_aes_ecb_cra_init, 131162306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 131262306a36Sopenharmony_ci .cra_module = THIS_MODULE, 131362306a36Sopenharmony_ci }, 131462306a36Sopenharmony_ci }, 131562306a36Sopenharmony_ci}; 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_cistatic int safexcel_skcipher_aes_cbc_cra_init(struct crypto_tfm *tfm) 131862306a36Sopenharmony_ci{ 131962306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 132062306a36Sopenharmony_ci 132162306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 132262306a36Sopenharmony_ci ctx->alg = SAFEXCEL_AES; 132362306a36Sopenharmony_ci ctx->blocksz = AES_BLOCK_SIZE; 132462306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 132562306a36Sopenharmony_ci return 0; 132662306a36Sopenharmony_ci} 132762306a36Sopenharmony_ci 132862306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cbc_aes = { 132962306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 133062306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES, 133162306a36Sopenharmony_ci .alg.skcipher = { 133262306a36Sopenharmony_ci .setkey = safexcel_skcipher_aes_setkey, 133362306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 133462306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 133562306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 133662306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 133762306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 133862306a36Sopenharmony_ci .base = { 133962306a36Sopenharmony_ci .cra_name = "cbc(aes)", 134062306a36Sopenharmony_ci .cra_driver_name = "safexcel-cbc-aes", 134162306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 134262306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 134362306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 134462306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 134562306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 134662306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 134762306a36Sopenharmony_ci .cra_alignmask = 0, 134862306a36Sopenharmony_ci .cra_init = safexcel_skcipher_aes_cbc_cra_init, 134962306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 135062306a36Sopenharmony_ci .cra_module = THIS_MODULE, 135162306a36Sopenharmony_ci }, 135262306a36Sopenharmony_ci }, 135362306a36Sopenharmony_ci}; 135462306a36Sopenharmony_ci 135562306a36Sopenharmony_cistatic int safexcel_skcipher_aes_cfb_cra_init(struct crypto_tfm *tfm) 135662306a36Sopenharmony_ci{ 135762306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 136062306a36Sopenharmony_ci ctx->alg = SAFEXCEL_AES; 136162306a36Sopenharmony_ci ctx->blocksz = AES_BLOCK_SIZE; 136262306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; 136362306a36Sopenharmony_ci return 0; 136462306a36Sopenharmony_ci} 136562306a36Sopenharmony_ci 136662306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cfb_aes = { 136762306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 136862306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB, 136962306a36Sopenharmony_ci .alg.skcipher = { 137062306a36Sopenharmony_ci .setkey = safexcel_skcipher_aes_setkey, 137162306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 137262306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 137362306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 137462306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 137562306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 137662306a36Sopenharmony_ci .base = { 137762306a36Sopenharmony_ci .cra_name = "cfb(aes)", 137862306a36Sopenharmony_ci .cra_driver_name = "safexcel-cfb-aes", 137962306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 138062306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 138162306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 138262306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 138362306a36Sopenharmony_ci .cra_blocksize = 1, 138462306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 138562306a36Sopenharmony_ci .cra_alignmask = 0, 138662306a36Sopenharmony_ci .cra_init = safexcel_skcipher_aes_cfb_cra_init, 138762306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 138862306a36Sopenharmony_ci .cra_module = THIS_MODULE, 138962306a36Sopenharmony_ci }, 139062306a36Sopenharmony_ci }, 139162306a36Sopenharmony_ci}; 139262306a36Sopenharmony_ci 139362306a36Sopenharmony_cistatic int safexcel_skcipher_aes_ofb_cra_init(struct crypto_tfm *tfm) 139462306a36Sopenharmony_ci{ 139562306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 139662306a36Sopenharmony_ci 139762306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 139862306a36Sopenharmony_ci ctx->alg = SAFEXCEL_AES; 139962306a36Sopenharmony_ci ctx->blocksz = AES_BLOCK_SIZE; 140062306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; 140162306a36Sopenharmony_ci return 0; 140262306a36Sopenharmony_ci} 140362306a36Sopenharmony_ci 140462306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ofb_aes = { 140562306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 140662306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB, 140762306a36Sopenharmony_ci .alg.skcipher = { 140862306a36Sopenharmony_ci .setkey = safexcel_skcipher_aes_setkey, 140962306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 141062306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 141162306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 141262306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 141362306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 141462306a36Sopenharmony_ci .base = { 141562306a36Sopenharmony_ci .cra_name = "ofb(aes)", 141662306a36Sopenharmony_ci .cra_driver_name = "safexcel-ofb-aes", 141762306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 141862306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 141962306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 142062306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 142162306a36Sopenharmony_ci .cra_blocksize = 1, 142262306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 142362306a36Sopenharmony_ci .cra_alignmask = 0, 142462306a36Sopenharmony_ci .cra_init = safexcel_skcipher_aes_ofb_cra_init, 142562306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 142662306a36Sopenharmony_ci .cra_module = THIS_MODULE, 142762306a36Sopenharmony_ci }, 142862306a36Sopenharmony_ci }, 142962306a36Sopenharmony_ci}; 143062306a36Sopenharmony_ci 143162306a36Sopenharmony_cistatic int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm, 143262306a36Sopenharmony_ci const u8 *key, unsigned int len) 143362306a36Sopenharmony_ci{ 143462306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 143562306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 143662306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 143762306a36Sopenharmony_ci struct crypto_aes_ctx aes; 143862306a36Sopenharmony_ci int ret, i; 143962306a36Sopenharmony_ci unsigned int keylen; 144062306a36Sopenharmony_ci 144162306a36Sopenharmony_ci /* last 4 bytes of key are the nonce! */ 144262306a36Sopenharmony_ci ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 144362306a36Sopenharmony_ci /* exclude the nonce here */ 144462306a36Sopenharmony_ci keylen = len - CTR_RFC3686_NONCE_SIZE; 144562306a36Sopenharmony_ci ret = aes_expandkey(&aes, key, keylen); 144662306a36Sopenharmony_ci if (ret) 144762306a36Sopenharmony_ci return ret; 144862306a36Sopenharmony_ci 144962306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 145062306a36Sopenharmony_ci for (i = 0; i < keylen / sizeof(u32); i++) { 145162306a36Sopenharmony_ci if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 145262306a36Sopenharmony_ci ctx->base.needs_inv = true; 145362306a36Sopenharmony_ci break; 145462306a36Sopenharmony_ci } 145562306a36Sopenharmony_ci } 145662306a36Sopenharmony_ci } 145762306a36Sopenharmony_ci 145862306a36Sopenharmony_ci for (i = 0; i < keylen / sizeof(u32); i++) 145962306a36Sopenharmony_ci ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 146062306a36Sopenharmony_ci 146162306a36Sopenharmony_ci ctx->key_len = keylen; 146262306a36Sopenharmony_ci 146362306a36Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 146462306a36Sopenharmony_ci return 0; 146562306a36Sopenharmony_ci} 146662306a36Sopenharmony_ci 146762306a36Sopenharmony_cistatic int safexcel_skcipher_aes_ctr_cra_init(struct crypto_tfm *tfm) 146862306a36Sopenharmony_ci{ 146962306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 147262306a36Sopenharmony_ci ctx->alg = SAFEXCEL_AES; 147362306a36Sopenharmony_ci ctx->blocksz = AES_BLOCK_SIZE; 147462306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 147562306a36Sopenharmony_ci return 0; 147662306a36Sopenharmony_ci} 147762306a36Sopenharmony_ci 147862306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ctr_aes = { 147962306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 148062306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES, 148162306a36Sopenharmony_ci .alg.skcipher = { 148262306a36Sopenharmony_ci .setkey = safexcel_skcipher_aesctr_setkey, 148362306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 148462306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 148562306a36Sopenharmony_ci /* Add nonce size */ 148662306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 148762306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 148862306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 148962306a36Sopenharmony_ci .base = { 149062306a36Sopenharmony_ci .cra_name = "rfc3686(ctr(aes))", 149162306a36Sopenharmony_ci .cra_driver_name = "safexcel-ctr-aes", 149262306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 149362306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 149462306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 149562306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 149662306a36Sopenharmony_ci .cra_blocksize = 1, 149762306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 149862306a36Sopenharmony_ci .cra_alignmask = 0, 149962306a36Sopenharmony_ci .cra_init = safexcel_skcipher_aes_ctr_cra_init, 150062306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 150162306a36Sopenharmony_ci .cra_module = THIS_MODULE, 150262306a36Sopenharmony_ci }, 150362306a36Sopenharmony_ci }, 150462306a36Sopenharmony_ci}; 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_cistatic int safexcel_des_setkey(struct crypto_skcipher *ctfm, const u8 *key, 150762306a36Sopenharmony_ci unsigned int len) 150862306a36Sopenharmony_ci{ 150962306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 151062306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 151162306a36Sopenharmony_ci int ret; 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci ret = verify_skcipher_des_key(ctfm, key); 151462306a36Sopenharmony_ci if (ret) 151562306a36Sopenharmony_ci return ret; 151662306a36Sopenharmony_ci 151762306a36Sopenharmony_ci /* if context exits and key changed, need to invalidate it */ 151862306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 151962306a36Sopenharmony_ci if (memcmp(ctx->key, key, len)) 152062306a36Sopenharmony_ci ctx->base.needs_inv = true; 152162306a36Sopenharmony_ci 152262306a36Sopenharmony_ci memcpy(ctx->key, key, len); 152362306a36Sopenharmony_ci ctx->key_len = len; 152462306a36Sopenharmony_ci 152562306a36Sopenharmony_ci return 0; 152662306a36Sopenharmony_ci} 152762306a36Sopenharmony_ci 152862306a36Sopenharmony_cistatic int safexcel_skcipher_des_cbc_cra_init(struct crypto_tfm *tfm) 152962306a36Sopenharmony_ci{ 153062306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 153162306a36Sopenharmony_ci 153262306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 153362306a36Sopenharmony_ci ctx->alg = SAFEXCEL_DES; 153462306a36Sopenharmony_ci ctx->blocksz = DES_BLOCK_SIZE; 153562306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 153662306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 153762306a36Sopenharmony_ci return 0; 153862306a36Sopenharmony_ci} 153962306a36Sopenharmony_ci 154062306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cbc_des = { 154162306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 154262306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES, 154362306a36Sopenharmony_ci .alg.skcipher = { 154462306a36Sopenharmony_ci .setkey = safexcel_des_setkey, 154562306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 154662306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 154762306a36Sopenharmony_ci .min_keysize = DES_KEY_SIZE, 154862306a36Sopenharmony_ci .max_keysize = DES_KEY_SIZE, 154962306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 155062306a36Sopenharmony_ci .base = { 155162306a36Sopenharmony_ci .cra_name = "cbc(des)", 155262306a36Sopenharmony_ci .cra_driver_name = "safexcel-cbc-des", 155362306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 155462306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 155562306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 155662306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 155762306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 155862306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 155962306a36Sopenharmony_ci .cra_alignmask = 0, 156062306a36Sopenharmony_ci .cra_init = safexcel_skcipher_des_cbc_cra_init, 156162306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 156262306a36Sopenharmony_ci .cra_module = THIS_MODULE, 156362306a36Sopenharmony_ci }, 156462306a36Sopenharmony_ci }, 156562306a36Sopenharmony_ci}; 156662306a36Sopenharmony_ci 156762306a36Sopenharmony_cistatic int safexcel_skcipher_des_ecb_cra_init(struct crypto_tfm *tfm) 156862306a36Sopenharmony_ci{ 156962306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 157062306a36Sopenharmony_ci 157162306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 157262306a36Sopenharmony_ci ctx->alg = SAFEXCEL_DES; 157362306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 157462306a36Sopenharmony_ci ctx->blocksz = 0; 157562306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 157662306a36Sopenharmony_ci return 0; 157762306a36Sopenharmony_ci} 157862306a36Sopenharmony_ci 157962306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ecb_des = { 158062306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 158162306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES, 158262306a36Sopenharmony_ci .alg.skcipher = { 158362306a36Sopenharmony_ci .setkey = safexcel_des_setkey, 158462306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 158562306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 158662306a36Sopenharmony_ci .min_keysize = DES_KEY_SIZE, 158762306a36Sopenharmony_ci .max_keysize = DES_KEY_SIZE, 158862306a36Sopenharmony_ci .base = { 158962306a36Sopenharmony_ci .cra_name = "ecb(des)", 159062306a36Sopenharmony_ci .cra_driver_name = "safexcel-ecb-des", 159162306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 159262306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 159362306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 159462306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 159562306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 159662306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 159762306a36Sopenharmony_ci .cra_alignmask = 0, 159862306a36Sopenharmony_ci .cra_init = safexcel_skcipher_des_ecb_cra_init, 159962306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 160062306a36Sopenharmony_ci .cra_module = THIS_MODULE, 160162306a36Sopenharmony_ci }, 160262306a36Sopenharmony_ci }, 160362306a36Sopenharmony_ci}; 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_cistatic int safexcel_des3_ede_setkey(struct crypto_skcipher *ctfm, 160662306a36Sopenharmony_ci const u8 *key, unsigned int len) 160762306a36Sopenharmony_ci{ 160862306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 160962306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 161062306a36Sopenharmony_ci int err; 161162306a36Sopenharmony_ci 161262306a36Sopenharmony_ci err = verify_skcipher_des3_key(ctfm, key); 161362306a36Sopenharmony_ci if (err) 161462306a36Sopenharmony_ci return err; 161562306a36Sopenharmony_ci 161662306a36Sopenharmony_ci /* if context exits and key changed, need to invalidate it */ 161762306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 161862306a36Sopenharmony_ci if (memcmp(ctx->key, key, len)) 161962306a36Sopenharmony_ci ctx->base.needs_inv = true; 162062306a36Sopenharmony_ci 162162306a36Sopenharmony_ci memcpy(ctx->key, key, len); 162262306a36Sopenharmony_ci ctx->key_len = len; 162362306a36Sopenharmony_ci 162462306a36Sopenharmony_ci return 0; 162562306a36Sopenharmony_ci} 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_cistatic int safexcel_skcipher_des3_cbc_cra_init(struct crypto_tfm *tfm) 162862306a36Sopenharmony_ci{ 162962306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 163062306a36Sopenharmony_ci 163162306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 163262306a36Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; 163362306a36Sopenharmony_ci ctx->blocksz = DES3_EDE_BLOCK_SIZE; 163462306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 163562306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 163662306a36Sopenharmony_ci return 0; 163762306a36Sopenharmony_ci} 163862306a36Sopenharmony_ci 163962306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cbc_des3_ede = { 164062306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 164162306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES, 164262306a36Sopenharmony_ci .alg.skcipher = { 164362306a36Sopenharmony_ci .setkey = safexcel_des3_ede_setkey, 164462306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 164562306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 164662306a36Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 164762306a36Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 164862306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 164962306a36Sopenharmony_ci .base = { 165062306a36Sopenharmony_ci .cra_name = "cbc(des3_ede)", 165162306a36Sopenharmony_ci .cra_driver_name = "safexcel-cbc-des3_ede", 165262306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 165362306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 165462306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 165562306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 165662306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 165762306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 165862306a36Sopenharmony_ci .cra_alignmask = 0, 165962306a36Sopenharmony_ci .cra_init = safexcel_skcipher_des3_cbc_cra_init, 166062306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 166162306a36Sopenharmony_ci .cra_module = THIS_MODULE, 166262306a36Sopenharmony_ci }, 166362306a36Sopenharmony_ci }, 166462306a36Sopenharmony_ci}; 166562306a36Sopenharmony_ci 166662306a36Sopenharmony_cistatic int safexcel_skcipher_des3_ecb_cra_init(struct crypto_tfm *tfm) 166762306a36Sopenharmony_ci{ 166862306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 167162306a36Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; 167262306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 167362306a36Sopenharmony_ci ctx->blocksz = 0; 167462306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 167562306a36Sopenharmony_ci return 0; 167662306a36Sopenharmony_ci} 167762306a36Sopenharmony_ci 167862306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ecb_des3_ede = { 167962306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 168062306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES, 168162306a36Sopenharmony_ci .alg.skcipher = { 168262306a36Sopenharmony_ci .setkey = safexcel_des3_ede_setkey, 168362306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 168462306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 168562306a36Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 168662306a36Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 168762306a36Sopenharmony_ci .base = { 168862306a36Sopenharmony_ci .cra_name = "ecb(des3_ede)", 168962306a36Sopenharmony_ci .cra_driver_name = "safexcel-ecb-des3_ede", 169062306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 169162306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 169262306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 169362306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 169462306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 169562306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 169662306a36Sopenharmony_ci .cra_alignmask = 0, 169762306a36Sopenharmony_ci .cra_init = safexcel_skcipher_des3_ecb_cra_init, 169862306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 169962306a36Sopenharmony_ci .cra_module = THIS_MODULE, 170062306a36Sopenharmony_ci }, 170162306a36Sopenharmony_ci }, 170262306a36Sopenharmony_ci}; 170362306a36Sopenharmony_ci 170462306a36Sopenharmony_cistatic int safexcel_aead_encrypt(struct aead_request *req) 170562306a36Sopenharmony_ci{ 170662306a36Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 170762306a36Sopenharmony_ci 170862306a36Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 170962306a36Sopenharmony_ci} 171062306a36Sopenharmony_ci 171162306a36Sopenharmony_cistatic int safexcel_aead_decrypt(struct aead_request *req) 171262306a36Sopenharmony_ci{ 171362306a36Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 171462306a36Sopenharmony_ci 171562306a36Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 171662306a36Sopenharmony_ci} 171762306a36Sopenharmony_ci 171862306a36Sopenharmony_cistatic int safexcel_aead_cra_init(struct crypto_tfm *tfm) 171962306a36Sopenharmony_ci{ 172062306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 172162306a36Sopenharmony_ci struct safexcel_alg_template *tmpl = 172262306a36Sopenharmony_ci container_of(tfm->__crt_alg, struct safexcel_alg_template, 172362306a36Sopenharmony_ci alg.aead.base); 172462306a36Sopenharmony_ci 172562306a36Sopenharmony_ci crypto_aead_set_reqsize(__crypto_aead_cast(tfm), 172662306a36Sopenharmony_ci sizeof(struct safexcel_cipher_req)); 172762306a36Sopenharmony_ci 172862306a36Sopenharmony_ci ctx->base.priv = tmpl->priv; 172962306a36Sopenharmony_ci 173062306a36Sopenharmony_ci ctx->alg = SAFEXCEL_AES; /* default */ 173162306a36Sopenharmony_ci ctx->blocksz = AES_BLOCK_SIZE; 173262306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD; 173362306a36Sopenharmony_ci ctx->ctrinit = 1; 173462306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; /* default */ 173562306a36Sopenharmony_ci ctx->aead = true; 173662306a36Sopenharmony_ci ctx->base.send = safexcel_aead_send; 173762306a36Sopenharmony_ci ctx->base.handle_result = safexcel_aead_handle_result; 173862306a36Sopenharmony_ci return 0; 173962306a36Sopenharmony_ci} 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_cistatic int safexcel_aead_sha1_cra_init(struct crypto_tfm *tfm) 174262306a36Sopenharmony_ci{ 174362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 174462306a36Sopenharmony_ci 174562306a36Sopenharmony_ci safexcel_aead_cra_init(tfm); 174662306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; 174762306a36Sopenharmony_ci ctx->state_sz = SHA1_DIGEST_SIZE; 174862306a36Sopenharmony_ci return 0; 174962306a36Sopenharmony_ci} 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_aes = { 175262306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 175362306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1, 175462306a36Sopenharmony_ci .alg.aead = { 175562306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 175662306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 175762306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 175862306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 175962306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 176062306a36Sopenharmony_ci .base = { 176162306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha1),cbc(aes))", 176262306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-aes", 176362306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 176462306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 176562306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 176662306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 176762306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 176862306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 176962306a36Sopenharmony_ci .cra_alignmask = 0, 177062306a36Sopenharmony_ci .cra_init = safexcel_aead_sha1_cra_init, 177162306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 177262306a36Sopenharmony_ci .cra_module = THIS_MODULE, 177362306a36Sopenharmony_ci }, 177462306a36Sopenharmony_ci }, 177562306a36Sopenharmony_ci}; 177662306a36Sopenharmony_ci 177762306a36Sopenharmony_cistatic int safexcel_aead_sha256_cra_init(struct crypto_tfm *tfm) 177862306a36Sopenharmony_ci{ 177962306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 178062306a36Sopenharmony_ci 178162306a36Sopenharmony_ci safexcel_aead_cra_init(tfm); 178262306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256; 178362306a36Sopenharmony_ci ctx->state_sz = SHA256_DIGEST_SIZE; 178462306a36Sopenharmony_ci return 0; 178562306a36Sopenharmony_ci} 178662306a36Sopenharmony_ci 178762306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_aes = { 178862306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 178962306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 179062306a36Sopenharmony_ci .alg.aead = { 179162306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 179262306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 179362306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 179462306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 179562306a36Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 179662306a36Sopenharmony_ci .base = { 179762306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha256),cbc(aes))", 179862306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-aes", 179962306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 180062306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 180162306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 180262306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 180362306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 180462306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 180562306a36Sopenharmony_ci .cra_alignmask = 0, 180662306a36Sopenharmony_ci .cra_init = safexcel_aead_sha256_cra_init, 180762306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 180862306a36Sopenharmony_ci .cra_module = THIS_MODULE, 180962306a36Sopenharmony_ci }, 181062306a36Sopenharmony_ci }, 181162306a36Sopenharmony_ci}; 181262306a36Sopenharmony_ci 181362306a36Sopenharmony_cistatic int safexcel_aead_sha224_cra_init(struct crypto_tfm *tfm) 181462306a36Sopenharmony_ci{ 181562306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 181662306a36Sopenharmony_ci 181762306a36Sopenharmony_ci safexcel_aead_cra_init(tfm); 181862306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224; 181962306a36Sopenharmony_ci ctx->state_sz = SHA256_DIGEST_SIZE; 182062306a36Sopenharmony_ci return 0; 182162306a36Sopenharmony_ci} 182262306a36Sopenharmony_ci 182362306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_aes = { 182462306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 182562306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 182662306a36Sopenharmony_ci .alg.aead = { 182762306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 182862306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 182962306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 183062306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 183162306a36Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 183262306a36Sopenharmony_ci .base = { 183362306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha224),cbc(aes))", 183462306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-aes", 183562306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 183662306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 183762306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 183862306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 183962306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 184062306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 184162306a36Sopenharmony_ci .cra_alignmask = 0, 184262306a36Sopenharmony_ci .cra_init = safexcel_aead_sha224_cra_init, 184362306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 184462306a36Sopenharmony_ci .cra_module = THIS_MODULE, 184562306a36Sopenharmony_ci }, 184662306a36Sopenharmony_ci }, 184762306a36Sopenharmony_ci}; 184862306a36Sopenharmony_ci 184962306a36Sopenharmony_cistatic int safexcel_aead_sha512_cra_init(struct crypto_tfm *tfm) 185062306a36Sopenharmony_ci{ 185162306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 185262306a36Sopenharmony_ci 185362306a36Sopenharmony_ci safexcel_aead_cra_init(tfm); 185462306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512; 185562306a36Sopenharmony_ci ctx->state_sz = SHA512_DIGEST_SIZE; 185662306a36Sopenharmony_ci return 0; 185762306a36Sopenharmony_ci} 185862306a36Sopenharmony_ci 185962306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_aes = { 186062306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 186162306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 186262306a36Sopenharmony_ci .alg.aead = { 186362306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 186462306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 186562306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 186662306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 186762306a36Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 186862306a36Sopenharmony_ci .base = { 186962306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha512),cbc(aes))", 187062306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-aes", 187162306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 187262306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 187362306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 187462306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 187562306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 187662306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 187762306a36Sopenharmony_ci .cra_alignmask = 0, 187862306a36Sopenharmony_ci .cra_init = safexcel_aead_sha512_cra_init, 187962306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 188062306a36Sopenharmony_ci .cra_module = THIS_MODULE, 188162306a36Sopenharmony_ci }, 188262306a36Sopenharmony_ci }, 188362306a36Sopenharmony_ci}; 188462306a36Sopenharmony_ci 188562306a36Sopenharmony_cistatic int safexcel_aead_sha384_cra_init(struct crypto_tfm *tfm) 188662306a36Sopenharmony_ci{ 188762306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 188862306a36Sopenharmony_ci 188962306a36Sopenharmony_ci safexcel_aead_cra_init(tfm); 189062306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384; 189162306a36Sopenharmony_ci ctx->state_sz = SHA512_DIGEST_SIZE; 189262306a36Sopenharmony_ci return 0; 189362306a36Sopenharmony_ci} 189462306a36Sopenharmony_ci 189562306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_aes = { 189662306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 189762306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 189862306a36Sopenharmony_ci .alg.aead = { 189962306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 190062306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 190162306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 190262306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 190362306a36Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 190462306a36Sopenharmony_ci .base = { 190562306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha384),cbc(aes))", 190662306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-aes", 190762306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 190862306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 190962306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 191062306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 191162306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 191262306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 191362306a36Sopenharmony_ci .cra_alignmask = 0, 191462306a36Sopenharmony_ci .cra_init = safexcel_aead_sha384_cra_init, 191562306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 191662306a36Sopenharmony_ci .cra_module = THIS_MODULE, 191762306a36Sopenharmony_ci }, 191862306a36Sopenharmony_ci }, 191962306a36Sopenharmony_ci}; 192062306a36Sopenharmony_ci 192162306a36Sopenharmony_cistatic int safexcel_aead_sha1_des3_cra_init(struct crypto_tfm *tfm) 192262306a36Sopenharmony_ci{ 192362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 192462306a36Sopenharmony_ci 192562306a36Sopenharmony_ci safexcel_aead_sha1_cra_init(tfm); 192662306a36Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; /* override default */ 192762306a36Sopenharmony_ci ctx->blocksz = DES3_EDE_BLOCK_SIZE; 192862306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 192962306a36Sopenharmony_ci return 0; 193062306a36Sopenharmony_ci} 193162306a36Sopenharmony_ci 193262306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des3_ede = { 193362306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 193462306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, 193562306a36Sopenharmony_ci .alg.aead = { 193662306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 193762306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 193862306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 193962306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 194062306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 194162306a36Sopenharmony_ci .base = { 194262306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", 194362306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des3_ede", 194462306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 194562306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 194662306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 194762306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 194862306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 194962306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 195062306a36Sopenharmony_ci .cra_alignmask = 0, 195162306a36Sopenharmony_ci .cra_init = safexcel_aead_sha1_des3_cra_init, 195262306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 195362306a36Sopenharmony_ci .cra_module = THIS_MODULE, 195462306a36Sopenharmony_ci }, 195562306a36Sopenharmony_ci }, 195662306a36Sopenharmony_ci}; 195762306a36Sopenharmony_ci 195862306a36Sopenharmony_cistatic int safexcel_aead_sha256_des3_cra_init(struct crypto_tfm *tfm) 195962306a36Sopenharmony_ci{ 196062306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 196162306a36Sopenharmony_ci 196262306a36Sopenharmony_ci safexcel_aead_sha256_cra_init(tfm); 196362306a36Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; /* override default */ 196462306a36Sopenharmony_ci ctx->blocksz = DES3_EDE_BLOCK_SIZE; 196562306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 196662306a36Sopenharmony_ci return 0; 196762306a36Sopenharmony_ci} 196862306a36Sopenharmony_ci 196962306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede = { 197062306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 197162306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 197262306a36Sopenharmony_ci .alg.aead = { 197362306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 197462306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 197562306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 197662306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 197762306a36Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 197862306a36Sopenharmony_ci .base = { 197962306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", 198062306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des3_ede", 198162306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 198262306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 198362306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 198462306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 198562306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 198662306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 198762306a36Sopenharmony_ci .cra_alignmask = 0, 198862306a36Sopenharmony_ci .cra_init = safexcel_aead_sha256_des3_cra_init, 198962306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 199062306a36Sopenharmony_ci .cra_module = THIS_MODULE, 199162306a36Sopenharmony_ci }, 199262306a36Sopenharmony_ci }, 199362306a36Sopenharmony_ci}; 199462306a36Sopenharmony_ci 199562306a36Sopenharmony_cistatic int safexcel_aead_sha224_des3_cra_init(struct crypto_tfm *tfm) 199662306a36Sopenharmony_ci{ 199762306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 199862306a36Sopenharmony_ci 199962306a36Sopenharmony_ci safexcel_aead_sha224_cra_init(tfm); 200062306a36Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; /* override default */ 200162306a36Sopenharmony_ci ctx->blocksz = DES3_EDE_BLOCK_SIZE; 200262306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 200362306a36Sopenharmony_ci return 0; 200462306a36Sopenharmony_ci} 200562306a36Sopenharmony_ci 200662306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede = { 200762306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 200862306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 200962306a36Sopenharmony_ci .alg.aead = { 201062306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 201162306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 201262306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 201362306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 201462306a36Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 201562306a36Sopenharmony_ci .base = { 201662306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha224),cbc(des3_ede))", 201762306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des3_ede", 201862306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 201962306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 202062306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 202162306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 202262306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 202362306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 202462306a36Sopenharmony_ci .cra_alignmask = 0, 202562306a36Sopenharmony_ci .cra_init = safexcel_aead_sha224_des3_cra_init, 202662306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 202762306a36Sopenharmony_ci .cra_module = THIS_MODULE, 202862306a36Sopenharmony_ci }, 202962306a36Sopenharmony_ci }, 203062306a36Sopenharmony_ci}; 203162306a36Sopenharmony_ci 203262306a36Sopenharmony_cistatic int safexcel_aead_sha512_des3_cra_init(struct crypto_tfm *tfm) 203362306a36Sopenharmony_ci{ 203462306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 203562306a36Sopenharmony_ci 203662306a36Sopenharmony_ci safexcel_aead_sha512_cra_init(tfm); 203762306a36Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; /* override default */ 203862306a36Sopenharmony_ci ctx->blocksz = DES3_EDE_BLOCK_SIZE; 203962306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 204062306a36Sopenharmony_ci return 0; 204162306a36Sopenharmony_ci} 204262306a36Sopenharmony_ci 204362306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede = { 204462306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 204562306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 204662306a36Sopenharmony_ci .alg.aead = { 204762306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 204862306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 204962306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 205062306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 205162306a36Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 205262306a36Sopenharmony_ci .base = { 205362306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha512),cbc(des3_ede))", 205462306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des3_ede", 205562306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 205662306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 205762306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 205862306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 205962306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 206062306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 206162306a36Sopenharmony_ci .cra_alignmask = 0, 206262306a36Sopenharmony_ci .cra_init = safexcel_aead_sha512_des3_cra_init, 206362306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 206462306a36Sopenharmony_ci .cra_module = THIS_MODULE, 206562306a36Sopenharmony_ci }, 206662306a36Sopenharmony_ci }, 206762306a36Sopenharmony_ci}; 206862306a36Sopenharmony_ci 206962306a36Sopenharmony_cistatic int safexcel_aead_sha384_des3_cra_init(struct crypto_tfm *tfm) 207062306a36Sopenharmony_ci{ 207162306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 207262306a36Sopenharmony_ci 207362306a36Sopenharmony_ci safexcel_aead_sha384_cra_init(tfm); 207462306a36Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; /* override default */ 207562306a36Sopenharmony_ci ctx->blocksz = DES3_EDE_BLOCK_SIZE; 207662306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 207762306a36Sopenharmony_ci return 0; 207862306a36Sopenharmony_ci} 207962306a36Sopenharmony_ci 208062306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede = { 208162306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 208262306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 208362306a36Sopenharmony_ci .alg.aead = { 208462306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 208562306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 208662306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 208762306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 208862306a36Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 208962306a36Sopenharmony_ci .base = { 209062306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha384),cbc(des3_ede))", 209162306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des3_ede", 209262306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 209362306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 209462306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 209562306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 209662306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 209762306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 209862306a36Sopenharmony_ci .cra_alignmask = 0, 209962306a36Sopenharmony_ci .cra_init = safexcel_aead_sha384_des3_cra_init, 210062306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 210162306a36Sopenharmony_ci .cra_module = THIS_MODULE, 210262306a36Sopenharmony_ci }, 210362306a36Sopenharmony_ci }, 210462306a36Sopenharmony_ci}; 210562306a36Sopenharmony_ci 210662306a36Sopenharmony_cistatic int safexcel_aead_sha1_des_cra_init(struct crypto_tfm *tfm) 210762306a36Sopenharmony_ci{ 210862306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 210962306a36Sopenharmony_ci 211062306a36Sopenharmony_ci safexcel_aead_sha1_cra_init(tfm); 211162306a36Sopenharmony_ci ctx->alg = SAFEXCEL_DES; /* override default */ 211262306a36Sopenharmony_ci ctx->blocksz = DES_BLOCK_SIZE; 211362306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 211462306a36Sopenharmony_ci return 0; 211562306a36Sopenharmony_ci} 211662306a36Sopenharmony_ci 211762306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des = { 211862306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 211962306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, 212062306a36Sopenharmony_ci .alg.aead = { 212162306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 212262306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 212362306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 212462306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 212562306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 212662306a36Sopenharmony_ci .base = { 212762306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha1),cbc(des))", 212862306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des", 212962306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 213062306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 213162306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 213262306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 213362306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 213462306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 213562306a36Sopenharmony_ci .cra_alignmask = 0, 213662306a36Sopenharmony_ci .cra_init = safexcel_aead_sha1_des_cra_init, 213762306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 213862306a36Sopenharmony_ci .cra_module = THIS_MODULE, 213962306a36Sopenharmony_ci }, 214062306a36Sopenharmony_ci }, 214162306a36Sopenharmony_ci}; 214262306a36Sopenharmony_ci 214362306a36Sopenharmony_cistatic int safexcel_aead_sha256_des_cra_init(struct crypto_tfm *tfm) 214462306a36Sopenharmony_ci{ 214562306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 214662306a36Sopenharmony_ci 214762306a36Sopenharmony_ci safexcel_aead_sha256_cra_init(tfm); 214862306a36Sopenharmony_ci ctx->alg = SAFEXCEL_DES; /* override default */ 214962306a36Sopenharmony_ci ctx->blocksz = DES_BLOCK_SIZE; 215062306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 215162306a36Sopenharmony_ci return 0; 215262306a36Sopenharmony_ci} 215362306a36Sopenharmony_ci 215462306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des = { 215562306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 215662306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 215762306a36Sopenharmony_ci .alg.aead = { 215862306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 215962306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 216062306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 216162306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 216262306a36Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 216362306a36Sopenharmony_ci .base = { 216462306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha256),cbc(des))", 216562306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des", 216662306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 216762306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 216862306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 216962306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 217062306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 217162306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 217262306a36Sopenharmony_ci .cra_alignmask = 0, 217362306a36Sopenharmony_ci .cra_init = safexcel_aead_sha256_des_cra_init, 217462306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 217562306a36Sopenharmony_ci .cra_module = THIS_MODULE, 217662306a36Sopenharmony_ci }, 217762306a36Sopenharmony_ci }, 217862306a36Sopenharmony_ci}; 217962306a36Sopenharmony_ci 218062306a36Sopenharmony_cistatic int safexcel_aead_sha224_des_cra_init(struct crypto_tfm *tfm) 218162306a36Sopenharmony_ci{ 218262306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 218362306a36Sopenharmony_ci 218462306a36Sopenharmony_ci safexcel_aead_sha224_cra_init(tfm); 218562306a36Sopenharmony_ci ctx->alg = SAFEXCEL_DES; /* override default */ 218662306a36Sopenharmony_ci ctx->blocksz = DES_BLOCK_SIZE; 218762306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 218862306a36Sopenharmony_ci return 0; 218962306a36Sopenharmony_ci} 219062306a36Sopenharmony_ci 219162306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des = { 219262306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 219362306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 219462306a36Sopenharmony_ci .alg.aead = { 219562306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 219662306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 219762306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 219862306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 219962306a36Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 220062306a36Sopenharmony_ci .base = { 220162306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha224),cbc(des))", 220262306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des", 220362306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 220462306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 220562306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 220662306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 220762306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 220862306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 220962306a36Sopenharmony_ci .cra_alignmask = 0, 221062306a36Sopenharmony_ci .cra_init = safexcel_aead_sha224_des_cra_init, 221162306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 221262306a36Sopenharmony_ci .cra_module = THIS_MODULE, 221362306a36Sopenharmony_ci }, 221462306a36Sopenharmony_ci }, 221562306a36Sopenharmony_ci}; 221662306a36Sopenharmony_ci 221762306a36Sopenharmony_cistatic int safexcel_aead_sha512_des_cra_init(struct crypto_tfm *tfm) 221862306a36Sopenharmony_ci{ 221962306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 222062306a36Sopenharmony_ci 222162306a36Sopenharmony_ci safexcel_aead_sha512_cra_init(tfm); 222262306a36Sopenharmony_ci ctx->alg = SAFEXCEL_DES; /* override default */ 222362306a36Sopenharmony_ci ctx->blocksz = DES_BLOCK_SIZE; 222462306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 222562306a36Sopenharmony_ci return 0; 222662306a36Sopenharmony_ci} 222762306a36Sopenharmony_ci 222862306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des = { 222962306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 223062306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 223162306a36Sopenharmony_ci .alg.aead = { 223262306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 223362306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 223462306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 223562306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 223662306a36Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 223762306a36Sopenharmony_ci .base = { 223862306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha512),cbc(des))", 223962306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des", 224062306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 224162306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 224262306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 224362306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 224462306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 224562306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 224662306a36Sopenharmony_ci .cra_alignmask = 0, 224762306a36Sopenharmony_ci .cra_init = safexcel_aead_sha512_des_cra_init, 224862306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 224962306a36Sopenharmony_ci .cra_module = THIS_MODULE, 225062306a36Sopenharmony_ci }, 225162306a36Sopenharmony_ci }, 225262306a36Sopenharmony_ci}; 225362306a36Sopenharmony_ci 225462306a36Sopenharmony_cistatic int safexcel_aead_sha384_des_cra_init(struct crypto_tfm *tfm) 225562306a36Sopenharmony_ci{ 225662306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 225762306a36Sopenharmony_ci 225862306a36Sopenharmony_ci safexcel_aead_sha384_cra_init(tfm); 225962306a36Sopenharmony_ci ctx->alg = SAFEXCEL_DES; /* override default */ 226062306a36Sopenharmony_ci ctx->blocksz = DES_BLOCK_SIZE; 226162306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 226262306a36Sopenharmony_ci return 0; 226362306a36Sopenharmony_ci} 226462306a36Sopenharmony_ci 226562306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des = { 226662306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 226762306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 226862306a36Sopenharmony_ci .alg.aead = { 226962306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 227062306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 227162306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 227262306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 227362306a36Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 227462306a36Sopenharmony_ci .base = { 227562306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha384),cbc(des))", 227662306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des", 227762306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 227862306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 227962306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 228062306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 228162306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 228262306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 228362306a36Sopenharmony_ci .cra_alignmask = 0, 228462306a36Sopenharmony_ci .cra_init = safexcel_aead_sha384_des_cra_init, 228562306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 228662306a36Sopenharmony_ci .cra_module = THIS_MODULE, 228762306a36Sopenharmony_ci }, 228862306a36Sopenharmony_ci }, 228962306a36Sopenharmony_ci}; 229062306a36Sopenharmony_ci 229162306a36Sopenharmony_cistatic int safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm *tfm) 229262306a36Sopenharmony_ci{ 229362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 229462306a36Sopenharmony_ci 229562306a36Sopenharmony_ci safexcel_aead_sha1_cra_init(tfm); 229662306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 229762306a36Sopenharmony_ci return 0; 229862306a36Sopenharmony_ci} 229962306a36Sopenharmony_ci 230062306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_aes = { 230162306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 230262306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1, 230362306a36Sopenharmony_ci .alg.aead = { 230462306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 230562306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 230662306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 230762306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 230862306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 230962306a36Sopenharmony_ci .base = { 231062306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))", 231162306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-aes", 231262306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 231362306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 231462306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 231562306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 231662306a36Sopenharmony_ci .cra_blocksize = 1, 231762306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 231862306a36Sopenharmony_ci .cra_alignmask = 0, 231962306a36Sopenharmony_ci .cra_init = safexcel_aead_sha1_ctr_cra_init, 232062306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 232162306a36Sopenharmony_ci .cra_module = THIS_MODULE, 232262306a36Sopenharmony_ci }, 232362306a36Sopenharmony_ci }, 232462306a36Sopenharmony_ci}; 232562306a36Sopenharmony_ci 232662306a36Sopenharmony_cistatic int safexcel_aead_sha256_ctr_cra_init(struct crypto_tfm *tfm) 232762306a36Sopenharmony_ci{ 232862306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 232962306a36Sopenharmony_ci 233062306a36Sopenharmony_ci safexcel_aead_sha256_cra_init(tfm); 233162306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 233262306a36Sopenharmony_ci return 0; 233362306a36Sopenharmony_ci} 233462306a36Sopenharmony_ci 233562306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes = { 233662306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 233762306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 233862306a36Sopenharmony_ci .alg.aead = { 233962306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 234062306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 234162306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 234262306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 234362306a36Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 234462306a36Sopenharmony_ci .base = { 234562306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))", 234662306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha256-ctr-aes", 234762306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 234862306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 234962306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 235062306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 235162306a36Sopenharmony_ci .cra_blocksize = 1, 235262306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 235362306a36Sopenharmony_ci .cra_alignmask = 0, 235462306a36Sopenharmony_ci .cra_init = safexcel_aead_sha256_ctr_cra_init, 235562306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 235662306a36Sopenharmony_ci .cra_module = THIS_MODULE, 235762306a36Sopenharmony_ci }, 235862306a36Sopenharmony_ci }, 235962306a36Sopenharmony_ci}; 236062306a36Sopenharmony_ci 236162306a36Sopenharmony_cistatic int safexcel_aead_sha224_ctr_cra_init(struct crypto_tfm *tfm) 236262306a36Sopenharmony_ci{ 236362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 236462306a36Sopenharmony_ci 236562306a36Sopenharmony_ci safexcel_aead_sha224_cra_init(tfm); 236662306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 236762306a36Sopenharmony_ci return 0; 236862306a36Sopenharmony_ci} 236962306a36Sopenharmony_ci 237062306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_ctr_aes = { 237162306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 237262306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 237362306a36Sopenharmony_ci .alg.aead = { 237462306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 237562306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 237662306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 237762306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 237862306a36Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 237962306a36Sopenharmony_ci .base = { 238062306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))", 238162306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha224-ctr-aes", 238262306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 238362306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 238462306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 238562306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 238662306a36Sopenharmony_ci .cra_blocksize = 1, 238762306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 238862306a36Sopenharmony_ci .cra_alignmask = 0, 238962306a36Sopenharmony_ci .cra_init = safexcel_aead_sha224_ctr_cra_init, 239062306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 239162306a36Sopenharmony_ci .cra_module = THIS_MODULE, 239262306a36Sopenharmony_ci }, 239362306a36Sopenharmony_ci }, 239462306a36Sopenharmony_ci}; 239562306a36Sopenharmony_ci 239662306a36Sopenharmony_cistatic int safexcel_aead_sha512_ctr_cra_init(struct crypto_tfm *tfm) 239762306a36Sopenharmony_ci{ 239862306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 239962306a36Sopenharmony_ci 240062306a36Sopenharmony_ci safexcel_aead_sha512_cra_init(tfm); 240162306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 240262306a36Sopenharmony_ci return 0; 240362306a36Sopenharmony_ci} 240462306a36Sopenharmony_ci 240562306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes = { 240662306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 240762306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 240862306a36Sopenharmony_ci .alg.aead = { 240962306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 241062306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 241162306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 241262306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 241362306a36Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 241462306a36Sopenharmony_ci .base = { 241562306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha512),rfc3686(ctr(aes)))", 241662306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha512-ctr-aes", 241762306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 241862306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 241962306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 242062306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 242162306a36Sopenharmony_ci .cra_blocksize = 1, 242262306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 242362306a36Sopenharmony_ci .cra_alignmask = 0, 242462306a36Sopenharmony_ci .cra_init = safexcel_aead_sha512_ctr_cra_init, 242562306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 242662306a36Sopenharmony_ci .cra_module = THIS_MODULE, 242762306a36Sopenharmony_ci }, 242862306a36Sopenharmony_ci }, 242962306a36Sopenharmony_ci}; 243062306a36Sopenharmony_ci 243162306a36Sopenharmony_cistatic int safexcel_aead_sha384_ctr_cra_init(struct crypto_tfm *tfm) 243262306a36Sopenharmony_ci{ 243362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 243462306a36Sopenharmony_ci 243562306a36Sopenharmony_ci safexcel_aead_sha384_cra_init(tfm); 243662306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 243762306a36Sopenharmony_ci return 0; 243862306a36Sopenharmony_ci} 243962306a36Sopenharmony_ci 244062306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes = { 244162306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 244262306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 244362306a36Sopenharmony_ci .alg.aead = { 244462306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 244562306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 244662306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 244762306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 244862306a36Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 244962306a36Sopenharmony_ci .base = { 245062306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha384),rfc3686(ctr(aes)))", 245162306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha384-ctr-aes", 245262306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 245362306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 245462306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 245562306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 245662306a36Sopenharmony_ci .cra_blocksize = 1, 245762306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 245862306a36Sopenharmony_ci .cra_alignmask = 0, 245962306a36Sopenharmony_ci .cra_init = safexcel_aead_sha384_ctr_cra_init, 246062306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 246162306a36Sopenharmony_ci .cra_module = THIS_MODULE, 246262306a36Sopenharmony_ci }, 246362306a36Sopenharmony_ci }, 246462306a36Sopenharmony_ci}; 246562306a36Sopenharmony_ci 246662306a36Sopenharmony_cistatic int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm, 246762306a36Sopenharmony_ci const u8 *key, unsigned int len) 246862306a36Sopenharmony_ci{ 246962306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 247062306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 247162306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 247262306a36Sopenharmony_ci struct crypto_aes_ctx aes; 247362306a36Sopenharmony_ci int ret, i; 247462306a36Sopenharmony_ci unsigned int keylen; 247562306a36Sopenharmony_ci 247662306a36Sopenharmony_ci /* Check for illegal XTS keys */ 247762306a36Sopenharmony_ci ret = xts_verify_key(ctfm, key, len); 247862306a36Sopenharmony_ci if (ret) 247962306a36Sopenharmony_ci return ret; 248062306a36Sopenharmony_ci 248162306a36Sopenharmony_ci /* Only half of the key data is cipher key */ 248262306a36Sopenharmony_ci keylen = (len >> 1); 248362306a36Sopenharmony_ci ret = aes_expandkey(&aes, key, keylen); 248462306a36Sopenharmony_ci if (ret) 248562306a36Sopenharmony_ci return ret; 248662306a36Sopenharmony_ci 248762306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 248862306a36Sopenharmony_ci for (i = 0; i < keylen / sizeof(u32); i++) { 248962306a36Sopenharmony_ci if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 249062306a36Sopenharmony_ci ctx->base.needs_inv = true; 249162306a36Sopenharmony_ci break; 249262306a36Sopenharmony_ci } 249362306a36Sopenharmony_ci } 249462306a36Sopenharmony_ci } 249562306a36Sopenharmony_ci 249662306a36Sopenharmony_ci for (i = 0; i < keylen / sizeof(u32); i++) 249762306a36Sopenharmony_ci ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 249862306a36Sopenharmony_ci 249962306a36Sopenharmony_ci /* The other half is the tweak key */ 250062306a36Sopenharmony_ci ret = aes_expandkey(&aes, (u8 *)(key + keylen), keylen); 250162306a36Sopenharmony_ci if (ret) 250262306a36Sopenharmony_ci return ret; 250362306a36Sopenharmony_ci 250462306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 250562306a36Sopenharmony_ci for (i = 0; i < keylen / sizeof(u32); i++) { 250662306a36Sopenharmony_ci if (le32_to_cpu(ctx->key[i + keylen / sizeof(u32)]) != 250762306a36Sopenharmony_ci aes.key_enc[i]) { 250862306a36Sopenharmony_ci ctx->base.needs_inv = true; 250962306a36Sopenharmony_ci break; 251062306a36Sopenharmony_ci } 251162306a36Sopenharmony_ci } 251262306a36Sopenharmony_ci } 251362306a36Sopenharmony_ci 251462306a36Sopenharmony_ci for (i = 0; i < keylen / sizeof(u32); i++) 251562306a36Sopenharmony_ci ctx->key[i + keylen / sizeof(u32)] = 251662306a36Sopenharmony_ci cpu_to_le32(aes.key_enc[i]); 251762306a36Sopenharmony_ci 251862306a36Sopenharmony_ci ctx->key_len = keylen << 1; 251962306a36Sopenharmony_ci 252062306a36Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 252162306a36Sopenharmony_ci return 0; 252262306a36Sopenharmony_ci} 252362306a36Sopenharmony_ci 252462306a36Sopenharmony_cistatic int safexcel_skcipher_aes_xts_cra_init(struct crypto_tfm *tfm) 252562306a36Sopenharmony_ci{ 252662306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 252762306a36Sopenharmony_ci 252862306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 252962306a36Sopenharmony_ci ctx->alg = SAFEXCEL_AES; 253062306a36Sopenharmony_ci ctx->blocksz = AES_BLOCK_SIZE; 253162306a36Sopenharmony_ci ctx->xts = 1; 253262306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS; 253362306a36Sopenharmony_ci return 0; 253462306a36Sopenharmony_ci} 253562306a36Sopenharmony_ci 253662306a36Sopenharmony_cistatic int safexcel_encrypt_xts(struct skcipher_request *req) 253762306a36Sopenharmony_ci{ 253862306a36Sopenharmony_ci if (req->cryptlen < XTS_BLOCK_SIZE) 253962306a36Sopenharmony_ci return -EINVAL; 254062306a36Sopenharmony_ci return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 254162306a36Sopenharmony_ci SAFEXCEL_ENCRYPT); 254262306a36Sopenharmony_ci} 254362306a36Sopenharmony_ci 254462306a36Sopenharmony_cistatic int safexcel_decrypt_xts(struct skcipher_request *req) 254562306a36Sopenharmony_ci{ 254662306a36Sopenharmony_ci if (req->cryptlen < XTS_BLOCK_SIZE) 254762306a36Sopenharmony_ci return -EINVAL; 254862306a36Sopenharmony_ci return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 254962306a36Sopenharmony_ci SAFEXCEL_DECRYPT); 255062306a36Sopenharmony_ci} 255162306a36Sopenharmony_ci 255262306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_xts_aes = { 255362306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 255462306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XTS, 255562306a36Sopenharmony_ci .alg.skcipher = { 255662306a36Sopenharmony_ci .setkey = safexcel_skcipher_aesxts_setkey, 255762306a36Sopenharmony_ci .encrypt = safexcel_encrypt_xts, 255862306a36Sopenharmony_ci .decrypt = safexcel_decrypt_xts, 255962306a36Sopenharmony_ci /* XTS actually uses 2 AES keys glued together */ 256062306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE * 2, 256162306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE * 2, 256262306a36Sopenharmony_ci .ivsize = XTS_BLOCK_SIZE, 256362306a36Sopenharmony_ci .base = { 256462306a36Sopenharmony_ci .cra_name = "xts(aes)", 256562306a36Sopenharmony_ci .cra_driver_name = "safexcel-xts-aes", 256662306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 256762306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 256862306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 256962306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 257062306a36Sopenharmony_ci .cra_blocksize = XTS_BLOCK_SIZE, 257162306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 257262306a36Sopenharmony_ci .cra_alignmask = 0, 257362306a36Sopenharmony_ci .cra_init = safexcel_skcipher_aes_xts_cra_init, 257462306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 257562306a36Sopenharmony_ci .cra_module = THIS_MODULE, 257662306a36Sopenharmony_ci }, 257762306a36Sopenharmony_ci }, 257862306a36Sopenharmony_ci}; 257962306a36Sopenharmony_ci 258062306a36Sopenharmony_cistatic int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, 258162306a36Sopenharmony_ci unsigned int len) 258262306a36Sopenharmony_ci{ 258362306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 258462306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 258562306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 258662306a36Sopenharmony_ci struct crypto_aes_ctx aes; 258762306a36Sopenharmony_ci u32 hashkey[AES_BLOCK_SIZE >> 2]; 258862306a36Sopenharmony_ci int ret, i; 258962306a36Sopenharmony_ci 259062306a36Sopenharmony_ci ret = aes_expandkey(&aes, key, len); 259162306a36Sopenharmony_ci if (ret) { 259262306a36Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 259362306a36Sopenharmony_ci return ret; 259462306a36Sopenharmony_ci } 259562306a36Sopenharmony_ci 259662306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 259762306a36Sopenharmony_ci for (i = 0; i < len / sizeof(u32); i++) { 259862306a36Sopenharmony_ci if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 259962306a36Sopenharmony_ci ctx->base.needs_inv = true; 260062306a36Sopenharmony_ci break; 260162306a36Sopenharmony_ci } 260262306a36Sopenharmony_ci } 260362306a36Sopenharmony_ci } 260462306a36Sopenharmony_ci 260562306a36Sopenharmony_ci for (i = 0; i < len / sizeof(u32); i++) 260662306a36Sopenharmony_ci ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 260762306a36Sopenharmony_ci 260862306a36Sopenharmony_ci ctx->key_len = len; 260962306a36Sopenharmony_ci 261062306a36Sopenharmony_ci /* Compute hash key by encrypting zeroes with cipher key */ 261162306a36Sopenharmony_ci memset(hashkey, 0, AES_BLOCK_SIZE); 261262306a36Sopenharmony_ci aes_encrypt(&aes, (u8 *)hashkey, (u8 *)hashkey); 261362306a36Sopenharmony_ci 261462306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 261562306a36Sopenharmony_ci for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) { 261662306a36Sopenharmony_ci if (be32_to_cpu(ctx->base.ipad.be[i]) != hashkey[i]) { 261762306a36Sopenharmony_ci ctx->base.needs_inv = true; 261862306a36Sopenharmony_ci break; 261962306a36Sopenharmony_ci } 262062306a36Sopenharmony_ci } 262162306a36Sopenharmony_ci } 262262306a36Sopenharmony_ci 262362306a36Sopenharmony_ci for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) 262462306a36Sopenharmony_ci ctx->base.ipad.be[i] = cpu_to_be32(hashkey[i]); 262562306a36Sopenharmony_ci 262662306a36Sopenharmony_ci memzero_explicit(hashkey, AES_BLOCK_SIZE); 262762306a36Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 262862306a36Sopenharmony_ci return 0; 262962306a36Sopenharmony_ci} 263062306a36Sopenharmony_ci 263162306a36Sopenharmony_cistatic int safexcel_aead_gcm_cra_init(struct crypto_tfm *tfm) 263262306a36Sopenharmony_ci{ 263362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 263462306a36Sopenharmony_ci 263562306a36Sopenharmony_ci safexcel_aead_cra_init(tfm); 263662306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_GHASH; 263762306a36Sopenharmony_ci ctx->state_sz = GHASH_BLOCK_SIZE; 263862306a36Sopenharmony_ci ctx->xcm = EIP197_XCM_MODE_GCM; 263962306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ 264062306a36Sopenharmony_ci 264162306a36Sopenharmony_ci return 0; 264262306a36Sopenharmony_ci} 264362306a36Sopenharmony_ci 264462306a36Sopenharmony_cistatic void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm) 264562306a36Sopenharmony_ci{ 264662306a36Sopenharmony_ci safexcel_aead_cra_exit(tfm); 264762306a36Sopenharmony_ci} 264862306a36Sopenharmony_ci 264962306a36Sopenharmony_cistatic int safexcel_aead_gcm_setauthsize(struct crypto_aead *tfm, 265062306a36Sopenharmony_ci unsigned int authsize) 265162306a36Sopenharmony_ci{ 265262306a36Sopenharmony_ci return crypto_gcm_check_authsize(authsize); 265362306a36Sopenharmony_ci} 265462306a36Sopenharmony_ci 265562306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_gcm = { 265662306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 265762306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 265862306a36Sopenharmony_ci .alg.aead = { 265962306a36Sopenharmony_ci .setkey = safexcel_aead_gcm_setkey, 266062306a36Sopenharmony_ci .setauthsize = safexcel_aead_gcm_setauthsize, 266162306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 266262306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 266362306a36Sopenharmony_ci .ivsize = GCM_AES_IV_SIZE, 266462306a36Sopenharmony_ci .maxauthsize = GHASH_DIGEST_SIZE, 266562306a36Sopenharmony_ci .base = { 266662306a36Sopenharmony_ci .cra_name = "gcm(aes)", 266762306a36Sopenharmony_ci .cra_driver_name = "safexcel-gcm-aes", 266862306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 266962306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 267062306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 267162306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 267262306a36Sopenharmony_ci .cra_blocksize = 1, 267362306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 267462306a36Sopenharmony_ci .cra_alignmask = 0, 267562306a36Sopenharmony_ci .cra_init = safexcel_aead_gcm_cra_init, 267662306a36Sopenharmony_ci .cra_exit = safexcel_aead_gcm_cra_exit, 267762306a36Sopenharmony_ci .cra_module = THIS_MODULE, 267862306a36Sopenharmony_ci }, 267962306a36Sopenharmony_ci }, 268062306a36Sopenharmony_ci}; 268162306a36Sopenharmony_ci 268262306a36Sopenharmony_cistatic int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, 268362306a36Sopenharmony_ci unsigned int len) 268462306a36Sopenharmony_ci{ 268562306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 268662306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 268762306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 268862306a36Sopenharmony_ci struct crypto_aes_ctx aes; 268962306a36Sopenharmony_ci int ret, i; 269062306a36Sopenharmony_ci 269162306a36Sopenharmony_ci ret = aes_expandkey(&aes, key, len); 269262306a36Sopenharmony_ci if (ret) { 269362306a36Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 269462306a36Sopenharmony_ci return ret; 269562306a36Sopenharmony_ci } 269662306a36Sopenharmony_ci 269762306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 269862306a36Sopenharmony_ci for (i = 0; i < len / sizeof(u32); i++) { 269962306a36Sopenharmony_ci if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 270062306a36Sopenharmony_ci ctx->base.needs_inv = true; 270162306a36Sopenharmony_ci break; 270262306a36Sopenharmony_ci } 270362306a36Sopenharmony_ci } 270462306a36Sopenharmony_ci } 270562306a36Sopenharmony_ci 270662306a36Sopenharmony_ci for (i = 0; i < len / sizeof(u32); i++) { 270762306a36Sopenharmony_ci ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 270862306a36Sopenharmony_ci ctx->base.ipad.be[i + 2 * AES_BLOCK_SIZE / sizeof(u32)] = 270962306a36Sopenharmony_ci cpu_to_be32(aes.key_enc[i]); 271062306a36Sopenharmony_ci } 271162306a36Sopenharmony_ci 271262306a36Sopenharmony_ci ctx->key_len = len; 271362306a36Sopenharmony_ci ctx->state_sz = 2 * AES_BLOCK_SIZE + len; 271462306a36Sopenharmony_ci 271562306a36Sopenharmony_ci if (len == AES_KEYSIZE_192) 271662306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192; 271762306a36Sopenharmony_ci else if (len == AES_KEYSIZE_256) 271862306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256; 271962306a36Sopenharmony_ci else 272062306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; 272162306a36Sopenharmony_ci 272262306a36Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 272362306a36Sopenharmony_ci return 0; 272462306a36Sopenharmony_ci} 272562306a36Sopenharmony_ci 272662306a36Sopenharmony_cistatic int safexcel_aead_ccm_cra_init(struct crypto_tfm *tfm) 272762306a36Sopenharmony_ci{ 272862306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 272962306a36Sopenharmony_ci 273062306a36Sopenharmony_ci safexcel_aead_cra_init(tfm); 273162306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; 273262306a36Sopenharmony_ci ctx->state_sz = 3 * AES_BLOCK_SIZE; 273362306a36Sopenharmony_ci ctx->xcm = EIP197_XCM_MODE_CCM; 273462306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ 273562306a36Sopenharmony_ci ctx->ctrinit = 0; 273662306a36Sopenharmony_ci return 0; 273762306a36Sopenharmony_ci} 273862306a36Sopenharmony_ci 273962306a36Sopenharmony_cistatic int safexcel_aead_ccm_setauthsize(struct crypto_aead *tfm, 274062306a36Sopenharmony_ci unsigned int authsize) 274162306a36Sopenharmony_ci{ 274262306a36Sopenharmony_ci /* Borrowed from crypto/ccm.c */ 274362306a36Sopenharmony_ci switch (authsize) { 274462306a36Sopenharmony_ci case 4: 274562306a36Sopenharmony_ci case 6: 274662306a36Sopenharmony_ci case 8: 274762306a36Sopenharmony_ci case 10: 274862306a36Sopenharmony_ci case 12: 274962306a36Sopenharmony_ci case 14: 275062306a36Sopenharmony_ci case 16: 275162306a36Sopenharmony_ci break; 275262306a36Sopenharmony_ci default: 275362306a36Sopenharmony_ci return -EINVAL; 275462306a36Sopenharmony_ci } 275562306a36Sopenharmony_ci 275662306a36Sopenharmony_ci return 0; 275762306a36Sopenharmony_ci} 275862306a36Sopenharmony_ci 275962306a36Sopenharmony_cistatic int safexcel_ccm_encrypt(struct aead_request *req) 276062306a36Sopenharmony_ci{ 276162306a36Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 276262306a36Sopenharmony_ci 276362306a36Sopenharmony_ci if (req->iv[0] < 1 || req->iv[0] > 7) 276462306a36Sopenharmony_ci return -EINVAL; 276562306a36Sopenharmony_ci 276662306a36Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 276762306a36Sopenharmony_ci} 276862306a36Sopenharmony_ci 276962306a36Sopenharmony_cistatic int safexcel_ccm_decrypt(struct aead_request *req) 277062306a36Sopenharmony_ci{ 277162306a36Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 277262306a36Sopenharmony_ci 277362306a36Sopenharmony_ci if (req->iv[0] < 1 || req->iv[0] > 7) 277462306a36Sopenharmony_ci return -EINVAL; 277562306a36Sopenharmony_ci 277662306a36Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 277762306a36Sopenharmony_ci} 277862306a36Sopenharmony_ci 277962306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ccm = { 278062306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 278162306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, 278262306a36Sopenharmony_ci .alg.aead = { 278362306a36Sopenharmony_ci .setkey = safexcel_aead_ccm_setkey, 278462306a36Sopenharmony_ci .setauthsize = safexcel_aead_ccm_setauthsize, 278562306a36Sopenharmony_ci .encrypt = safexcel_ccm_encrypt, 278662306a36Sopenharmony_ci .decrypt = safexcel_ccm_decrypt, 278762306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 278862306a36Sopenharmony_ci .maxauthsize = AES_BLOCK_SIZE, 278962306a36Sopenharmony_ci .base = { 279062306a36Sopenharmony_ci .cra_name = "ccm(aes)", 279162306a36Sopenharmony_ci .cra_driver_name = "safexcel-ccm-aes", 279262306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 279362306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 279462306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 279562306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 279662306a36Sopenharmony_ci .cra_blocksize = 1, 279762306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 279862306a36Sopenharmony_ci .cra_alignmask = 0, 279962306a36Sopenharmony_ci .cra_init = safexcel_aead_ccm_cra_init, 280062306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 280162306a36Sopenharmony_ci .cra_module = THIS_MODULE, 280262306a36Sopenharmony_ci }, 280362306a36Sopenharmony_ci }, 280462306a36Sopenharmony_ci}; 280562306a36Sopenharmony_ci 280662306a36Sopenharmony_cistatic void safexcel_chacha20_setkey(struct safexcel_cipher_ctx *ctx, 280762306a36Sopenharmony_ci const u8 *key) 280862306a36Sopenharmony_ci{ 280962306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 281062306a36Sopenharmony_ci 281162306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 281262306a36Sopenharmony_ci if (memcmp(ctx->key, key, CHACHA_KEY_SIZE)) 281362306a36Sopenharmony_ci ctx->base.needs_inv = true; 281462306a36Sopenharmony_ci 281562306a36Sopenharmony_ci memcpy(ctx->key, key, CHACHA_KEY_SIZE); 281662306a36Sopenharmony_ci ctx->key_len = CHACHA_KEY_SIZE; 281762306a36Sopenharmony_ci} 281862306a36Sopenharmony_ci 281962306a36Sopenharmony_cistatic int safexcel_skcipher_chacha20_setkey(struct crypto_skcipher *ctfm, 282062306a36Sopenharmony_ci const u8 *key, unsigned int len) 282162306a36Sopenharmony_ci{ 282262306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 282362306a36Sopenharmony_ci 282462306a36Sopenharmony_ci if (len != CHACHA_KEY_SIZE) 282562306a36Sopenharmony_ci return -EINVAL; 282662306a36Sopenharmony_ci 282762306a36Sopenharmony_ci safexcel_chacha20_setkey(ctx, key); 282862306a36Sopenharmony_ci 282962306a36Sopenharmony_ci return 0; 283062306a36Sopenharmony_ci} 283162306a36Sopenharmony_ci 283262306a36Sopenharmony_cistatic int safexcel_skcipher_chacha20_cra_init(struct crypto_tfm *tfm) 283362306a36Sopenharmony_ci{ 283462306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 283562306a36Sopenharmony_ci 283662306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 283762306a36Sopenharmony_ci ctx->alg = SAFEXCEL_CHACHA20; 283862306a36Sopenharmony_ci ctx->ctrinit = 0; 283962306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32; 284062306a36Sopenharmony_ci return 0; 284162306a36Sopenharmony_ci} 284262306a36Sopenharmony_ci 284362306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_chacha20 = { 284462306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 284562306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_CHACHA20, 284662306a36Sopenharmony_ci .alg.skcipher = { 284762306a36Sopenharmony_ci .setkey = safexcel_skcipher_chacha20_setkey, 284862306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 284962306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 285062306a36Sopenharmony_ci .min_keysize = CHACHA_KEY_SIZE, 285162306a36Sopenharmony_ci .max_keysize = CHACHA_KEY_SIZE, 285262306a36Sopenharmony_ci .ivsize = CHACHA_IV_SIZE, 285362306a36Sopenharmony_ci .base = { 285462306a36Sopenharmony_ci .cra_name = "chacha20", 285562306a36Sopenharmony_ci .cra_driver_name = "safexcel-chacha20", 285662306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 285762306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 285862306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 285962306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 286062306a36Sopenharmony_ci .cra_blocksize = 1, 286162306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 286262306a36Sopenharmony_ci .cra_alignmask = 0, 286362306a36Sopenharmony_ci .cra_init = safexcel_skcipher_chacha20_cra_init, 286462306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 286562306a36Sopenharmony_ci .cra_module = THIS_MODULE, 286662306a36Sopenharmony_ci }, 286762306a36Sopenharmony_ci }, 286862306a36Sopenharmony_ci}; 286962306a36Sopenharmony_ci 287062306a36Sopenharmony_cistatic int safexcel_aead_chachapoly_setkey(struct crypto_aead *ctfm, 287162306a36Sopenharmony_ci const u8 *key, unsigned int len) 287262306a36Sopenharmony_ci{ 287362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_aead_ctx(ctfm); 287462306a36Sopenharmony_ci 287562306a36Sopenharmony_ci if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP && 287662306a36Sopenharmony_ci len > EIP197_AEAD_IPSEC_NONCE_SIZE) { 287762306a36Sopenharmony_ci /* ESP variant has nonce appended to key */ 287862306a36Sopenharmony_ci len -= EIP197_AEAD_IPSEC_NONCE_SIZE; 287962306a36Sopenharmony_ci ctx->nonce = *(u32 *)(key + len); 288062306a36Sopenharmony_ci } 288162306a36Sopenharmony_ci if (len != CHACHA_KEY_SIZE) 288262306a36Sopenharmony_ci return -EINVAL; 288362306a36Sopenharmony_ci 288462306a36Sopenharmony_ci safexcel_chacha20_setkey(ctx, key); 288562306a36Sopenharmony_ci 288662306a36Sopenharmony_ci return 0; 288762306a36Sopenharmony_ci} 288862306a36Sopenharmony_ci 288962306a36Sopenharmony_cistatic int safexcel_aead_chachapoly_setauthsize(struct crypto_aead *tfm, 289062306a36Sopenharmony_ci unsigned int authsize) 289162306a36Sopenharmony_ci{ 289262306a36Sopenharmony_ci if (authsize != POLY1305_DIGEST_SIZE) 289362306a36Sopenharmony_ci return -EINVAL; 289462306a36Sopenharmony_ci return 0; 289562306a36Sopenharmony_ci} 289662306a36Sopenharmony_ci 289762306a36Sopenharmony_cistatic int safexcel_aead_chachapoly_crypt(struct aead_request *req, 289862306a36Sopenharmony_ci enum safexcel_cipher_direction dir) 289962306a36Sopenharmony_ci{ 290062306a36Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 290162306a36Sopenharmony_ci struct crypto_aead *aead = crypto_aead_reqtfm(req); 290262306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(aead); 290362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 290462306a36Sopenharmony_ci struct aead_request *subreq = aead_request_ctx(req); 290562306a36Sopenharmony_ci u32 key[CHACHA_KEY_SIZE / sizeof(u32) + 1]; 290662306a36Sopenharmony_ci int ret = 0; 290762306a36Sopenharmony_ci 290862306a36Sopenharmony_ci /* 290962306a36Sopenharmony_ci * Instead of wasting time detecting umpteen silly corner cases, 291062306a36Sopenharmony_ci * just dump all "small" requests to the fallback implementation. 291162306a36Sopenharmony_ci * HW would not be faster on such small requests anyway. 291262306a36Sopenharmony_ci */ 291362306a36Sopenharmony_ci if (likely((ctx->aead != EIP197_AEAD_TYPE_IPSEC_ESP || 291462306a36Sopenharmony_ci req->assoclen >= EIP197_AEAD_IPSEC_IV_SIZE) && 291562306a36Sopenharmony_ci req->cryptlen > POLY1305_DIGEST_SIZE)) { 291662306a36Sopenharmony_ci return safexcel_queue_req(&req->base, creq, dir); 291762306a36Sopenharmony_ci } 291862306a36Sopenharmony_ci 291962306a36Sopenharmony_ci /* HW cannot do full (AAD+payload) zero length, use fallback */ 292062306a36Sopenharmony_ci memcpy(key, ctx->key, CHACHA_KEY_SIZE); 292162306a36Sopenharmony_ci if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 292262306a36Sopenharmony_ci /* ESP variant has nonce appended to the key */ 292362306a36Sopenharmony_ci key[CHACHA_KEY_SIZE / sizeof(u32)] = ctx->nonce; 292462306a36Sopenharmony_ci ret = crypto_aead_setkey(ctx->fback, (u8 *)key, 292562306a36Sopenharmony_ci CHACHA_KEY_SIZE + 292662306a36Sopenharmony_ci EIP197_AEAD_IPSEC_NONCE_SIZE); 292762306a36Sopenharmony_ci } else { 292862306a36Sopenharmony_ci ret = crypto_aead_setkey(ctx->fback, (u8 *)key, 292962306a36Sopenharmony_ci CHACHA_KEY_SIZE); 293062306a36Sopenharmony_ci } 293162306a36Sopenharmony_ci if (ret) { 293262306a36Sopenharmony_ci crypto_aead_clear_flags(aead, CRYPTO_TFM_REQ_MASK); 293362306a36Sopenharmony_ci crypto_aead_set_flags(aead, crypto_aead_get_flags(ctx->fback) & 293462306a36Sopenharmony_ci CRYPTO_TFM_REQ_MASK); 293562306a36Sopenharmony_ci return ret; 293662306a36Sopenharmony_ci } 293762306a36Sopenharmony_ci 293862306a36Sopenharmony_ci aead_request_set_tfm(subreq, ctx->fback); 293962306a36Sopenharmony_ci aead_request_set_callback(subreq, req->base.flags, req->base.complete, 294062306a36Sopenharmony_ci req->base.data); 294162306a36Sopenharmony_ci aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 294262306a36Sopenharmony_ci req->iv); 294362306a36Sopenharmony_ci aead_request_set_ad(subreq, req->assoclen); 294462306a36Sopenharmony_ci 294562306a36Sopenharmony_ci return (dir == SAFEXCEL_ENCRYPT) ? 294662306a36Sopenharmony_ci crypto_aead_encrypt(subreq) : 294762306a36Sopenharmony_ci crypto_aead_decrypt(subreq); 294862306a36Sopenharmony_ci} 294962306a36Sopenharmony_ci 295062306a36Sopenharmony_cistatic int safexcel_aead_chachapoly_encrypt(struct aead_request *req) 295162306a36Sopenharmony_ci{ 295262306a36Sopenharmony_ci return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_ENCRYPT); 295362306a36Sopenharmony_ci} 295462306a36Sopenharmony_ci 295562306a36Sopenharmony_cistatic int safexcel_aead_chachapoly_decrypt(struct aead_request *req) 295662306a36Sopenharmony_ci{ 295762306a36Sopenharmony_ci return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_DECRYPT); 295862306a36Sopenharmony_ci} 295962306a36Sopenharmony_ci 296062306a36Sopenharmony_cistatic int safexcel_aead_fallback_cra_init(struct crypto_tfm *tfm) 296162306a36Sopenharmony_ci{ 296262306a36Sopenharmony_ci struct crypto_aead *aead = __crypto_aead_cast(tfm); 296362306a36Sopenharmony_ci struct aead_alg *alg = crypto_aead_alg(aead); 296462306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 296562306a36Sopenharmony_ci 296662306a36Sopenharmony_ci safexcel_aead_cra_init(tfm); 296762306a36Sopenharmony_ci 296862306a36Sopenharmony_ci /* Allocate fallback implementation */ 296962306a36Sopenharmony_ci ctx->fback = crypto_alloc_aead(alg->base.cra_name, 0, 297062306a36Sopenharmony_ci CRYPTO_ALG_ASYNC | 297162306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK); 297262306a36Sopenharmony_ci if (IS_ERR(ctx->fback)) 297362306a36Sopenharmony_ci return PTR_ERR(ctx->fback); 297462306a36Sopenharmony_ci 297562306a36Sopenharmony_ci crypto_aead_set_reqsize(aead, max(sizeof(struct safexcel_cipher_req), 297662306a36Sopenharmony_ci sizeof(struct aead_request) + 297762306a36Sopenharmony_ci crypto_aead_reqsize(ctx->fback))); 297862306a36Sopenharmony_ci 297962306a36Sopenharmony_ci return 0; 298062306a36Sopenharmony_ci} 298162306a36Sopenharmony_ci 298262306a36Sopenharmony_cistatic int safexcel_aead_chachapoly_cra_init(struct crypto_tfm *tfm) 298362306a36Sopenharmony_ci{ 298462306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 298562306a36Sopenharmony_ci 298662306a36Sopenharmony_ci safexcel_aead_fallback_cra_init(tfm); 298762306a36Sopenharmony_ci ctx->alg = SAFEXCEL_CHACHA20; 298862306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32 | 298962306a36Sopenharmony_ci CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK; 299062306a36Sopenharmony_ci ctx->ctrinit = 0; 299162306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_POLY1305; 299262306a36Sopenharmony_ci ctx->state_sz = 0; /* Precomputed by HW */ 299362306a36Sopenharmony_ci return 0; 299462306a36Sopenharmony_ci} 299562306a36Sopenharmony_ci 299662306a36Sopenharmony_cistatic void safexcel_aead_fallback_cra_exit(struct crypto_tfm *tfm) 299762306a36Sopenharmony_ci{ 299862306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 299962306a36Sopenharmony_ci 300062306a36Sopenharmony_ci crypto_free_aead(ctx->fback); 300162306a36Sopenharmony_ci safexcel_aead_cra_exit(tfm); 300262306a36Sopenharmony_ci} 300362306a36Sopenharmony_ci 300462306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_chachapoly = { 300562306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 300662306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, 300762306a36Sopenharmony_ci .alg.aead = { 300862306a36Sopenharmony_ci .setkey = safexcel_aead_chachapoly_setkey, 300962306a36Sopenharmony_ci .setauthsize = safexcel_aead_chachapoly_setauthsize, 301062306a36Sopenharmony_ci .encrypt = safexcel_aead_chachapoly_encrypt, 301162306a36Sopenharmony_ci .decrypt = safexcel_aead_chachapoly_decrypt, 301262306a36Sopenharmony_ci .ivsize = CHACHAPOLY_IV_SIZE, 301362306a36Sopenharmony_ci .maxauthsize = POLY1305_DIGEST_SIZE, 301462306a36Sopenharmony_ci .base = { 301562306a36Sopenharmony_ci .cra_name = "rfc7539(chacha20,poly1305)", 301662306a36Sopenharmony_ci .cra_driver_name = "safexcel-chacha20-poly1305", 301762306a36Sopenharmony_ci /* +1 to put it above HW chacha + SW poly */ 301862306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, 301962306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 302062306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 302162306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY | 302262306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 302362306a36Sopenharmony_ci .cra_blocksize = 1, 302462306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 302562306a36Sopenharmony_ci .cra_alignmask = 0, 302662306a36Sopenharmony_ci .cra_init = safexcel_aead_chachapoly_cra_init, 302762306a36Sopenharmony_ci .cra_exit = safexcel_aead_fallback_cra_exit, 302862306a36Sopenharmony_ci .cra_module = THIS_MODULE, 302962306a36Sopenharmony_ci }, 303062306a36Sopenharmony_ci }, 303162306a36Sopenharmony_ci}; 303262306a36Sopenharmony_ci 303362306a36Sopenharmony_cistatic int safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm *tfm) 303462306a36Sopenharmony_ci{ 303562306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 303662306a36Sopenharmony_ci int ret; 303762306a36Sopenharmony_ci 303862306a36Sopenharmony_ci ret = safexcel_aead_chachapoly_cra_init(tfm); 303962306a36Sopenharmony_ci ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 304062306a36Sopenharmony_ci ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 304162306a36Sopenharmony_ci return ret; 304262306a36Sopenharmony_ci} 304362306a36Sopenharmony_ci 304462306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_chachapoly_esp = { 304562306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 304662306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, 304762306a36Sopenharmony_ci .alg.aead = { 304862306a36Sopenharmony_ci .setkey = safexcel_aead_chachapoly_setkey, 304962306a36Sopenharmony_ci .setauthsize = safexcel_aead_chachapoly_setauthsize, 305062306a36Sopenharmony_ci .encrypt = safexcel_aead_chachapoly_encrypt, 305162306a36Sopenharmony_ci .decrypt = safexcel_aead_chachapoly_decrypt, 305262306a36Sopenharmony_ci .ivsize = CHACHAPOLY_IV_SIZE - EIP197_AEAD_IPSEC_NONCE_SIZE, 305362306a36Sopenharmony_ci .maxauthsize = POLY1305_DIGEST_SIZE, 305462306a36Sopenharmony_ci .base = { 305562306a36Sopenharmony_ci .cra_name = "rfc7539esp(chacha20,poly1305)", 305662306a36Sopenharmony_ci .cra_driver_name = "safexcel-chacha20-poly1305-esp", 305762306a36Sopenharmony_ci /* +1 to put it above HW chacha + SW poly */ 305862306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, 305962306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 306062306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 306162306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY | 306262306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 306362306a36Sopenharmony_ci .cra_blocksize = 1, 306462306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 306562306a36Sopenharmony_ci .cra_alignmask = 0, 306662306a36Sopenharmony_ci .cra_init = safexcel_aead_chachapolyesp_cra_init, 306762306a36Sopenharmony_ci .cra_exit = safexcel_aead_fallback_cra_exit, 306862306a36Sopenharmony_ci .cra_module = THIS_MODULE, 306962306a36Sopenharmony_ci }, 307062306a36Sopenharmony_ci }, 307162306a36Sopenharmony_ci}; 307262306a36Sopenharmony_ci 307362306a36Sopenharmony_cistatic int safexcel_skcipher_sm4_setkey(struct crypto_skcipher *ctfm, 307462306a36Sopenharmony_ci const u8 *key, unsigned int len) 307562306a36Sopenharmony_ci{ 307662306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 307762306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 307862306a36Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 307962306a36Sopenharmony_ci 308062306a36Sopenharmony_ci if (len != SM4_KEY_SIZE) 308162306a36Sopenharmony_ci return -EINVAL; 308262306a36Sopenharmony_ci 308362306a36Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 308462306a36Sopenharmony_ci if (memcmp(ctx->key, key, SM4_KEY_SIZE)) 308562306a36Sopenharmony_ci ctx->base.needs_inv = true; 308662306a36Sopenharmony_ci 308762306a36Sopenharmony_ci memcpy(ctx->key, key, SM4_KEY_SIZE); 308862306a36Sopenharmony_ci ctx->key_len = SM4_KEY_SIZE; 308962306a36Sopenharmony_ci 309062306a36Sopenharmony_ci return 0; 309162306a36Sopenharmony_ci} 309262306a36Sopenharmony_ci 309362306a36Sopenharmony_cistatic int safexcel_sm4_blk_encrypt(struct skcipher_request *req) 309462306a36Sopenharmony_ci{ 309562306a36Sopenharmony_ci /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 309662306a36Sopenharmony_ci if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 309762306a36Sopenharmony_ci return -EINVAL; 309862306a36Sopenharmony_ci else 309962306a36Sopenharmony_ci return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 310062306a36Sopenharmony_ci SAFEXCEL_ENCRYPT); 310162306a36Sopenharmony_ci} 310262306a36Sopenharmony_ci 310362306a36Sopenharmony_cistatic int safexcel_sm4_blk_decrypt(struct skcipher_request *req) 310462306a36Sopenharmony_ci{ 310562306a36Sopenharmony_ci /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 310662306a36Sopenharmony_ci if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 310762306a36Sopenharmony_ci return -EINVAL; 310862306a36Sopenharmony_ci else 310962306a36Sopenharmony_ci return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 311062306a36Sopenharmony_ci SAFEXCEL_DECRYPT); 311162306a36Sopenharmony_ci} 311262306a36Sopenharmony_ci 311362306a36Sopenharmony_cistatic int safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm *tfm) 311462306a36Sopenharmony_ci{ 311562306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 311662306a36Sopenharmony_ci 311762306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 311862306a36Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 311962306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 312062306a36Sopenharmony_ci ctx->blocksz = 0; 312162306a36Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 312262306a36Sopenharmony_ci return 0; 312362306a36Sopenharmony_ci} 312462306a36Sopenharmony_ci 312562306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ecb_sm4 = { 312662306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 312762306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4, 312862306a36Sopenharmony_ci .alg.skcipher = { 312962306a36Sopenharmony_ci .setkey = safexcel_skcipher_sm4_setkey, 313062306a36Sopenharmony_ci .encrypt = safexcel_sm4_blk_encrypt, 313162306a36Sopenharmony_ci .decrypt = safexcel_sm4_blk_decrypt, 313262306a36Sopenharmony_ci .min_keysize = SM4_KEY_SIZE, 313362306a36Sopenharmony_ci .max_keysize = SM4_KEY_SIZE, 313462306a36Sopenharmony_ci .base = { 313562306a36Sopenharmony_ci .cra_name = "ecb(sm4)", 313662306a36Sopenharmony_ci .cra_driver_name = "safexcel-ecb-sm4", 313762306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 313862306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 313962306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 314062306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 314162306a36Sopenharmony_ci .cra_blocksize = SM4_BLOCK_SIZE, 314262306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 314362306a36Sopenharmony_ci .cra_alignmask = 0, 314462306a36Sopenharmony_ci .cra_init = safexcel_skcipher_sm4_ecb_cra_init, 314562306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 314662306a36Sopenharmony_ci .cra_module = THIS_MODULE, 314762306a36Sopenharmony_ci }, 314862306a36Sopenharmony_ci }, 314962306a36Sopenharmony_ci}; 315062306a36Sopenharmony_ci 315162306a36Sopenharmony_cistatic int safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm *tfm) 315262306a36Sopenharmony_ci{ 315362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 315462306a36Sopenharmony_ci 315562306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 315662306a36Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 315762306a36Sopenharmony_ci ctx->blocksz = SM4_BLOCK_SIZE; 315862306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 315962306a36Sopenharmony_ci return 0; 316062306a36Sopenharmony_ci} 316162306a36Sopenharmony_ci 316262306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cbc_sm4 = { 316362306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 316462306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4, 316562306a36Sopenharmony_ci .alg.skcipher = { 316662306a36Sopenharmony_ci .setkey = safexcel_skcipher_sm4_setkey, 316762306a36Sopenharmony_ci .encrypt = safexcel_sm4_blk_encrypt, 316862306a36Sopenharmony_ci .decrypt = safexcel_sm4_blk_decrypt, 316962306a36Sopenharmony_ci .min_keysize = SM4_KEY_SIZE, 317062306a36Sopenharmony_ci .max_keysize = SM4_KEY_SIZE, 317162306a36Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 317262306a36Sopenharmony_ci .base = { 317362306a36Sopenharmony_ci .cra_name = "cbc(sm4)", 317462306a36Sopenharmony_ci .cra_driver_name = "safexcel-cbc-sm4", 317562306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 317662306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 317762306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 317862306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 317962306a36Sopenharmony_ci .cra_blocksize = SM4_BLOCK_SIZE, 318062306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 318162306a36Sopenharmony_ci .cra_alignmask = 0, 318262306a36Sopenharmony_ci .cra_init = safexcel_skcipher_sm4_cbc_cra_init, 318362306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 318462306a36Sopenharmony_ci .cra_module = THIS_MODULE, 318562306a36Sopenharmony_ci }, 318662306a36Sopenharmony_ci }, 318762306a36Sopenharmony_ci}; 318862306a36Sopenharmony_ci 318962306a36Sopenharmony_cistatic int safexcel_skcipher_sm4_ofb_cra_init(struct crypto_tfm *tfm) 319062306a36Sopenharmony_ci{ 319162306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 319262306a36Sopenharmony_ci 319362306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 319462306a36Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 319562306a36Sopenharmony_ci ctx->blocksz = SM4_BLOCK_SIZE; 319662306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; 319762306a36Sopenharmony_ci return 0; 319862306a36Sopenharmony_ci} 319962306a36Sopenharmony_ci 320062306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ofb_sm4 = { 320162306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 320262306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, 320362306a36Sopenharmony_ci .alg.skcipher = { 320462306a36Sopenharmony_ci .setkey = safexcel_skcipher_sm4_setkey, 320562306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 320662306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 320762306a36Sopenharmony_ci .min_keysize = SM4_KEY_SIZE, 320862306a36Sopenharmony_ci .max_keysize = SM4_KEY_SIZE, 320962306a36Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 321062306a36Sopenharmony_ci .base = { 321162306a36Sopenharmony_ci .cra_name = "ofb(sm4)", 321262306a36Sopenharmony_ci .cra_driver_name = "safexcel-ofb-sm4", 321362306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 321462306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 321562306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 321662306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 321762306a36Sopenharmony_ci .cra_blocksize = 1, 321862306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 321962306a36Sopenharmony_ci .cra_alignmask = 0, 322062306a36Sopenharmony_ci .cra_init = safexcel_skcipher_sm4_ofb_cra_init, 322162306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 322262306a36Sopenharmony_ci .cra_module = THIS_MODULE, 322362306a36Sopenharmony_ci }, 322462306a36Sopenharmony_ci }, 322562306a36Sopenharmony_ci}; 322662306a36Sopenharmony_ci 322762306a36Sopenharmony_cistatic int safexcel_skcipher_sm4_cfb_cra_init(struct crypto_tfm *tfm) 322862306a36Sopenharmony_ci{ 322962306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 323062306a36Sopenharmony_ci 323162306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 323262306a36Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 323362306a36Sopenharmony_ci ctx->blocksz = SM4_BLOCK_SIZE; 323462306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; 323562306a36Sopenharmony_ci return 0; 323662306a36Sopenharmony_ci} 323762306a36Sopenharmony_ci 323862306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cfb_sm4 = { 323962306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 324062306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, 324162306a36Sopenharmony_ci .alg.skcipher = { 324262306a36Sopenharmony_ci .setkey = safexcel_skcipher_sm4_setkey, 324362306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 324462306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 324562306a36Sopenharmony_ci .min_keysize = SM4_KEY_SIZE, 324662306a36Sopenharmony_ci .max_keysize = SM4_KEY_SIZE, 324762306a36Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 324862306a36Sopenharmony_ci .base = { 324962306a36Sopenharmony_ci .cra_name = "cfb(sm4)", 325062306a36Sopenharmony_ci .cra_driver_name = "safexcel-cfb-sm4", 325162306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 325262306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 325362306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 325462306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 325562306a36Sopenharmony_ci .cra_blocksize = 1, 325662306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 325762306a36Sopenharmony_ci .cra_alignmask = 0, 325862306a36Sopenharmony_ci .cra_init = safexcel_skcipher_sm4_cfb_cra_init, 325962306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 326062306a36Sopenharmony_ci .cra_module = THIS_MODULE, 326162306a36Sopenharmony_ci }, 326262306a36Sopenharmony_ci }, 326362306a36Sopenharmony_ci}; 326462306a36Sopenharmony_ci 326562306a36Sopenharmony_cistatic int safexcel_skcipher_sm4ctr_setkey(struct crypto_skcipher *ctfm, 326662306a36Sopenharmony_ci const u8 *key, unsigned int len) 326762306a36Sopenharmony_ci{ 326862306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 326962306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 327062306a36Sopenharmony_ci 327162306a36Sopenharmony_ci /* last 4 bytes of key are the nonce! */ 327262306a36Sopenharmony_ci ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 327362306a36Sopenharmony_ci /* exclude the nonce here */ 327462306a36Sopenharmony_ci len -= CTR_RFC3686_NONCE_SIZE; 327562306a36Sopenharmony_ci 327662306a36Sopenharmony_ci return safexcel_skcipher_sm4_setkey(ctfm, key, len); 327762306a36Sopenharmony_ci} 327862306a36Sopenharmony_ci 327962306a36Sopenharmony_cistatic int safexcel_skcipher_sm4_ctr_cra_init(struct crypto_tfm *tfm) 328062306a36Sopenharmony_ci{ 328162306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 328262306a36Sopenharmony_ci 328362306a36Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 328462306a36Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 328562306a36Sopenharmony_ci ctx->blocksz = SM4_BLOCK_SIZE; 328662306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 328762306a36Sopenharmony_ci return 0; 328862306a36Sopenharmony_ci} 328962306a36Sopenharmony_ci 329062306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ctr_sm4 = { 329162306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 329262306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4, 329362306a36Sopenharmony_ci .alg.skcipher = { 329462306a36Sopenharmony_ci .setkey = safexcel_skcipher_sm4ctr_setkey, 329562306a36Sopenharmony_ci .encrypt = safexcel_encrypt, 329662306a36Sopenharmony_ci .decrypt = safexcel_decrypt, 329762306a36Sopenharmony_ci /* Add nonce size */ 329862306a36Sopenharmony_ci .min_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 329962306a36Sopenharmony_ci .max_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 330062306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 330162306a36Sopenharmony_ci .base = { 330262306a36Sopenharmony_ci .cra_name = "rfc3686(ctr(sm4))", 330362306a36Sopenharmony_ci .cra_driver_name = "safexcel-ctr-sm4", 330462306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 330562306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 330662306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 330762306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 330862306a36Sopenharmony_ci .cra_blocksize = 1, 330962306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 331062306a36Sopenharmony_ci .cra_alignmask = 0, 331162306a36Sopenharmony_ci .cra_init = safexcel_skcipher_sm4_ctr_cra_init, 331262306a36Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 331362306a36Sopenharmony_ci .cra_module = THIS_MODULE, 331462306a36Sopenharmony_ci }, 331562306a36Sopenharmony_ci }, 331662306a36Sopenharmony_ci}; 331762306a36Sopenharmony_ci 331862306a36Sopenharmony_cistatic int safexcel_aead_sm4_blk_encrypt(struct aead_request *req) 331962306a36Sopenharmony_ci{ 332062306a36Sopenharmony_ci /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 332162306a36Sopenharmony_ci if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 332262306a36Sopenharmony_ci return -EINVAL; 332362306a36Sopenharmony_ci 332462306a36Sopenharmony_ci return safexcel_queue_req(&req->base, aead_request_ctx(req), 332562306a36Sopenharmony_ci SAFEXCEL_ENCRYPT); 332662306a36Sopenharmony_ci} 332762306a36Sopenharmony_ci 332862306a36Sopenharmony_cistatic int safexcel_aead_sm4_blk_decrypt(struct aead_request *req) 332962306a36Sopenharmony_ci{ 333062306a36Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 333162306a36Sopenharmony_ci 333262306a36Sopenharmony_ci /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 333362306a36Sopenharmony_ci if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) 333462306a36Sopenharmony_ci return -EINVAL; 333562306a36Sopenharmony_ci 333662306a36Sopenharmony_ci return safexcel_queue_req(&req->base, aead_request_ctx(req), 333762306a36Sopenharmony_ci SAFEXCEL_DECRYPT); 333862306a36Sopenharmony_ci} 333962306a36Sopenharmony_ci 334062306a36Sopenharmony_cistatic int safexcel_aead_sm4cbc_sha1_cra_init(struct crypto_tfm *tfm) 334162306a36Sopenharmony_ci{ 334262306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 334362306a36Sopenharmony_ci 334462306a36Sopenharmony_ci safexcel_aead_cra_init(tfm); 334562306a36Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 334662306a36Sopenharmony_ci ctx->blocksz = SM4_BLOCK_SIZE; 334762306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; 334862306a36Sopenharmony_ci ctx->state_sz = SHA1_DIGEST_SIZE; 334962306a36Sopenharmony_ci return 0; 335062306a36Sopenharmony_ci} 335162306a36Sopenharmony_ci 335262306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4 = { 335362306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 335462306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, 335562306a36Sopenharmony_ci .alg.aead = { 335662306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 335762306a36Sopenharmony_ci .encrypt = safexcel_aead_sm4_blk_encrypt, 335862306a36Sopenharmony_ci .decrypt = safexcel_aead_sm4_blk_decrypt, 335962306a36Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 336062306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 336162306a36Sopenharmony_ci .base = { 336262306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha1),cbc(sm4))", 336362306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-sm4", 336462306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 336562306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 336662306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 336762306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 336862306a36Sopenharmony_ci .cra_blocksize = SM4_BLOCK_SIZE, 336962306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 337062306a36Sopenharmony_ci .cra_alignmask = 0, 337162306a36Sopenharmony_ci .cra_init = safexcel_aead_sm4cbc_sha1_cra_init, 337262306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 337362306a36Sopenharmony_ci .cra_module = THIS_MODULE, 337462306a36Sopenharmony_ci }, 337562306a36Sopenharmony_ci }, 337662306a36Sopenharmony_ci}; 337762306a36Sopenharmony_ci 337862306a36Sopenharmony_cistatic int safexcel_aead_fallback_setkey(struct crypto_aead *ctfm, 337962306a36Sopenharmony_ci const u8 *key, unsigned int len) 338062306a36Sopenharmony_ci{ 338162306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 338262306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 338362306a36Sopenharmony_ci 338462306a36Sopenharmony_ci /* Keep fallback cipher synchronized */ 338562306a36Sopenharmony_ci return crypto_aead_setkey(ctx->fback, (u8 *)key, len) ?: 338662306a36Sopenharmony_ci safexcel_aead_setkey(ctfm, key, len); 338762306a36Sopenharmony_ci} 338862306a36Sopenharmony_ci 338962306a36Sopenharmony_cistatic int safexcel_aead_fallback_setauthsize(struct crypto_aead *ctfm, 339062306a36Sopenharmony_ci unsigned int authsize) 339162306a36Sopenharmony_ci{ 339262306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 339362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 339462306a36Sopenharmony_ci 339562306a36Sopenharmony_ci /* Keep fallback cipher synchronized */ 339662306a36Sopenharmony_ci return crypto_aead_setauthsize(ctx->fback, authsize); 339762306a36Sopenharmony_ci} 339862306a36Sopenharmony_ci 339962306a36Sopenharmony_cistatic int safexcel_aead_fallback_crypt(struct aead_request *req, 340062306a36Sopenharmony_ci enum safexcel_cipher_direction dir) 340162306a36Sopenharmony_ci{ 340262306a36Sopenharmony_ci struct crypto_aead *aead = crypto_aead_reqtfm(req); 340362306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(aead); 340462306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 340562306a36Sopenharmony_ci struct aead_request *subreq = aead_request_ctx(req); 340662306a36Sopenharmony_ci 340762306a36Sopenharmony_ci aead_request_set_tfm(subreq, ctx->fback); 340862306a36Sopenharmony_ci aead_request_set_callback(subreq, req->base.flags, req->base.complete, 340962306a36Sopenharmony_ci req->base.data); 341062306a36Sopenharmony_ci aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 341162306a36Sopenharmony_ci req->iv); 341262306a36Sopenharmony_ci aead_request_set_ad(subreq, req->assoclen); 341362306a36Sopenharmony_ci 341462306a36Sopenharmony_ci return (dir == SAFEXCEL_ENCRYPT) ? 341562306a36Sopenharmony_ci crypto_aead_encrypt(subreq) : 341662306a36Sopenharmony_ci crypto_aead_decrypt(subreq); 341762306a36Sopenharmony_ci} 341862306a36Sopenharmony_ci 341962306a36Sopenharmony_cistatic int safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request *req) 342062306a36Sopenharmony_ci{ 342162306a36Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 342262306a36Sopenharmony_ci 342362306a36Sopenharmony_ci /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 342462306a36Sopenharmony_ci if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 342562306a36Sopenharmony_ci return -EINVAL; 342662306a36Sopenharmony_ci else if (req->cryptlen || req->assoclen) /* If input length > 0 only */ 342762306a36Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 342862306a36Sopenharmony_ci 342962306a36Sopenharmony_ci /* HW cannot do full (AAD+payload) zero length, use fallback */ 343062306a36Sopenharmony_ci return safexcel_aead_fallback_crypt(req, SAFEXCEL_ENCRYPT); 343162306a36Sopenharmony_ci} 343262306a36Sopenharmony_ci 343362306a36Sopenharmony_cistatic int safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request *req) 343462306a36Sopenharmony_ci{ 343562306a36Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 343662306a36Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 343762306a36Sopenharmony_ci 343862306a36Sopenharmony_ci /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 343962306a36Sopenharmony_ci if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) 344062306a36Sopenharmony_ci return -EINVAL; 344162306a36Sopenharmony_ci else if (req->cryptlen > crypto_aead_authsize(tfm) || req->assoclen) 344262306a36Sopenharmony_ci /* If input length > 0 only */ 344362306a36Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 344462306a36Sopenharmony_ci 344562306a36Sopenharmony_ci /* HW cannot do full (AAD+payload) zero length, use fallback */ 344662306a36Sopenharmony_ci return safexcel_aead_fallback_crypt(req, SAFEXCEL_DECRYPT); 344762306a36Sopenharmony_ci} 344862306a36Sopenharmony_ci 344962306a36Sopenharmony_cistatic int safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm *tfm) 345062306a36Sopenharmony_ci{ 345162306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 345262306a36Sopenharmony_ci 345362306a36Sopenharmony_ci safexcel_aead_fallback_cra_init(tfm); 345462306a36Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 345562306a36Sopenharmony_ci ctx->blocksz = SM4_BLOCK_SIZE; 345662306a36Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3; 345762306a36Sopenharmony_ci ctx->state_sz = SM3_DIGEST_SIZE; 345862306a36Sopenharmony_ci return 0; 345962306a36Sopenharmony_ci} 346062306a36Sopenharmony_ci 346162306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4 = { 346262306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 346362306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, 346462306a36Sopenharmony_ci .alg.aead = { 346562306a36Sopenharmony_ci .setkey = safexcel_aead_fallback_setkey, 346662306a36Sopenharmony_ci .setauthsize = safexcel_aead_fallback_setauthsize, 346762306a36Sopenharmony_ci .encrypt = safexcel_aead_sm4cbc_sm3_encrypt, 346862306a36Sopenharmony_ci .decrypt = safexcel_aead_sm4cbc_sm3_decrypt, 346962306a36Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 347062306a36Sopenharmony_ci .maxauthsize = SM3_DIGEST_SIZE, 347162306a36Sopenharmony_ci .base = { 347262306a36Sopenharmony_ci .cra_name = "authenc(hmac(sm3),cbc(sm4))", 347362306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sm3-cbc-sm4", 347462306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 347562306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 347662306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 347762306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY | 347862306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 347962306a36Sopenharmony_ci .cra_blocksize = SM4_BLOCK_SIZE, 348062306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 348162306a36Sopenharmony_ci .cra_alignmask = 0, 348262306a36Sopenharmony_ci .cra_init = safexcel_aead_sm4cbc_sm3_cra_init, 348362306a36Sopenharmony_ci .cra_exit = safexcel_aead_fallback_cra_exit, 348462306a36Sopenharmony_ci .cra_module = THIS_MODULE, 348562306a36Sopenharmony_ci }, 348662306a36Sopenharmony_ci }, 348762306a36Sopenharmony_ci}; 348862306a36Sopenharmony_ci 348962306a36Sopenharmony_cistatic int safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm *tfm) 349062306a36Sopenharmony_ci{ 349162306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 349262306a36Sopenharmony_ci 349362306a36Sopenharmony_ci safexcel_aead_sm4cbc_sha1_cra_init(tfm); 349462306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 349562306a36Sopenharmony_ci return 0; 349662306a36Sopenharmony_ci} 349762306a36Sopenharmony_ci 349862306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4 = { 349962306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 350062306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, 350162306a36Sopenharmony_ci .alg.aead = { 350262306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 350362306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 350462306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 350562306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 350662306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 350762306a36Sopenharmony_ci .base = { 350862306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha1),rfc3686(ctr(sm4)))", 350962306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-sm4", 351062306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 351162306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 351262306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 351362306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 351462306a36Sopenharmony_ci .cra_blocksize = 1, 351562306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 351662306a36Sopenharmony_ci .cra_alignmask = 0, 351762306a36Sopenharmony_ci .cra_init = safexcel_aead_sm4ctr_sha1_cra_init, 351862306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 351962306a36Sopenharmony_ci .cra_module = THIS_MODULE, 352062306a36Sopenharmony_ci }, 352162306a36Sopenharmony_ci }, 352262306a36Sopenharmony_ci}; 352362306a36Sopenharmony_ci 352462306a36Sopenharmony_cistatic int safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm *tfm) 352562306a36Sopenharmony_ci{ 352662306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 352762306a36Sopenharmony_ci 352862306a36Sopenharmony_ci safexcel_aead_sm4cbc_sm3_cra_init(tfm); 352962306a36Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 353062306a36Sopenharmony_ci return 0; 353162306a36Sopenharmony_ci} 353262306a36Sopenharmony_ci 353362306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4 = { 353462306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 353562306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, 353662306a36Sopenharmony_ci .alg.aead = { 353762306a36Sopenharmony_ci .setkey = safexcel_aead_setkey, 353862306a36Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 353962306a36Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 354062306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 354162306a36Sopenharmony_ci .maxauthsize = SM3_DIGEST_SIZE, 354262306a36Sopenharmony_ci .base = { 354362306a36Sopenharmony_ci .cra_name = "authenc(hmac(sm3),rfc3686(ctr(sm4)))", 354462306a36Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sm3-ctr-sm4", 354562306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 354662306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 354762306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 354862306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 354962306a36Sopenharmony_ci .cra_blocksize = 1, 355062306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 355162306a36Sopenharmony_ci .cra_alignmask = 0, 355262306a36Sopenharmony_ci .cra_init = safexcel_aead_sm4ctr_sm3_cra_init, 355362306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 355462306a36Sopenharmony_ci .cra_module = THIS_MODULE, 355562306a36Sopenharmony_ci }, 355662306a36Sopenharmony_ci }, 355762306a36Sopenharmony_ci}; 355862306a36Sopenharmony_ci 355962306a36Sopenharmony_cistatic int safexcel_rfc4106_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, 356062306a36Sopenharmony_ci unsigned int len) 356162306a36Sopenharmony_ci{ 356262306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 356362306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 356462306a36Sopenharmony_ci 356562306a36Sopenharmony_ci /* last 4 bytes of key are the nonce! */ 356662306a36Sopenharmony_ci ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 356762306a36Sopenharmony_ci 356862306a36Sopenharmony_ci len -= CTR_RFC3686_NONCE_SIZE; 356962306a36Sopenharmony_ci return safexcel_aead_gcm_setkey(ctfm, key, len); 357062306a36Sopenharmony_ci} 357162306a36Sopenharmony_ci 357262306a36Sopenharmony_cistatic int safexcel_rfc4106_gcm_setauthsize(struct crypto_aead *tfm, 357362306a36Sopenharmony_ci unsigned int authsize) 357462306a36Sopenharmony_ci{ 357562306a36Sopenharmony_ci return crypto_rfc4106_check_authsize(authsize); 357662306a36Sopenharmony_ci} 357762306a36Sopenharmony_ci 357862306a36Sopenharmony_cistatic int safexcel_rfc4106_encrypt(struct aead_request *req) 357962306a36Sopenharmony_ci{ 358062306a36Sopenharmony_ci return crypto_ipsec_check_assoclen(req->assoclen) ?: 358162306a36Sopenharmony_ci safexcel_aead_encrypt(req); 358262306a36Sopenharmony_ci} 358362306a36Sopenharmony_ci 358462306a36Sopenharmony_cistatic int safexcel_rfc4106_decrypt(struct aead_request *req) 358562306a36Sopenharmony_ci{ 358662306a36Sopenharmony_ci return crypto_ipsec_check_assoclen(req->assoclen) ?: 358762306a36Sopenharmony_ci safexcel_aead_decrypt(req); 358862306a36Sopenharmony_ci} 358962306a36Sopenharmony_ci 359062306a36Sopenharmony_cistatic int safexcel_rfc4106_gcm_cra_init(struct crypto_tfm *tfm) 359162306a36Sopenharmony_ci{ 359262306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 359362306a36Sopenharmony_ci int ret; 359462306a36Sopenharmony_ci 359562306a36Sopenharmony_ci ret = safexcel_aead_gcm_cra_init(tfm); 359662306a36Sopenharmony_ci ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 359762306a36Sopenharmony_ci ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 359862306a36Sopenharmony_ci return ret; 359962306a36Sopenharmony_ci} 360062306a36Sopenharmony_ci 360162306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_rfc4106_gcm = { 360262306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 360362306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 360462306a36Sopenharmony_ci .alg.aead = { 360562306a36Sopenharmony_ci .setkey = safexcel_rfc4106_gcm_setkey, 360662306a36Sopenharmony_ci .setauthsize = safexcel_rfc4106_gcm_setauthsize, 360762306a36Sopenharmony_ci .encrypt = safexcel_rfc4106_encrypt, 360862306a36Sopenharmony_ci .decrypt = safexcel_rfc4106_decrypt, 360962306a36Sopenharmony_ci .ivsize = GCM_RFC4106_IV_SIZE, 361062306a36Sopenharmony_ci .maxauthsize = GHASH_DIGEST_SIZE, 361162306a36Sopenharmony_ci .base = { 361262306a36Sopenharmony_ci .cra_name = "rfc4106(gcm(aes))", 361362306a36Sopenharmony_ci .cra_driver_name = "safexcel-rfc4106-gcm-aes", 361462306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 361562306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 361662306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 361762306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 361862306a36Sopenharmony_ci .cra_blocksize = 1, 361962306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 362062306a36Sopenharmony_ci .cra_alignmask = 0, 362162306a36Sopenharmony_ci .cra_init = safexcel_rfc4106_gcm_cra_init, 362262306a36Sopenharmony_ci .cra_exit = safexcel_aead_gcm_cra_exit, 362362306a36Sopenharmony_ci }, 362462306a36Sopenharmony_ci }, 362562306a36Sopenharmony_ci}; 362662306a36Sopenharmony_ci 362762306a36Sopenharmony_cistatic int safexcel_rfc4543_gcm_setauthsize(struct crypto_aead *tfm, 362862306a36Sopenharmony_ci unsigned int authsize) 362962306a36Sopenharmony_ci{ 363062306a36Sopenharmony_ci if (authsize != GHASH_DIGEST_SIZE) 363162306a36Sopenharmony_ci return -EINVAL; 363262306a36Sopenharmony_ci 363362306a36Sopenharmony_ci return 0; 363462306a36Sopenharmony_ci} 363562306a36Sopenharmony_ci 363662306a36Sopenharmony_cistatic int safexcel_rfc4543_gcm_cra_init(struct crypto_tfm *tfm) 363762306a36Sopenharmony_ci{ 363862306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 363962306a36Sopenharmony_ci int ret; 364062306a36Sopenharmony_ci 364162306a36Sopenharmony_ci ret = safexcel_aead_gcm_cra_init(tfm); 364262306a36Sopenharmony_ci ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP_GMAC; 364362306a36Sopenharmony_ci return ret; 364462306a36Sopenharmony_ci} 364562306a36Sopenharmony_ci 364662306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_rfc4543_gcm = { 364762306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 364862306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 364962306a36Sopenharmony_ci .alg.aead = { 365062306a36Sopenharmony_ci .setkey = safexcel_rfc4106_gcm_setkey, 365162306a36Sopenharmony_ci .setauthsize = safexcel_rfc4543_gcm_setauthsize, 365262306a36Sopenharmony_ci .encrypt = safexcel_rfc4106_encrypt, 365362306a36Sopenharmony_ci .decrypt = safexcel_rfc4106_decrypt, 365462306a36Sopenharmony_ci .ivsize = GCM_RFC4543_IV_SIZE, 365562306a36Sopenharmony_ci .maxauthsize = GHASH_DIGEST_SIZE, 365662306a36Sopenharmony_ci .base = { 365762306a36Sopenharmony_ci .cra_name = "rfc4543(gcm(aes))", 365862306a36Sopenharmony_ci .cra_driver_name = "safexcel-rfc4543-gcm-aes", 365962306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 366062306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 366162306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 366262306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 366362306a36Sopenharmony_ci .cra_blocksize = 1, 366462306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 366562306a36Sopenharmony_ci .cra_alignmask = 0, 366662306a36Sopenharmony_ci .cra_init = safexcel_rfc4543_gcm_cra_init, 366762306a36Sopenharmony_ci .cra_exit = safexcel_aead_gcm_cra_exit, 366862306a36Sopenharmony_ci }, 366962306a36Sopenharmony_ci }, 367062306a36Sopenharmony_ci}; 367162306a36Sopenharmony_ci 367262306a36Sopenharmony_cistatic int safexcel_rfc4309_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, 367362306a36Sopenharmony_ci unsigned int len) 367462306a36Sopenharmony_ci{ 367562306a36Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 367662306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 367762306a36Sopenharmony_ci 367862306a36Sopenharmony_ci /* First byte of the nonce = L = always 3 for RFC4309 (4 byte ctr) */ 367962306a36Sopenharmony_ci *(u8 *)&ctx->nonce = EIP197_AEAD_IPSEC_COUNTER_SIZE - 1; 368062306a36Sopenharmony_ci /* last 3 bytes of key are the nonce! */ 368162306a36Sopenharmony_ci memcpy((u8 *)&ctx->nonce + 1, key + len - 368262306a36Sopenharmony_ci EIP197_AEAD_IPSEC_CCM_NONCE_SIZE, 368362306a36Sopenharmony_ci EIP197_AEAD_IPSEC_CCM_NONCE_SIZE); 368462306a36Sopenharmony_ci 368562306a36Sopenharmony_ci len -= EIP197_AEAD_IPSEC_CCM_NONCE_SIZE; 368662306a36Sopenharmony_ci return safexcel_aead_ccm_setkey(ctfm, key, len); 368762306a36Sopenharmony_ci} 368862306a36Sopenharmony_ci 368962306a36Sopenharmony_cistatic int safexcel_rfc4309_ccm_setauthsize(struct crypto_aead *tfm, 369062306a36Sopenharmony_ci unsigned int authsize) 369162306a36Sopenharmony_ci{ 369262306a36Sopenharmony_ci /* Borrowed from crypto/ccm.c */ 369362306a36Sopenharmony_ci switch (authsize) { 369462306a36Sopenharmony_ci case 8: 369562306a36Sopenharmony_ci case 12: 369662306a36Sopenharmony_ci case 16: 369762306a36Sopenharmony_ci break; 369862306a36Sopenharmony_ci default: 369962306a36Sopenharmony_ci return -EINVAL; 370062306a36Sopenharmony_ci } 370162306a36Sopenharmony_ci 370262306a36Sopenharmony_ci return 0; 370362306a36Sopenharmony_ci} 370462306a36Sopenharmony_ci 370562306a36Sopenharmony_cistatic int safexcel_rfc4309_ccm_encrypt(struct aead_request *req) 370662306a36Sopenharmony_ci{ 370762306a36Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 370862306a36Sopenharmony_ci 370962306a36Sopenharmony_ci /* Borrowed from crypto/ccm.c */ 371062306a36Sopenharmony_ci if (req->assoclen != 16 && req->assoclen != 20) 371162306a36Sopenharmony_ci return -EINVAL; 371262306a36Sopenharmony_ci 371362306a36Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 371462306a36Sopenharmony_ci} 371562306a36Sopenharmony_ci 371662306a36Sopenharmony_cistatic int safexcel_rfc4309_ccm_decrypt(struct aead_request *req) 371762306a36Sopenharmony_ci{ 371862306a36Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 371962306a36Sopenharmony_ci 372062306a36Sopenharmony_ci /* Borrowed from crypto/ccm.c */ 372162306a36Sopenharmony_ci if (req->assoclen != 16 && req->assoclen != 20) 372262306a36Sopenharmony_ci return -EINVAL; 372362306a36Sopenharmony_ci 372462306a36Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 372562306a36Sopenharmony_ci} 372662306a36Sopenharmony_ci 372762306a36Sopenharmony_cistatic int safexcel_rfc4309_ccm_cra_init(struct crypto_tfm *tfm) 372862306a36Sopenharmony_ci{ 372962306a36Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 373062306a36Sopenharmony_ci int ret; 373162306a36Sopenharmony_ci 373262306a36Sopenharmony_ci ret = safexcel_aead_ccm_cra_init(tfm); 373362306a36Sopenharmony_ci ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 373462306a36Sopenharmony_ci ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 373562306a36Sopenharmony_ci return ret; 373662306a36Sopenharmony_ci} 373762306a36Sopenharmony_ci 373862306a36Sopenharmony_cistruct safexcel_alg_template safexcel_alg_rfc4309_ccm = { 373962306a36Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 374062306a36Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, 374162306a36Sopenharmony_ci .alg.aead = { 374262306a36Sopenharmony_ci .setkey = safexcel_rfc4309_ccm_setkey, 374362306a36Sopenharmony_ci .setauthsize = safexcel_rfc4309_ccm_setauthsize, 374462306a36Sopenharmony_ci .encrypt = safexcel_rfc4309_ccm_encrypt, 374562306a36Sopenharmony_ci .decrypt = safexcel_rfc4309_ccm_decrypt, 374662306a36Sopenharmony_ci .ivsize = EIP197_AEAD_IPSEC_IV_SIZE, 374762306a36Sopenharmony_ci .maxauthsize = AES_BLOCK_SIZE, 374862306a36Sopenharmony_ci .base = { 374962306a36Sopenharmony_ci .cra_name = "rfc4309(ccm(aes))", 375062306a36Sopenharmony_ci .cra_driver_name = "safexcel-rfc4309-ccm-aes", 375162306a36Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 375262306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 375362306a36Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 375462306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 375562306a36Sopenharmony_ci .cra_blocksize = 1, 375662306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 375762306a36Sopenharmony_ci .cra_alignmask = 0, 375862306a36Sopenharmony_ci .cra_init = safexcel_rfc4309_ccm_cra_init, 375962306a36Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 376062306a36Sopenharmony_ci .cra_module = THIS_MODULE, 376162306a36Sopenharmony_ci }, 376262306a36Sopenharmony_ci }, 376362306a36Sopenharmony_ci}; 3764