18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2017 Marvell 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Antoine Tenart <antoine.tenart@free-electrons.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <asm/unaligned.h> 98c2ecf20Sopenharmony_ci#include <linux/device.h> 108c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 118c2ecf20Sopenharmony_ci#include <linux/dmapool.h> 128c2ecf20Sopenharmony_ci#include <crypto/aead.h> 138c2ecf20Sopenharmony_ci#include <crypto/aes.h> 148c2ecf20Sopenharmony_ci#include <crypto/authenc.h> 158c2ecf20Sopenharmony_ci#include <crypto/chacha.h> 168c2ecf20Sopenharmony_ci#include <crypto/ctr.h> 178c2ecf20Sopenharmony_ci#include <crypto/internal/des.h> 188c2ecf20Sopenharmony_ci#include <crypto/gcm.h> 198c2ecf20Sopenharmony_ci#include <crypto/ghash.h> 208c2ecf20Sopenharmony_ci#include <crypto/poly1305.h> 218c2ecf20Sopenharmony_ci#include <crypto/sha.h> 228c2ecf20Sopenharmony_ci#include <crypto/sm3.h> 238c2ecf20Sopenharmony_ci#include <crypto/sm4.h> 248c2ecf20Sopenharmony_ci#include <crypto/xts.h> 258c2ecf20Sopenharmony_ci#include <crypto/skcipher.h> 268c2ecf20Sopenharmony_ci#include <crypto/internal/aead.h> 278c2ecf20Sopenharmony_ci#include <crypto/internal/skcipher.h> 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#include "safexcel.h" 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cienum safexcel_cipher_direction { 328c2ecf20Sopenharmony_ci SAFEXCEL_ENCRYPT, 338c2ecf20Sopenharmony_ci SAFEXCEL_DECRYPT, 348c2ecf20Sopenharmony_ci}; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cienum safexcel_cipher_alg { 378c2ecf20Sopenharmony_ci SAFEXCEL_DES, 388c2ecf20Sopenharmony_ci SAFEXCEL_3DES, 398c2ecf20Sopenharmony_ci SAFEXCEL_AES, 408c2ecf20Sopenharmony_ci SAFEXCEL_CHACHA20, 418c2ecf20Sopenharmony_ci SAFEXCEL_SM4, 428c2ecf20Sopenharmony_ci}; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistruct safexcel_cipher_ctx { 458c2ecf20Sopenharmony_ci struct safexcel_context base; 468c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci u32 mode; 498c2ecf20Sopenharmony_ci enum safexcel_cipher_alg alg; 508c2ecf20Sopenharmony_ci u8 aead; /* !=0=AEAD, 2=IPSec ESP AEAD, 3=IPsec ESP GMAC */ 518c2ecf20Sopenharmony_ci u8 xcm; /* 0=authenc, 1=GCM, 2 reserved for CCM */ 528c2ecf20Sopenharmony_ci u8 aadskip; 538c2ecf20Sopenharmony_ci u8 blocksz; 548c2ecf20Sopenharmony_ci u32 ivmask; 558c2ecf20Sopenharmony_ci u32 ctrinit; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci __le32 key[16]; 588c2ecf20Sopenharmony_ci u32 nonce; 598c2ecf20Sopenharmony_ci unsigned int key_len, xts; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* All the below is AEAD specific */ 628c2ecf20Sopenharmony_ci u32 hash_alg; 638c2ecf20Sopenharmony_ci u32 state_sz; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci struct crypto_cipher *hkaes; 668c2ecf20Sopenharmony_ci struct crypto_aead *fback; 678c2ecf20Sopenharmony_ci}; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistruct safexcel_cipher_req { 708c2ecf20Sopenharmony_ci enum safexcel_cipher_direction direction; 718c2ecf20Sopenharmony_ci /* Number of result descriptors associated to the request */ 728c2ecf20Sopenharmony_ci unsigned int rdescs; 738c2ecf20Sopenharmony_ci bool needs_inv; 748c2ecf20Sopenharmony_ci int nr_src, nr_dst; 758c2ecf20Sopenharmony_ci}; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic int safexcel_skcipher_iv(struct safexcel_cipher_ctx *ctx, u8 *iv, 788c2ecf20Sopenharmony_ci struct safexcel_command_desc *cdesc) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { 818c2ecf20Sopenharmony_ci cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 828c2ecf20Sopenharmony_ci /* 32 bit nonce */ 838c2ecf20Sopenharmony_ci cdesc->control_data.token[0] = ctx->nonce; 848c2ecf20Sopenharmony_ci /* 64 bit IV part */ 858c2ecf20Sopenharmony_ci memcpy(&cdesc->control_data.token[1], iv, 8); 868c2ecf20Sopenharmony_ci /* 32 bit counter, start at 0 or 1 (big endian!) */ 878c2ecf20Sopenharmony_ci cdesc->control_data.token[3] = 888c2ecf20Sopenharmony_ci (__force u32)cpu_to_be32(ctx->ctrinit); 898c2ecf20Sopenharmony_ci return 4; 908c2ecf20Sopenharmony_ci } 918c2ecf20Sopenharmony_ci if (ctx->alg == SAFEXCEL_CHACHA20) { 928c2ecf20Sopenharmony_ci cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 938c2ecf20Sopenharmony_ci /* 96 bit nonce part */ 948c2ecf20Sopenharmony_ci memcpy(&cdesc->control_data.token[0], &iv[4], 12); 958c2ecf20Sopenharmony_ci /* 32 bit counter */ 968c2ecf20Sopenharmony_ci cdesc->control_data.token[3] = *(u32 *)iv; 978c2ecf20Sopenharmony_ci return 4; 988c2ecf20Sopenharmony_ci } 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci cdesc->control_data.options |= ctx->ivmask; 1018c2ecf20Sopenharmony_ci memcpy(cdesc->control_data.token, iv, ctx->blocksz); 1028c2ecf20Sopenharmony_ci return ctx->blocksz / sizeof(u32); 1038c2ecf20Sopenharmony_ci} 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistatic void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 1068c2ecf20Sopenharmony_ci struct safexcel_command_desc *cdesc, 1078c2ecf20Sopenharmony_ci struct safexcel_token *atoken, 1088c2ecf20Sopenharmony_ci u32 length) 1098c2ecf20Sopenharmony_ci{ 1108c2ecf20Sopenharmony_ci struct safexcel_token *token; 1118c2ecf20Sopenharmony_ci int ivlen; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci ivlen = safexcel_skcipher_iv(ctx, iv, cdesc); 1148c2ecf20Sopenharmony_ci if (ivlen == 4) { 1158c2ecf20Sopenharmony_ci /* No space in cdesc, instruction moves to atoken */ 1168c2ecf20Sopenharmony_ci cdesc->additional_cdata_size = 1; 1178c2ecf20Sopenharmony_ci token = atoken; 1188c2ecf20Sopenharmony_ci } else { 1198c2ecf20Sopenharmony_ci /* Everything fits in cdesc */ 1208c2ecf20Sopenharmony_ci token = (struct safexcel_token *)(cdesc->control_data.token + 2); 1218c2ecf20Sopenharmony_ci /* Need to pad with NOP */ 1228c2ecf20Sopenharmony_ci eip197_noop_token(&token[1]); 1238c2ecf20Sopenharmony_ci } 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci token->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 1268c2ecf20Sopenharmony_ci token->packet_length = length; 1278c2ecf20Sopenharmony_ci token->stat = EIP197_TOKEN_STAT_LAST_PACKET | 1288c2ecf20Sopenharmony_ci EIP197_TOKEN_STAT_LAST_HASH; 1298c2ecf20Sopenharmony_ci token->instructions = EIP197_TOKEN_INS_LAST | 1308c2ecf20Sopenharmony_ci EIP197_TOKEN_INS_TYPE_CRYPTO | 1318c2ecf20Sopenharmony_ci EIP197_TOKEN_INS_TYPE_OUTPUT; 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic void safexcel_aead_iv(struct safexcel_cipher_ctx *ctx, u8 *iv, 1358c2ecf20Sopenharmony_ci struct safexcel_command_desc *cdesc) 1368c2ecf20Sopenharmony_ci{ 1378c2ecf20Sopenharmony_ci if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD || 1388c2ecf20Sopenharmony_ci ctx->aead & EIP197_AEAD_TYPE_IPSEC_ESP) { /* _ESP and _ESP_GMAC */ 1398c2ecf20Sopenharmony_ci /* 32 bit nonce */ 1408c2ecf20Sopenharmony_ci cdesc->control_data.token[0] = ctx->nonce; 1418c2ecf20Sopenharmony_ci /* 64 bit IV part */ 1428c2ecf20Sopenharmony_ci memcpy(&cdesc->control_data.token[1], iv, 8); 1438c2ecf20Sopenharmony_ci /* 32 bit counter, start at 0 or 1 (big endian!) */ 1448c2ecf20Sopenharmony_ci cdesc->control_data.token[3] = 1458c2ecf20Sopenharmony_ci (__force u32)cpu_to_be32(ctx->ctrinit); 1468c2ecf20Sopenharmony_ci return; 1478c2ecf20Sopenharmony_ci } 1488c2ecf20Sopenharmony_ci if (ctx->xcm == EIP197_XCM_MODE_GCM || ctx->alg == SAFEXCEL_CHACHA20) { 1498c2ecf20Sopenharmony_ci /* 96 bit IV part */ 1508c2ecf20Sopenharmony_ci memcpy(&cdesc->control_data.token[0], iv, 12); 1518c2ecf20Sopenharmony_ci /* 32 bit counter, start at 0 or 1 (big endian!) */ 1528c2ecf20Sopenharmony_ci cdesc->control_data.token[3] = 1538c2ecf20Sopenharmony_ci (__force u32)cpu_to_be32(ctx->ctrinit); 1548c2ecf20Sopenharmony_ci return; 1558c2ecf20Sopenharmony_ci } 1568c2ecf20Sopenharmony_ci /* CBC */ 1578c2ecf20Sopenharmony_ci memcpy(cdesc->control_data.token, iv, ctx->blocksz); 1588c2ecf20Sopenharmony_ci} 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_cistatic void safexcel_aead_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 1618c2ecf20Sopenharmony_ci struct safexcel_command_desc *cdesc, 1628c2ecf20Sopenharmony_ci struct safexcel_token *atoken, 1638c2ecf20Sopenharmony_ci enum safexcel_cipher_direction direction, 1648c2ecf20Sopenharmony_ci u32 cryptlen, u32 assoclen, u32 digestsize) 1658c2ecf20Sopenharmony_ci{ 1668c2ecf20Sopenharmony_ci struct safexcel_token *aadref; 1678c2ecf20Sopenharmony_ci int atoksize = 2; /* Start with minimum size */ 1688c2ecf20Sopenharmony_ci int assocadj = assoclen - ctx->aadskip, aadalign; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci /* Always 4 dwords of embedded IV for AEAD modes */ 1718c2ecf20Sopenharmony_ci cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci if (direction == SAFEXCEL_DECRYPT) 1748c2ecf20Sopenharmony_ci cryptlen -= digestsize; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM)) { 1778c2ecf20Sopenharmony_ci /* Construct IV block B0 for the CBC-MAC */ 1788c2ecf20Sopenharmony_ci u8 *final_iv = (u8 *)cdesc->control_data.token; 1798c2ecf20Sopenharmony_ci u8 *cbcmaciv = (u8 *)&atoken[1]; 1808c2ecf20Sopenharmony_ci __le32 *aadlen = (__le32 *)&atoken[5]; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 1838c2ecf20Sopenharmony_ci /* Length + nonce */ 1848c2ecf20Sopenharmony_ci cdesc->control_data.token[0] = ctx->nonce; 1858c2ecf20Sopenharmony_ci /* Fixup flags byte */ 1868c2ecf20Sopenharmony_ci *(__le32 *)cbcmaciv = 1878c2ecf20Sopenharmony_ci cpu_to_le32(ctx->nonce | 1888c2ecf20Sopenharmony_ci ((assocadj > 0) << 6) | 1898c2ecf20Sopenharmony_ci ((digestsize - 2) << 2)); 1908c2ecf20Sopenharmony_ci /* 64 bit IV part */ 1918c2ecf20Sopenharmony_ci memcpy(&cdesc->control_data.token[1], iv, 8); 1928c2ecf20Sopenharmony_ci memcpy(cbcmaciv + 4, iv, 8); 1938c2ecf20Sopenharmony_ci /* Start counter at 0 */ 1948c2ecf20Sopenharmony_ci cdesc->control_data.token[3] = 0; 1958c2ecf20Sopenharmony_ci /* Message length */ 1968c2ecf20Sopenharmony_ci *(__be32 *)(cbcmaciv + 12) = cpu_to_be32(cryptlen); 1978c2ecf20Sopenharmony_ci } else { 1988c2ecf20Sopenharmony_ci /* Variable length IV part */ 1998c2ecf20Sopenharmony_ci memcpy(final_iv, iv, 15 - iv[0]); 2008c2ecf20Sopenharmony_ci memcpy(cbcmaciv, iv, 15 - iv[0]); 2018c2ecf20Sopenharmony_ci /* Start variable length counter at 0 */ 2028c2ecf20Sopenharmony_ci memset(final_iv + 15 - iv[0], 0, iv[0] + 1); 2038c2ecf20Sopenharmony_ci memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1); 2048c2ecf20Sopenharmony_ci /* fixup flags byte */ 2058c2ecf20Sopenharmony_ci cbcmaciv[0] |= ((assocadj > 0) << 6) | 2068c2ecf20Sopenharmony_ci ((digestsize - 2) << 2); 2078c2ecf20Sopenharmony_ci /* insert lower 2 bytes of message length */ 2088c2ecf20Sopenharmony_ci cbcmaciv[14] = cryptlen >> 8; 2098c2ecf20Sopenharmony_ci cbcmaciv[15] = cryptlen & 255; 2108c2ecf20Sopenharmony_ci } 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 2138c2ecf20Sopenharmony_ci atoken->packet_length = AES_BLOCK_SIZE + 2148c2ecf20Sopenharmony_ci ((assocadj > 0) << 1); 2158c2ecf20Sopenharmony_ci atoken->stat = 0; 2168c2ecf20Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN | 2178c2ecf20Sopenharmony_ci EIP197_TOKEN_INS_TYPE_HASH; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci if (likely(assocadj)) { 2208c2ecf20Sopenharmony_ci *aadlen = cpu_to_le32((assocadj >> 8) | 2218c2ecf20Sopenharmony_ci (assocadj & 255) << 8); 2228c2ecf20Sopenharmony_ci atoken += 6; 2238c2ecf20Sopenharmony_ci atoksize += 7; 2248c2ecf20Sopenharmony_ci } else { 2258c2ecf20Sopenharmony_ci atoken += 5; 2268c2ecf20Sopenharmony_ci atoksize += 6; 2278c2ecf20Sopenharmony_ci } 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci /* Process AAD data */ 2308c2ecf20Sopenharmony_ci aadref = atoken; 2318c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 2328c2ecf20Sopenharmony_ci atoken->packet_length = assocadj; 2338c2ecf20Sopenharmony_ci atoken->stat = 0; 2348c2ecf20Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 2358c2ecf20Sopenharmony_ci atoken++; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci /* For CCM only, align AAD data towards hash engine */ 2388c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 2398c2ecf20Sopenharmony_ci aadalign = (assocadj + 2) & 15; 2408c2ecf20Sopenharmony_ci atoken->packet_length = assocadj && aadalign ? 2418c2ecf20Sopenharmony_ci 16 - aadalign : 2428c2ecf20Sopenharmony_ci 0; 2438c2ecf20Sopenharmony_ci if (likely(cryptlen)) { 2448c2ecf20Sopenharmony_ci atoken->stat = 0; 2458c2ecf20Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 2468c2ecf20Sopenharmony_ci } else { 2478c2ecf20Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 2488c2ecf20Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_LAST | 2498c2ecf20Sopenharmony_ci EIP197_TOKEN_INS_TYPE_HASH; 2508c2ecf20Sopenharmony_ci } 2518c2ecf20Sopenharmony_ci } else { 2528c2ecf20Sopenharmony_ci safexcel_aead_iv(ctx, iv, cdesc); 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci /* Process AAD data */ 2558c2ecf20Sopenharmony_ci aadref = atoken; 2568c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 2578c2ecf20Sopenharmony_ci atoken->packet_length = assocadj; 2588c2ecf20Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 2598c2ecf20Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_LAST | 2608c2ecf20Sopenharmony_ci EIP197_TOKEN_INS_TYPE_HASH; 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci atoken++; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 2658c2ecf20Sopenharmony_ci /* For ESP mode (and not GMAC), skip over the IV */ 2668c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 2678c2ecf20Sopenharmony_ci atoken->packet_length = EIP197_AEAD_IPSEC_IV_SIZE; 2688c2ecf20Sopenharmony_ci atoken->stat = 0; 2698c2ecf20Sopenharmony_ci atoken->instructions = 0; 2708c2ecf20Sopenharmony_ci atoken++; 2718c2ecf20Sopenharmony_ci atoksize++; 2728c2ecf20Sopenharmony_ci } else if (unlikely(ctx->alg == SAFEXCEL_CHACHA20 && 2738c2ecf20Sopenharmony_ci direction == SAFEXCEL_DECRYPT)) { 2748c2ecf20Sopenharmony_ci /* Poly-chacha decryption needs a dummy NOP here ... */ 2758c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 2768c2ecf20Sopenharmony_ci atoken->packet_length = 16; /* According to Op Manual */ 2778c2ecf20Sopenharmony_ci atoken->stat = 0; 2788c2ecf20Sopenharmony_ci atoken->instructions = 0; 2798c2ecf20Sopenharmony_ci atoken++; 2808c2ecf20Sopenharmony_ci atoksize++; 2818c2ecf20Sopenharmony_ci } 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci if (ctx->xcm) { 2848c2ecf20Sopenharmony_ci /* For GCM and CCM, obtain enc(Y0) */ 2858c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES; 2868c2ecf20Sopenharmony_ci atoken->packet_length = 0; 2878c2ecf20Sopenharmony_ci atoken->stat = 0; 2888c2ecf20Sopenharmony_ci atoken->instructions = AES_BLOCK_SIZE; 2898c2ecf20Sopenharmony_ci atoken++; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 2928c2ecf20Sopenharmony_ci atoken->packet_length = AES_BLOCK_SIZE; 2938c2ecf20Sopenharmony_ci atoken->stat = 0; 2948c2ecf20Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | 2958c2ecf20Sopenharmony_ci EIP197_TOKEN_INS_TYPE_CRYPTO; 2968c2ecf20Sopenharmony_ci atoken++; 2978c2ecf20Sopenharmony_ci atoksize += 2; 2988c2ecf20Sopenharmony_ci } 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci if (likely(cryptlen || ctx->alg == SAFEXCEL_CHACHA20)) { 3018c2ecf20Sopenharmony_ci /* Fixup stat field for AAD direction instruction */ 3028c2ecf20Sopenharmony_ci aadref->stat = 0; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci /* Process crypto data */ 3058c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 3068c2ecf20Sopenharmony_ci atoken->packet_length = cryptlen; 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci if (unlikely(ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) { 3098c2ecf20Sopenharmony_ci /* Fixup instruction field for AAD dir instruction */ 3108c2ecf20Sopenharmony_ci aadref->instructions = EIP197_TOKEN_INS_TYPE_HASH; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci /* Do not send to crypt engine in case of GMAC */ 3138c2ecf20Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_LAST | 3148c2ecf20Sopenharmony_ci EIP197_TOKEN_INS_TYPE_HASH | 3158c2ecf20Sopenharmony_ci EIP197_TOKEN_INS_TYPE_OUTPUT; 3168c2ecf20Sopenharmony_ci } else { 3178c2ecf20Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_LAST | 3188c2ecf20Sopenharmony_ci EIP197_TOKEN_INS_TYPE_CRYPTO | 3198c2ecf20Sopenharmony_ci EIP197_TOKEN_INS_TYPE_HASH | 3208c2ecf20Sopenharmony_ci EIP197_TOKEN_INS_TYPE_OUTPUT; 3218c2ecf20Sopenharmony_ci } 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci cryptlen &= 15; 3248c2ecf20Sopenharmony_ci if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM && cryptlen)) { 3258c2ecf20Sopenharmony_ci atoken->stat = 0; 3268c2ecf20Sopenharmony_ci /* For CCM only, pad crypto data to the hash engine */ 3278c2ecf20Sopenharmony_ci atoken++; 3288c2ecf20Sopenharmony_ci atoksize++; 3298c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 3308c2ecf20Sopenharmony_ci atoken->packet_length = 16 - cryptlen; 3318c2ecf20Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 3328c2ecf20Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 3338c2ecf20Sopenharmony_ci } else { 3348c2ecf20Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 3358c2ecf20Sopenharmony_ci } 3368c2ecf20Sopenharmony_ci atoken++; 3378c2ecf20Sopenharmony_ci atoksize++; 3388c2ecf20Sopenharmony_ci } 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci if (direction == SAFEXCEL_ENCRYPT) { 3418c2ecf20Sopenharmony_ci /* Append ICV */ 3428c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 3438c2ecf20Sopenharmony_ci atoken->packet_length = digestsize; 3448c2ecf20Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 3458c2ecf20Sopenharmony_ci EIP197_TOKEN_STAT_LAST_PACKET; 3468c2ecf20Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | 3478c2ecf20Sopenharmony_ci EIP197_TOKEN_INS_INSERT_HASH_DIGEST; 3488c2ecf20Sopenharmony_ci } else { 3498c2ecf20Sopenharmony_ci /* Extract ICV */ 3508c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_RETRIEVE; 3518c2ecf20Sopenharmony_ci atoken->packet_length = digestsize; 3528c2ecf20Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 3538c2ecf20Sopenharmony_ci EIP197_TOKEN_STAT_LAST_PACKET; 3548c2ecf20Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST; 3558c2ecf20Sopenharmony_ci atoken++; 3568c2ecf20Sopenharmony_ci atoksize++; 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci /* Verify ICV */ 3598c2ecf20Sopenharmony_ci atoken->opcode = EIP197_TOKEN_OPCODE_VERIFY; 3608c2ecf20Sopenharmony_ci atoken->packet_length = digestsize | 3618c2ecf20Sopenharmony_ci EIP197_TOKEN_HASH_RESULT_VERIFY; 3628c2ecf20Sopenharmony_ci atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 3638c2ecf20Sopenharmony_ci EIP197_TOKEN_STAT_LAST_PACKET; 3648c2ecf20Sopenharmony_ci atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT; 3658c2ecf20Sopenharmony_ci } 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci /* Fixup length of the token in the command descriptor */ 3688c2ecf20Sopenharmony_ci cdesc->additional_cdata_size = atoksize; 3698c2ecf20Sopenharmony_ci} 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm, 3728c2ecf20Sopenharmony_ci const u8 *key, unsigned int len) 3738c2ecf20Sopenharmony_ci{ 3748c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 3758c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3768c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 3778c2ecf20Sopenharmony_ci struct crypto_aes_ctx aes; 3788c2ecf20Sopenharmony_ci int ret, i; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci ret = aes_expandkey(&aes, key, len); 3818c2ecf20Sopenharmony_ci if (ret) 3828c2ecf20Sopenharmony_ci return ret; 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 3858c2ecf20Sopenharmony_ci for (i = 0; i < len / sizeof(u32); i++) { 3868c2ecf20Sopenharmony_ci if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 3878c2ecf20Sopenharmony_ci ctx->base.needs_inv = true; 3888c2ecf20Sopenharmony_ci break; 3898c2ecf20Sopenharmony_ci } 3908c2ecf20Sopenharmony_ci } 3918c2ecf20Sopenharmony_ci } 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci for (i = 0; i < len / sizeof(u32); i++) 3948c2ecf20Sopenharmony_ci ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci ctx->key_len = len; 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 3998c2ecf20Sopenharmony_ci return 0; 4008c2ecf20Sopenharmony_ci} 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_cistatic int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key, 4038c2ecf20Sopenharmony_ci unsigned int len) 4048c2ecf20Sopenharmony_ci{ 4058c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 4068c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 4078c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 4088c2ecf20Sopenharmony_ci struct crypto_authenc_keys keys; 4098c2ecf20Sopenharmony_ci struct crypto_aes_ctx aes; 4108c2ecf20Sopenharmony_ci int err = -EINVAL, i; 4118c2ecf20Sopenharmony_ci const char *alg; 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci if (unlikely(crypto_authenc_extractkeys(&keys, key, len))) 4148c2ecf20Sopenharmony_ci goto badkey; 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { 4178c2ecf20Sopenharmony_ci /* Must have at least space for the nonce here */ 4188c2ecf20Sopenharmony_ci if (unlikely(keys.enckeylen < CTR_RFC3686_NONCE_SIZE)) 4198c2ecf20Sopenharmony_ci goto badkey; 4208c2ecf20Sopenharmony_ci /* last 4 bytes of key are the nonce! */ 4218c2ecf20Sopenharmony_ci ctx->nonce = *(u32 *)(keys.enckey + keys.enckeylen - 4228c2ecf20Sopenharmony_ci CTR_RFC3686_NONCE_SIZE); 4238c2ecf20Sopenharmony_ci /* exclude the nonce here */ 4248c2ecf20Sopenharmony_ci keys.enckeylen -= CTR_RFC3686_NONCE_SIZE; 4258c2ecf20Sopenharmony_ci } 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci /* Encryption key */ 4288c2ecf20Sopenharmony_ci switch (ctx->alg) { 4298c2ecf20Sopenharmony_ci case SAFEXCEL_DES: 4308c2ecf20Sopenharmony_ci err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen); 4318c2ecf20Sopenharmony_ci if (unlikely(err)) 4328c2ecf20Sopenharmony_ci goto badkey; 4338c2ecf20Sopenharmony_ci break; 4348c2ecf20Sopenharmony_ci case SAFEXCEL_3DES: 4358c2ecf20Sopenharmony_ci err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen); 4368c2ecf20Sopenharmony_ci if (unlikely(err)) 4378c2ecf20Sopenharmony_ci goto badkey; 4388c2ecf20Sopenharmony_ci break; 4398c2ecf20Sopenharmony_ci case SAFEXCEL_AES: 4408c2ecf20Sopenharmony_ci err = aes_expandkey(&aes, keys.enckey, keys.enckeylen); 4418c2ecf20Sopenharmony_ci if (unlikely(err)) 4428c2ecf20Sopenharmony_ci goto badkey; 4438c2ecf20Sopenharmony_ci break; 4448c2ecf20Sopenharmony_ci case SAFEXCEL_SM4: 4458c2ecf20Sopenharmony_ci if (unlikely(keys.enckeylen != SM4_KEY_SIZE)) 4468c2ecf20Sopenharmony_ci goto badkey; 4478c2ecf20Sopenharmony_ci break; 4488c2ecf20Sopenharmony_ci default: 4498c2ecf20Sopenharmony_ci dev_err(priv->dev, "aead: unsupported cipher algorithm\n"); 4508c2ecf20Sopenharmony_ci goto badkey; 4518c2ecf20Sopenharmony_ci } 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 4548c2ecf20Sopenharmony_ci for (i = 0; i < keys.enckeylen / sizeof(u32); i++) { 4558c2ecf20Sopenharmony_ci if (le32_to_cpu(ctx->key[i]) != 4568c2ecf20Sopenharmony_ci ((u32 *)keys.enckey)[i]) { 4578c2ecf20Sopenharmony_ci ctx->base.needs_inv = true; 4588c2ecf20Sopenharmony_ci break; 4598c2ecf20Sopenharmony_ci } 4608c2ecf20Sopenharmony_ci } 4618c2ecf20Sopenharmony_ci } 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci /* Auth key */ 4648c2ecf20Sopenharmony_ci switch (ctx->hash_alg) { 4658c2ecf20Sopenharmony_ci case CONTEXT_CONTROL_CRYPTO_ALG_SHA1: 4668c2ecf20Sopenharmony_ci alg = "safexcel-sha1"; 4678c2ecf20Sopenharmony_ci break; 4688c2ecf20Sopenharmony_ci case CONTEXT_CONTROL_CRYPTO_ALG_SHA224: 4698c2ecf20Sopenharmony_ci alg = "safexcel-sha224"; 4708c2ecf20Sopenharmony_ci break; 4718c2ecf20Sopenharmony_ci case CONTEXT_CONTROL_CRYPTO_ALG_SHA256: 4728c2ecf20Sopenharmony_ci alg = "safexcel-sha256"; 4738c2ecf20Sopenharmony_ci break; 4748c2ecf20Sopenharmony_ci case CONTEXT_CONTROL_CRYPTO_ALG_SHA384: 4758c2ecf20Sopenharmony_ci alg = "safexcel-sha384"; 4768c2ecf20Sopenharmony_ci break; 4778c2ecf20Sopenharmony_ci case CONTEXT_CONTROL_CRYPTO_ALG_SHA512: 4788c2ecf20Sopenharmony_ci alg = "safexcel-sha512"; 4798c2ecf20Sopenharmony_ci break; 4808c2ecf20Sopenharmony_ci case CONTEXT_CONTROL_CRYPTO_ALG_SM3: 4818c2ecf20Sopenharmony_ci alg = "safexcel-sm3"; 4828c2ecf20Sopenharmony_ci break; 4838c2ecf20Sopenharmony_ci default: 4848c2ecf20Sopenharmony_ci dev_err(priv->dev, "aead: unsupported hash algorithm\n"); 4858c2ecf20Sopenharmony_ci goto badkey; 4868c2ecf20Sopenharmony_ci } 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci if (safexcel_hmac_setkey(&ctx->base, keys.authkey, keys.authkeylen, 4898c2ecf20Sopenharmony_ci alg, ctx->state_sz)) 4908c2ecf20Sopenharmony_ci goto badkey; 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_ci /* Now copy the keys into the context */ 4938c2ecf20Sopenharmony_ci for (i = 0; i < keys.enckeylen / sizeof(u32); i++) 4948c2ecf20Sopenharmony_ci ctx->key[i] = cpu_to_le32(((u32 *)keys.enckey)[i]); 4958c2ecf20Sopenharmony_ci ctx->key_len = keys.enckeylen; 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci memzero_explicit(&keys, sizeof(keys)); 4988c2ecf20Sopenharmony_ci return 0; 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_cibadkey: 5018c2ecf20Sopenharmony_ci memzero_explicit(&keys, sizeof(keys)); 5028c2ecf20Sopenharmony_ci return err; 5038c2ecf20Sopenharmony_ci} 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_cistatic int safexcel_context_control(struct safexcel_cipher_ctx *ctx, 5068c2ecf20Sopenharmony_ci struct crypto_async_request *async, 5078c2ecf20Sopenharmony_ci struct safexcel_cipher_req *sreq, 5088c2ecf20Sopenharmony_ci struct safexcel_command_desc *cdesc) 5098c2ecf20Sopenharmony_ci{ 5108c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 5118c2ecf20Sopenharmony_ci int ctrl_size = ctx->key_len / sizeof(u32); 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci cdesc->control_data.control1 = ctx->mode; 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_ci if (ctx->aead) { 5168c2ecf20Sopenharmony_ci /* Take in account the ipad+opad digests */ 5178c2ecf20Sopenharmony_ci if (ctx->xcm) { 5188c2ecf20Sopenharmony_ci ctrl_size += ctx->state_sz / sizeof(u32); 5198c2ecf20Sopenharmony_ci cdesc->control_data.control0 = 5208c2ecf20Sopenharmony_ci CONTEXT_CONTROL_KEY_EN | 5218c2ecf20Sopenharmony_ci CONTEXT_CONTROL_DIGEST_XCM | 5228c2ecf20Sopenharmony_ci ctx->hash_alg | 5238c2ecf20Sopenharmony_ci CONTEXT_CONTROL_SIZE(ctrl_size); 5248c2ecf20Sopenharmony_ci } else if (ctx->alg == SAFEXCEL_CHACHA20) { 5258c2ecf20Sopenharmony_ci /* Chacha20-Poly1305 */ 5268c2ecf20Sopenharmony_ci cdesc->control_data.control0 = 5278c2ecf20Sopenharmony_ci CONTEXT_CONTROL_KEY_EN | 5288c2ecf20Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 | 5298c2ecf20Sopenharmony_ci (sreq->direction == SAFEXCEL_ENCRYPT ? 5308c2ecf20Sopenharmony_ci CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT : 5318c2ecf20Sopenharmony_ci CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN) | 5328c2ecf20Sopenharmony_ci ctx->hash_alg | 5338c2ecf20Sopenharmony_ci CONTEXT_CONTROL_SIZE(ctrl_size); 5348c2ecf20Sopenharmony_ci return 0; 5358c2ecf20Sopenharmony_ci } else { 5368c2ecf20Sopenharmony_ci ctrl_size += ctx->state_sz / sizeof(u32) * 2; 5378c2ecf20Sopenharmony_ci cdesc->control_data.control0 = 5388c2ecf20Sopenharmony_ci CONTEXT_CONTROL_KEY_EN | 5398c2ecf20Sopenharmony_ci CONTEXT_CONTROL_DIGEST_HMAC | 5408c2ecf20Sopenharmony_ci ctx->hash_alg | 5418c2ecf20Sopenharmony_ci CONTEXT_CONTROL_SIZE(ctrl_size); 5428c2ecf20Sopenharmony_ci } 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_ci if (sreq->direction == SAFEXCEL_ENCRYPT && 5458c2ecf20Sopenharmony_ci (ctx->xcm == EIP197_XCM_MODE_CCM || 5468c2ecf20Sopenharmony_ci ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) 5478c2ecf20Sopenharmony_ci cdesc->control_data.control0 |= 5488c2ecf20Sopenharmony_ci CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT; 5498c2ecf20Sopenharmony_ci else if (sreq->direction == SAFEXCEL_ENCRYPT) 5508c2ecf20Sopenharmony_ci cdesc->control_data.control0 |= 5518c2ecf20Sopenharmony_ci CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT; 5528c2ecf20Sopenharmony_ci else if (ctx->xcm == EIP197_XCM_MODE_CCM) 5538c2ecf20Sopenharmony_ci cdesc->control_data.control0 |= 5548c2ecf20Sopenharmony_ci CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN; 5558c2ecf20Sopenharmony_ci else 5568c2ecf20Sopenharmony_ci cdesc->control_data.control0 |= 5578c2ecf20Sopenharmony_ci CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN; 5588c2ecf20Sopenharmony_ci } else { 5598c2ecf20Sopenharmony_ci if (sreq->direction == SAFEXCEL_ENCRYPT) 5608c2ecf20Sopenharmony_ci cdesc->control_data.control0 = 5618c2ecf20Sopenharmony_ci CONTEXT_CONTROL_TYPE_CRYPTO_OUT | 5628c2ecf20Sopenharmony_ci CONTEXT_CONTROL_KEY_EN | 5638c2ecf20Sopenharmony_ci CONTEXT_CONTROL_SIZE(ctrl_size); 5648c2ecf20Sopenharmony_ci else 5658c2ecf20Sopenharmony_ci cdesc->control_data.control0 = 5668c2ecf20Sopenharmony_ci CONTEXT_CONTROL_TYPE_CRYPTO_IN | 5678c2ecf20Sopenharmony_ci CONTEXT_CONTROL_KEY_EN | 5688c2ecf20Sopenharmony_ci CONTEXT_CONTROL_SIZE(ctrl_size); 5698c2ecf20Sopenharmony_ci } 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci if (ctx->alg == SAFEXCEL_DES) { 5728c2ecf20Sopenharmony_ci cdesc->control_data.control0 |= 5738c2ecf20Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_DES; 5748c2ecf20Sopenharmony_ci } else if (ctx->alg == SAFEXCEL_3DES) { 5758c2ecf20Sopenharmony_ci cdesc->control_data.control0 |= 5768c2ecf20Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_3DES; 5778c2ecf20Sopenharmony_ci } else if (ctx->alg == SAFEXCEL_AES) { 5788c2ecf20Sopenharmony_ci switch (ctx->key_len >> ctx->xts) { 5798c2ecf20Sopenharmony_ci case AES_KEYSIZE_128: 5808c2ecf20Sopenharmony_ci cdesc->control_data.control0 |= 5818c2ecf20Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_AES128; 5828c2ecf20Sopenharmony_ci break; 5838c2ecf20Sopenharmony_ci case AES_KEYSIZE_192: 5848c2ecf20Sopenharmony_ci cdesc->control_data.control0 |= 5858c2ecf20Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_AES192; 5868c2ecf20Sopenharmony_ci break; 5878c2ecf20Sopenharmony_ci case AES_KEYSIZE_256: 5888c2ecf20Sopenharmony_ci cdesc->control_data.control0 |= 5898c2ecf20Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_AES256; 5908c2ecf20Sopenharmony_ci break; 5918c2ecf20Sopenharmony_ci default: 5928c2ecf20Sopenharmony_ci dev_err(priv->dev, "aes keysize not supported: %u\n", 5938c2ecf20Sopenharmony_ci ctx->key_len >> ctx->xts); 5948c2ecf20Sopenharmony_ci return -EINVAL; 5958c2ecf20Sopenharmony_ci } 5968c2ecf20Sopenharmony_ci } else if (ctx->alg == SAFEXCEL_CHACHA20) { 5978c2ecf20Sopenharmony_ci cdesc->control_data.control0 |= 5988c2ecf20Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20; 5998c2ecf20Sopenharmony_ci } else if (ctx->alg == SAFEXCEL_SM4) { 6008c2ecf20Sopenharmony_ci cdesc->control_data.control0 |= 6018c2ecf20Sopenharmony_ci CONTEXT_CONTROL_CRYPTO_ALG_SM4; 6028c2ecf20Sopenharmony_ci } 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci return 0; 6058c2ecf20Sopenharmony_ci} 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_cistatic int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring, 6088c2ecf20Sopenharmony_ci struct crypto_async_request *async, 6098c2ecf20Sopenharmony_ci struct scatterlist *src, 6108c2ecf20Sopenharmony_ci struct scatterlist *dst, 6118c2ecf20Sopenharmony_ci unsigned int cryptlen, 6128c2ecf20Sopenharmony_ci struct safexcel_cipher_req *sreq, 6138c2ecf20Sopenharmony_ci bool *should_complete, int *ret) 6148c2ecf20Sopenharmony_ci{ 6158c2ecf20Sopenharmony_ci struct skcipher_request *areq = skcipher_request_cast(async); 6168c2ecf20Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq); 6178c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(skcipher); 6188c2ecf20Sopenharmony_ci struct safexcel_result_desc *rdesc; 6198c2ecf20Sopenharmony_ci int ndesc = 0; 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci *ret = 0; 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ci if (unlikely(!sreq->rdescs)) 6248c2ecf20Sopenharmony_ci return 0; 6258c2ecf20Sopenharmony_ci 6268c2ecf20Sopenharmony_ci while (sreq->rdescs--) { 6278c2ecf20Sopenharmony_ci rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr); 6288c2ecf20Sopenharmony_ci if (IS_ERR(rdesc)) { 6298c2ecf20Sopenharmony_ci dev_err(priv->dev, 6308c2ecf20Sopenharmony_ci "cipher: result: could not retrieve the result descriptor\n"); 6318c2ecf20Sopenharmony_ci *ret = PTR_ERR(rdesc); 6328c2ecf20Sopenharmony_ci break; 6338c2ecf20Sopenharmony_ci } 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_ci if (likely(!*ret)) 6368c2ecf20Sopenharmony_ci *ret = safexcel_rdesc_check_errors(priv, rdesc); 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci ndesc++; 6398c2ecf20Sopenharmony_ci } 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci safexcel_complete(priv, ring); 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_ci if (src == dst) { 6448c2ecf20Sopenharmony_ci dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL); 6458c2ecf20Sopenharmony_ci } else { 6468c2ecf20Sopenharmony_ci dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 6478c2ecf20Sopenharmony_ci dma_unmap_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE); 6488c2ecf20Sopenharmony_ci } 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci /* 6518c2ecf20Sopenharmony_ci * Update IV in req from last crypto output word for CBC modes 6528c2ecf20Sopenharmony_ci */ 6538c2ecf20Sopenharmony_ci if ((!ctx->aead) && (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) && 6548c2ecf20Sopenharmony_ci (sreq->direction == SAFEXCEL_ENCRYPT)) { 6558c2ecf20Sopenharmony_ci /* For encrypt take the last output word */ 6568c2ecf20Sopenharmony_ci sg_pcopy_to_buffer(dst, sreq->nr_dst, areq->iv, 6578c2ecf20Sopenharmony_ci crypto_skcipher_ivsize(skcipher), 6588c2ecf20Sopenharmony_ci (cryptlen - 6598c2ecf20Sopenharmony_ci crypto_skcipher_ivsize(skcipher))); 6608c2ecf20Sopenharmony_ci } 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_ci *should_complete = true; 6638c2ecf20Sopenharmony_ci 6648c2ecf20Sopenharmony_ci return ndesc; 6658c2ecf20Sopenharmony_ci} 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_cistatic int safexcel_send_req(struct crypto_async_request *base, int ring, 6688c2ecf20Sopenharmony_ci struct safexcel_cipher_req *sreq, 6698c2ecf20Sopenharmony_ci struct scatterlist *src, struct scatterlist *dst, 6708c2ecf20Sopenharmony_ci unsigned int cryptlen, unsigned int assoclen, 6718c2ecf20Sopenharmony_ci unsigned int digestsize, u8 *iv, int *commands, 6728c2ecf20Sopenharmony_ci int *results) 6738c2ecf20Sopenharmony_ci{ 6748c2ecf20Sopenharmony_ci struct skcipher_request *areq = skcipher_request_cast(base); 6758c2ecf20Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq); 6768c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 6778c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 6788c2ecf20Sopenharmony_ci struct safexcel_command_desc *cdesc; 6798c2ecf20Sopenharmony_ci struct safexcel_command_desc *first_cdesc = NULL; 6808c2ecf20Sopenharmony_ci struct safexcel_result_desc *rdesc, *first_rdesc = NULL; 6818c2ecf20Sopenharmony_ci struct scatterlist *sg; 6828c2ecf20Sopenharmony_ci unsigned int totlen; 6838c2ecf20Sopenharmony_ci unsigned int totlen_src = cryptlen + assoclen; 6848c2ecf20Sopenharmony_ci unsigned int totlen_dst = totlen_src; 6858c2ecf20Sopenharmony_ci struct safexcel_token *atoken; 6868c2ecf20Sopenharmony_ci int n_cdesc = 0, n_rdesc = 0; 6878c2ecf20Sopenharmony_ci int queued, i, ret = 0; 6888c2ecf20Sopenharmony_ci bool first = true; 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci sreq->nr_src = sg_nents_for_len(src, totlen_src); 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci if (ctx->aead) { 6938c2ecf20Sopenharmony_ci /* 6948c2ecf20Sopenharmony_ci * AEAD has auth tag appended to output for encrypt and 6958c2ecf20Sopenharmony_ci * removed from the output for decrypt! 6968c2ecf20Sopenharmony_ci */ 6978c2ecf20Sopenharmony_ci if (sreq->direction == SAFEXCEL_DECRYPT) 6988c2ecf20Sopenharmony_ci totlen_dst -= digestsize; 6998c2ecf20Sopenharmony_ci else 7008c2ecf20Sopenharmony_ci totlen_dst += digestsize; 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci memcpy(ctx->base.ctxr->data + ctx->key_len / sizeof(u32), 7038c2ecf20Sopenharmony_ci &ctx->base.ipad, ctx->state_sz); 7048c2ecf20Sopenharmony_ci if (!ctx->xcm) 7058c2ecf20Sopenharmony_ci memcpy(ctx->base.ctxr->data + (ctx->key_len + 7068c2ecf20Sopenharmony_ci ctx->state_sz) / sizeof(u32), &ctx->base.opad, 7078c2ecf20Sopenharmony_ci ctx->state_sz); 7088c2ecf20Sopenharmony_ci } else if ((ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) && 7098c2ecf20Sopenharmony_ci (sreq->direction == SAFEXCEL_DECRYPT)) { 7108c2ecf20Sopenharmony_ci /* 7118c2ecf20Sopenharmony_ci * Save IV from last crypto input word for CBC modes in decrypt 7128c2ecf20Sopenharmony_ci * direction. Need to do this first in case of inplace operation 7138c2ecf20Sopenharmony_ci * as it will be overwritten. 7148c2ecf20Sopenharmony_ci */ 7158c2ecf20Sopenharmony_ci sg_pcopy_to_buffer(src, sreq->nr_src, areq->iv, 7168c2ecf20Sopenharmony_ci crypto_skcipher_ivsize(skcipher), 7178c2ecf20Sopenharmony_ci (totlen_src - 7188c2ecf20Sopenharmony_ci crypto_skcipher_ivsize(skcipher))); 7198c2ecf20Sopenharmony_ci } 7208c2ecf20Sopenharmony_ci 7218c2ecf20Sopenharmony_ci sreq->nr_dst = sg_nents_for_len(dst, totlen_dst); 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci /* 7248c2ecf20Sopenharmony_ci * Remember actual input length, source buffer length may be 7258c2ecf20Sopenharmony_ci * updated in case of inline operation below. 7268c2ecf20Sopenharmony_ci */ 7278c2ecf20Sopenharmony_ci totlen = totlen_src; 7288c2ecf20Sopenharmony_ci queued = totlen_src; 7298c2ecf20Sopenharmony_ci 7308c2ecf20Sopenharmony_ci if (src == dst) { 7318c2ecf20Sopenharmony_ci sreq->nr_src = max(sreq->nr_src, sreq->nr_dst); 7328c2ecf20Sopenharmony_ci sreq->nr_dst = sreq->nr_src; 7338c2ecf20Sopenharmony_ci if (unlikely((totlen_src || totlen_dst) && 7348c2ecf20Sopenharmony_ci (sreq->nr_src <= 0))) { 7358c2ecf20Sopenharmony_ci dev_err(priv->dev, "In-place buffer not large enough (need %d bytes)!", 7368c2ecf20Sopenharmony_ci max(totlen_src, totlen_dst)); 7378c2ecf20Sopenharmony_ci return -EINVAL; 7388c2ecf20Sopenharmony_ci } 7398c2ecf20Sopenharmony_ci dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL); 7408c2ecf20Sopenharmony_ci } else { 7418c2ecf20Sopenharmony_ci if (unlikely(totlen_src && (sreq->nr_src <= 0))) { 7428c2ecf20Sopenharmony_ci dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!", 7438c2ecf20Sopenharmony_ci totlen_src); 7448c2ecf20Sopenharmony_ci return -EINVAL; 7458c2ecf20Sopenharmony_ci } 7468c2ecf20Sopenharmony_ci dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 7478c2ecf20Sopenharmony_ci 7488c2ecf20Sopenharmony_ci if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) { 7498c2ecf20Sopenharmony_ci dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!", 7508c2ecf20Sopenharmony_ci totlen_dst); 7518c2ecf20Sopenharmony_ci dma_unmap_sg(priv->dev, src, sreq->nr_src, 7528c2ecf20Sopenharmony_ci DMA_TO_DEVICE); 7538c2ecf20Sopenharmony_ci return -EINVAL; 7548c2ecf20Sopenharmony_ci } 7558c2ecf20Sopenharmony_ci dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE); 7568c2ecf20Sopenharmony_ci } 7578c2ecf20Sopenharmony_ci 7588c2ecf20Sopenharmony_ci memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len); 7598c2ecf20Sopenharmony_ci 7608c2ecf20Sopenharmony_ci if (!totlen) { 7618c2ecf20Sopenharmony_ci /* 7628c2ecf20Sopenharmony_ci * The EIP97 cannot deal with zero length input packets! 7638c2ecf20Sopenharmony_ci * So stuff a dummy command descriptor indicating a 1 byte 7648c2ecf20Sopenharmony_ci * (dummy) input packet, using the context record as source. 7658c2ecf20Sopenharmony_ci */ 7668c2ecf20Sopenharmony_ci first_cdesc = safexcel_add_cdesc(priv, ring, 7678c2ecf20Sopenharmony_ci 1, 1, ctx->base.ctxr_dma, 7688c2ecf20Sopenharmony_ci 1, 1, ctx->base.ctxr_dma, 7698c2ecf20Sopenharmony_ci &atoken); 7708c2ecf20Sopenharmony_ci if (IS_ERR(first_cdesc)) { 7718c2ecf20Sopenharmony_ci /* No space left in the command descriptor ring */ 7728c2ecf20Sopenharmony_ci ret = PTR_ERR(first_cdesc); 7738c2ecf20Sopenharmony_ci goto cdesc_rollback; 7748c2ecf20Sopenharmony_ci } 7758c2ecf20Sopenharmony_ci n_cdesc = 1; 7768c2ecf20Sopenharmony_ci goto skip_cdesc; 7778c2ecf20Sopenharmony_ci } 7788c2ecf20Sopenharmony_ci 7798c2ecf20Sopenharmony_ci /* command descriptors */ 7808c2ecf20Sopenharmony_ci for_each_sg(src, sg, sreq->nr_src, i) { 7818c2ecf20Sopenharmony_ci int len = sg_dma_len(sg); 7828c2ecf20Sopenharmony_ci 7838c2ecf20Sopenharmony_ci /* Do not overflow the request */ 7848c2ecf20Sopenharmony_ci if (queued < len) 7858c2ecf20Sopenharmony_ci len = queued; 7868c2ecf20Sopenharmony_ci 7878c2ecf20Sopenharmony_ci cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc, 7888c2ecf20Sopenharmony_ci !(queued - len), 7898c2ecf20Sopenharmony_ci sg_dma_address(sg), len, totlen, 7908c2ecf20Sopenharmony_ci ctx->base.ctxr_dma, &atoken); 7918c2ecf20Sopenharmony_ci if (IS_ERR(cdesc)) { 7928c2ecf20Sopenharmony_ci /* No space left in the command descriptor ring */ 7938c2ecf20Sopenharmony_ci ret = PTR_ERR(cdesc); 7948c2ecf20Sopenharmony_ci goto cdesc_rollback; 7958c2ecf20Sopenharmony_ci } 7968c2ecf20Sopenharmony_ci 7978c2ecf20Sopenharmony_ci if (!n_cdesc) 7988c2ecf20Sopenharmony_ci first_cdesc = cdesc; 7998c2ecf20Sopenharmony_ci 8008c2ecf20Sopenharmony_ci n_cdesc++; 8018c2ecf20Sopenharmony_ci queued -= len; 8028c2ecf20Sopenharmony_ci if (!queued) 8038c2ecf20Sopenharmony_ci break; 8048c2ecf20Sopenharmony_ci } 8058c2ecf20Sopenharmony_ciskip_cdesc: 8068c2ecf20Sopenharmony_ci /* Add context control words and token to first command descriptor */ 8078c2ecf20Sopenharmony_ci safexcel_context_control(ctx, base, sreq, first_cdesc); 8088c2ecf20Sopenharmony_ci if (ctx->aead) 8098c2ecf20Sopenharmony_ci safexcel_aead_token(ctx, iv, first_cdesc, atoken, 8108c2ecf20Sopenharmony_ci sreq->direction, cryptlen, 8118c2ecf20Sopenharmony_ci assoclen, digestsize); 8128c2ecf20Sopenharmony_ci else 8138c2ecf20Sopenharmony_ci safexcel_skcipher_token(ctx, iv, first_cdesc, atoken, 8148c2ecf20Sopenharmony_ci cryptlen); 8158c2ecf20Sopenharmony_ci 8168c2ecf20Sopenharmony_ci /* result descriptors */ 8178c2ecf20Sopenharmony_ci for_each_sg(dst, sg, sreq->nr_dst, i) { 8188c2ecf20Sopenharmony_ci bool last = (i == sreq->nr_dst - 1); 8198c2ecf20Sopenharmony_ci u32 len = sg_dma_len(sg); 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_ci /* only allow the part of the buffer we know we need */ 8228c2ecf20Sopenharmony_ci if (len > totlen_dst) 8238c2ecf20Sopenharmony_ci len = totlen_dst; 8248c2ecf20Sopenharmony_ci if (unlikely(!len)) 8258c2ecf20Sopenharmony_ci break; 8268c2ecf20Sopenharmony_ci totlen_dst -= len; 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_ci /* skip over AAD space in buffer - not written */ 8298c2ecf20Sopenharmony_ci if (assoclen) { 8308c2ecf20Sopenharmony_ci if (assoclen >= len) { 8318c2ecf20Sopenharmony_ci assoclen -= len; 8328c2ecf20Sopenharmony_ci continue; 8338c2ecf20Sopenharmony_ci } 8348c2ecf20Sopenharmony_ci rdesc = safexcel_add_rdesc(priv, ring, first, last, 8358c2ecf20Sopenharmony_ci sg_dma_address(sg) + 8368c2ecf20Sopenharmony_ci assoclen, 8378c2ecf20Sopenharmony_ci len - assoclen); 8388c2ecf20Sopenharmony_ci assoclen = 0; 8398c2ecf20Sopenharmony_ci } else { 8408c2ecf20Sopenharmony_ci rdesc = safexcel_add_rdesc(priv, ring, first, last, 8418c2ecf20Sopenharmony_ci sg_dma_address(sg), 8428c2ecf20Sopenharmony_ci len); 8438c2ecf20Sopenharmony_ci } 8448c2ecf20Sopenharmony_ci if (IS_ERR(rdesc)) { 8458c2ecf20Sopenharmony_ci /* No space left in the result descriptor ring */ 8468c2ecf20Sopenharmony_ci ret = PTR_ERR(rdesc); 8478c2ecf20Sopenharmony_ci goto rdesc_rollback; 8488c2ecf20Sopenharmony_ci } 8498c2ecf20Sopenharmony_ci if (first) { 8508c2ecf20Sopenharmony_ci first_rdesc = rdesc; 8518c2ecf20Sopenharmony_ci first = false; 8528c2ecf20Sopenharmony_ci } 8538c2ecf20Sopenharmony_ci n_rdesc++; 8548c2ecf20Sopenharmony_ci } 8558c2ecf20Sopenharmony_ci 8568c2ecf20Sopenharmony_ci if (unlikely(first)) { 8578c2ecf20Sopenharmony_ci /* 8588c2ecf20Sopenharmony_ci * Special case: AEAD decrypt with only AAD data. 8598c2ecf20Sopenharmony_ci * In this case there is NO output data from the engine, 8608c2ecf20Sopenharmony_ci * but the engine still needs a result descriptor! 8618c2ecf20Sopenharmony_ci * Create a dummy one just for catching the result token. 8628c2ecf20Sopenharmony_ci */ 8638c2ecf20Sopenharmony_ci rdesc = safexcel_add_rdesc(priv, ring, true, true, 0, 0); 8648c2ecf20Sopenharmony_ci if (IS_ERR(rdesc)) { 8658c2ecf20Sopenharmony_ci /* No space left in the result descriptor ring */ 8668c2ecf20Sopenharmony_ci ret = PTR_ERR(rdesc); 8678c2ecf20Sopenharmony_ci goto rdesc_rollback; 8688c2ecf20Sopenharmony_ci } 8698c2ecf20Sopenharmony_ci first_rdesc = rdesc; 8708c2ecf20Sopenharmony_ci n_rdesc = 1; 8718c2ecf20Sopenharmony_ci } 8728c2ecf20Sopenharmony_ci 8738c2ecf20Sopenharmony_ci safexcel_rdr_req_set(priv, ring, first_rdesc, base); 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_ci *commands = n_cdesc; 8768c2ecf20Sopenharmony_ci *results = n_rdesc; 8778c2ecf20Sopenharmony_ci return 0; 8788c2ecf20Sopenharmony_ci 8798c2ecf20Sopenharmony_cirdesc_rollback: 8808c2ecf20Sopenharmony_ci for (i = 0; i < n_rdesc; i++) 8818c2ecf20Sopenharmony_ci safexcel_ring_rollback_wptr(priv, &priv->ring[ring].rdr); 8828c2ecf20Sopenharmony_cicdesc_rollback: 8838c2ecf20Sopenharmony_ci for (i = 0; i < n_cdesc; i++) 8848c2ecf20Sopenharmony_ci safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr); 8858c2ecf20Sopenharmony_ci 8868c2ecf20Sopenharmony_ci if (src == dst) { 8878c2ecf20Sopenharmony_ci dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL); 8888c2ecf20Sopenharmony_ci } else { 8898c2ecf20Sopenharmony_ci dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 8908c2ecf20Sopenharmony_ci dma_unmap_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE); 8918c2ecf20Sopenharmony_ci } 8928c2ecf20Sopenharmony_ci 8938c2ecf20Sopenharmony_ci return ret; 8948c2ecf20Sopenharmony_ci} 8958c2ecf20Sopenharmony_ci 8968c2ecf20Sopenharmony_cistatic int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv, 8978c2ecf20Sopenharmony_ci int ring, 8988c2ecf20Sopenharmony_ci struct crypto_async_request *base, 8998c2ecf20Sopenharmony_ci struct safexcel_cipher_req *sreq, 9008c2ecf20Sopenharmony_ci bool *should_complete, int *ret) 9018c2ecf20Sopenharmony_ci{ 9028c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 9038c2ecf20Sopenharmony_ci struct safexcel_result_desc *rdesc; 9048c2ecf20Sopenharmony_ci int ndesc = 0, enq_ret; 9058c2ecf20Sopenharmony_ci 9068c2ecf20Sopenharmony_ci *ret = 0; 9078c2ecf20Sopenharmony_ci 9088c2ecf20Sopenharmony_ci if (unlikely(!sreq->rdescs)) 9098c2ecf20Sopenharmony_ci return 0; 9108c2ecf20Sopenharmony_ci 9118c2ecf20Sopenharmony_ci while (sreq->rdescs--) { 9128c2ecf20Sopenharmony_ci rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr); 9138c2ecf20Sopenharmony_ci if (IS_ERR(rdesc)) { 9148c2ecf20Sopenharmony_ci dev_err(priv->dev, 9158c2ecf20Sopenharmony_ci "cipher: invalidate: could not retrieve the result descriptor\n"); 9168c2ecf20Sopenharmony_ci *ret = PTR_ERR(rdesc); 9178c2ecf20Sopenharmony_ci break; 9188c2ecf20Sopenharmony_ci } 9198c2ecf20Sopenharmony_ci 9208c2ecf20Sopenharmony_ci if (likely(!*ret)) 9218c2ecf20Sopenharmony_ci *ret = safexcel_rdesc_check_errors(priv, rdesc); 9228c2ecf20Sopenharmony_ci 9238c2ecf20Sopenharmony_ci ndesc++; 9248c2ecf20Sopenharmony_ci } 9258c2ecf20Sopenharmony_ci 9268c2ecf20Sopenharmony_ci safexcel_complete(priv, ring); 9278c2ecf20Sopenharmony_ci 9288c2ecf20Sopenharmony_ci if (ctx->base.exit_inv) { 9298c2ecf20Sopenharmony_ci dma_pool_free(priv->context_pool, ctx->base.ctxr, 9308c2ecf20Sopenharmony_ci ctx->base.ctxr_dma); 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_ci *should_complete = true; 9338c2ecf20Sopenharmony_ci 9348c2ecf20Sopenharmony_ci return ndesc; 9358c2ecf20Sopenharmony_ci } 9368c2ecf20Sopenharmony_ci 9378c2ecf20Sopenharmony_ci ring = safexcel_select_ring(priv); 9388c2ecf20Sopenharmony_ci ctx->base.ring = ring; 9398c2ecf20Sopenharmony_ci 9408c2ecf20Sopenharmony_ci spin_lock_bh(&priv->ring[ring].queue_lock); 9418c2ecf20Sopenharmony_ci enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, base); 9428c2ecf20Sopenharmony_ci spin_unlock_bh(&priv->ring[ring].queue_lock); 9438c2ecf20Sopenharmony_ci 9448c2ecf20Sopenharmony_ci if (enq_ret != -EINPROGRESS) 9458c2ecf20Sopenharmony_ci *ret = enq_ret; 9468c2ecf20Sopenharmony_ci 9478c2ecf20Sopenharmony_ci queue_work(priv->ring[ring].workqueue, 9488c2ecf20Sopenharmony_ci &priv->ring[ring].work_data.work); 9498c2ecf20Sopenharmony_ci 9508c2ecf20Sopenharmony_ci *should_complete = false; 9518c2ecf20Sopenharmony_ci 9528c2ecf20Sopenharmony_ci return ndesc; 9538c2ecf20Sopenharmony_ci} 9548c2ecf20Sopenharmony_ci 9558c2ecf20Sopenharmony_cistatic int safexcel_skcipher_handle_result(struct safexcel_crypto_priv *priv, 9568c2ecf20Sopenharmony_ci int ring, 9578c2ecf20Sopenharmony_ci struct crypto_async_request *async, 9588c2ecf20Sopenharmony_ci bool *should_complete, int *ret) 9598c2ecf20Sopenharmony_ci{ 9608c2ecf20Sopenharmony_ci struct skcipher_request *req = skcipher_request_cast(async); 9618c2ecf20Sopenharmony_ci struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 9628c2ecf20Sopenharmony_ci int err; 9638c2ecf20Sopenharmony_ci 9648c2ecf20Sopenharmony_ci if (sreq->needs_inv) { 9658c2ecf20Sopenharmony_ci sreq->needs_inv = false; 9668c2ecf20Sopenharmony_ci err = safexcel_handle_inv_result(priv, ring, async, sreq, 9678c2ecf20Sopenharmony_ci should_complete, ret); 9688c2ecf20Sopenharmony_ci } else { 9698c2ecf20Sopenharmony_ci err = safexcel_handle_req_result(priv, ring, async, req->src, 9708c2ecf20Sopenharmony_ci req->dst, req->cryptlen, sreq, 9718c2ecf20Sopenharmony_ci should_complete, ret); 9728c2ecf20Sopenharmony_ci } 9738c2ecf20Sopenharmony_ci 9748c2ecf20Sopenharmony_ci return err; 9758c2ecf20Sopenharmony_ci} 9768c2ecf20Sopenharmony_ci 9778c2ecf20Sopenharmony_cistatic int safexcel_aead_handle_result(struct safexcel_crypto_priv *priv, 9788c2ecf20Sopenharmony_ci int ring, 9798c2ecf20Sopenharmony_ci struct crypto_async_request *async, 9808c2ecf20Sopenharmony_ci bool *should_complete, int *ret) 9818c2ecf20Sopenharmony_ci{ 9828c2ecf20Sopenharmony_ci struct aead_request *req = aead_request_cast(async); 9838c2ecf20Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 9848c2ecf20Sopenharmony_ci struct safexcel_cipher_req *sreq = aead_request_ctx(req); 9858c2ecf20Sopenharmony_ci int err; 9868c2ecf20Sopenharmony_ci 9878c2ecf20Sopenharmony_ci if (sreq->needs_inv) { 9888c2ecf20Sopenharmony_ci sreq->needs_inv = false; 9898c2ecf20Sopenharmony_ci err = safexcel_handle_inv_result(priv, ring, async, sreq, 9908c2ecf20Sopenharmony_ci should_complete, ret); 9918c2ecf20Sopenharmony_ci } else { 9928c2ecf20Sopenharmony_ci err = safexcel_handle_req_result(priv, ring, async, req->src, 9938c2ecf20Sopenharmony_ci req->dst, 9948c2ecf20Sopenharmony_ci req->cryptlen + crypto_aead_authsize(tfm), 9958c2ecf20Sopenharmony_ci sreq, should_complete, ret); 9968c2ecf20Sopenharmony_ci } 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_ci return err; 9998c2ecf20Sopenharmony_ci} 10008c2ecf20Sopenharmony_ci 10018c2ecf20Sopenharmony_cistatic int safexcel_cipher_send_inv(struct crypto_async_request *base, 10028c2ecf20Sopenharmony_ci int ring, int *commands, int *results) 10038c2ecf20Sopenharmony_ci{ 10048c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 10058c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 10068c2ecf20Sopenharmony_ci int ret; 10078c2ecf20Sopenharmony_ci 10088c2ecf20Sopenharmony_ci ret = safexcel_invalidate_cache(base, priv, ctx->base.ctxr_dma, ring); 10098c2ecf20Sopenharmony_ci if (unlikely(ret)) 10108c2ecf20Sopenharmony_ci return ret; 10118c2ecf20Sopenharmony_ci 10128c2ecf20Sopenharmony_ci *commands = 1; 10138c2ecf20Sopenharmony_ci *results = 1; 10148c2ecf20Sopenharmony_ci 10158c2ecf20Sopenharmony_ci return 0; 10168c2ecf20Sopenharmony_ci} 10178c2ecf20Sopenharmony_ci 10188c2ecf20Sopenharmony_cistatic int safexcel_skcipher_send(struct crypto_async_request *async, int ring, 10198c2ecf20Sopenharmony_ci int *commands, int *results) 10208c2ecf20Sopenharmony_ci{ 10218c2ecf20Sopenharmony_ci struct skcipher_request *req = skcipher_request_cast(async); 10228c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 10238c2ecf20Sopenharmony_ci struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 10248c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 10258c2ecf20Sopenharmony_ci int ret; 10268c2ecf20Sopenharmony_ci 10278c2ecf20Sopenharmony_ci BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv); 10288c2ecf20Sopenharmony_ci 10298c2ecf20Sopenharmony_ci if (sreq->needs_inv) { 10308c2ecf20Sopenharmony_ci ret = safexcel_cipher_send_inv(async, ring, commands, results); 10318c2ecf20Sopenharmony_ci } else { 10328c2ecf20Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 10338c2ecf20Sopenharmony_ci u8 input_iv[AES_BLOCK_SIZE]; 10348c2ecf20Sopenharmony_ci 10358c2ecf20Sopenharmony_ci /* 10368c2ecf20Sopenharmony_ci * Save input IV in case of CBC decrypt mode 10378c2ecf20Sopenharmony_ci * Will be overwritten with output IV prior to use! 10388c2ecf20Sopenharmony_ci */ 10398c2ecf20Sopenharmony_ci memcpy(input_iv, req->iv, crypto_skcipher_ivsize(skcipher)); 10408c2ecf20Sopenharmony_ci 10418c2ecf20Sopenharmony_ci ret = safexcel_send_req(async, ring, sreq, req->src, 10428c2ecf20Sopenharmony_ci req->dst, req->cryptlen, 0, 0, input_iv, 10438c2ecf20Sopenharmony_ci commands, results); 10448c2ecf20Sopenharmony_ci } 10458c2ecf20Sopenharmony_ci 10468c2ecf20Sopenharmony_ci sreq->rdescs = *results; 10478c2ecf20Sopenharmony_ci return ret; 10488c2ecf20Sopenharmony_ci} 10498c2ecf20Sopenharmony_ci 10508c2ecf20Sopenharmony_cistatic int safexcel_aead_send(struct crypto_async_request *async, int ring, 10518c2ecf20Sopenharmony_ci int *commands, int *results) 10528c2ecf20Sopenharmony_ci{ 10538c2ecf20Sopenharmony_ci struct aead_request *req = aead_request_cast(async); 10548c2ecf20Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 10558c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 10568c2ecf20Sopenharmony_ci struct safexcel_cipher_req *sreq = aead_request_ctx(req); 10578c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 10588c2ecf20Sopenharmony_ci int ret; 10598c2ecf20Sopenharmony_ci 10608c2ecf20Sopenharmony_ci BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv); 10618c2ecf20Sopenharmony_ci 10628c2ecf20Sopenharmony_ci if (sreq->needs_inv) 10638c2ecf20Sopenharmony_ci ret = safexcel_cipher_send_inv(async, ring, commands, results); 10648c2ecf20Sopenharmony_ci else 10658c2ecf20Sopenharmony_ci ret = safexcel_send_req(async, ring, sreq, req->src, req->dst, 10668c2ecf20Sopenharmony_ci req->cryptlen, req->assoclen, 10678c2ecf20Sopenharmony_ci crypto_aead_authsize(tfm), req->iv, 10688c2ecf20Sopenharmony_ci commands, results); 10698c2ecf20Sopenharmony_ci sreq->rdescs = *results; 10708c2ecf20Sopenharmony_ci return ret; 10718c2ecf20Sopenharmony_ci} 10728c2ecf20Sopenharmony_ci 10738c2ecf20Sopenharmony_cistatic int safexcel_cipher_exit_inv(struct crypto_tfm *tfm, 10748c2ecf20Sopenharmony_ci struct crypto_async_request *base, 10758c2ecf20Sopenharmony_ci struct safexcel_cipher_req *sreq, 10768c2ecf20Sopenharmony_ci struct safexcel_inv_result *result) 10778c2ecf20Sopenharmony_ci{ 10788c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 10798c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 10808c2ecf20Sopenharmony_ci int ring = ctx->base.ring; 10818c2ecf20Sopenharmony_ci 10828c2ecf20Sopenharmony_ci init_completion(&result->completion); 10838c2ecf20Sopenharmony_ci 10848c2ecf20Sopenharmony_ci ctx = crypto_tfm_ctx(base->tfm); 10858c2ecf20Sopenharmony_ci ctx->base.exit_inv = true; 10868c2ecf20Sopenharmony_ci sreq->needs_inv = true; 10878c2ecf20Sopenharmony_ci 10888c2ecf20Sopenharmony_ci spin_lock_bh(&priv->ring[ring].queue_lock); 10898c2ecf20Sopenharmony_ci crypto_enqueue_request(&priv->ring[ring].queue, base); 10908c2ecf20Sopenharmony_ci spin_unlock_bh(&priv->ring[ring].queue_lock); 10918c2ecf20Sopenharmony_ci 10928c2ecf20Sopenharmony_ci queue_work(priv->ring[ring].workqueue, 10938c2ecf20Sopenharmony_ci &priv->ring[ring].work_data.work); 10948c2ecf20Sopenharmony_ci 10958c2ecf20Sopenharmony_ci wait_for_completion(&result->completion); 10968c2ecf20Sopenharmony_ci 10978c2ecf20Sopenharmony_ci if (result->error) { 10988c2ecf20Sopenharmony_ci dev_warn(priv->dev, 10998c2ecf20Sopenharmony_ci "cipher: sync: invalidate: completion error %d\n", 11008c2ecf20Sopenharmony_ci result->error); 11018c2ecf20Sopenharmony_ci return result->error; 11028c2ecf20Sopenharmony_ci } 11038c2ecf20Sopenharmony_ci 11048c2ecf20Sopenharmony_ci return 0; 11058c2ecf20Sopenharmony_ci} 11068c2ecf20Sopenharmony_ci 11078c2ecf20Sopenharmony_cistatic int safexcel_skcipher_exit_inv(struct crypto_tfm *tfm) 11088c2ecf20Sopenharmony_ci{ 11098c2ecf20Sopenharmony_ci EIP197_REQUEST_ON_STACK(req, skcipher, EIP197_SKCIPHER_REQ_SIZE); 11108c2ecf20Sopenharmony_ci struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 11118c2ecf20Sopenharmony_ci struct safexcel_inv_result result = {}; 11128c2ecf20Sopenharmony_ci 11138c2ecf20Sopenharmony_ci memset(req, 0, sizeof(struct skcipher_request)); 11148c2ecf20Sopenharmony_ci 11158c2ecf20Sopenharmony_ci skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 11168c2ecf20Sopenharmony_ci safexcel_inv_complete, &result); 11178c2ecf20Sopenharmony_ci skcipher_request_set_tfm(req, __crypto_skcipher_cast(tfm)); 11188c2ecf20Sopenharmony_ci 11198c2ecf20Sopenharmony_ci return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result); 11208c2ecf20Sopenharmony_ci} 11218c2ecf20Sopenharmony_ci 11228c2ecf20Sopenharmony_cistatic int safexcel_aead_exit_inv(struct crypto_tfm *tfm) 11238c2ecf20Sopenharmony_ci{ 11248c2ecf20Sopenharmony_ci EIP197_REQUEST_ON_STACK(req, aead, EIP197_AEAD_REQ_SIZE); 11258c2ecf20Sopenharmony_ci struct safexcel_cipher_req *sreq = aead_request_ctx(req); 11268c2ecf20Sopenharmony_ci struct safexcel_inv_result result = {}; 11278c2ecf20Sopenharmony_ci 11288c2ecf20Sopenharmony_ci memset(req, 0, sizeof(struct aead_request)); 11298c2ecf20Sopenharmony_ci 11308c2ecf20Sopenharmony_ci aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 11318c2ecf20Sopenharmony_ci safexcel_inv_complete, &result); 11328c2ecf20Sopenharmony_ci aead_request_set_tfm(req, __crypto_aead_cast(tfm)); 11338c2ecf20Sopenharmony_ci 11348c2ecf20Sopenharmony_ci return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result); 11358c2ecf20Sopenharmony_ci} 11368c2ecf20Sopenharmony_ci 11378c2ecf20Sopenharmony_cistatic int safexcel_queue_req(struct crypto_async_request *base, 11388c2ecf20Sopenharmony_ci struct safexcel_cipher_req *sreq, 11398c2ecf20Sopenharmony_ci enum safexcel_cipher_direction dir) 11408c2ecf20Sopenharmony_ci{ 11418c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 11428c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 11438c2ecf20Sopenharmony_ci int ret, ring; 11448c2ecf20Sopenharmony_ci 11458c2ecf20Sopenharmony_ci sreq->needs_inv = false; 11468c2ecf20Sopenharmony_ci sreq->direction = dir; 11478c2ecf20Sopenharmony_ci 11488c2ecf20Sopenharmony_ci if (ctx->base.ctxr) { 11498c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.needs_inv) { 11508c2ecf20Sopenharmony_ci sreq->needs_inv = true; 11518c2ecf20Sopenharmony_ci ctx->base.needs_inv = false; 11528c2ecf20Sopenharmony_ci } 11538c2ecf20Sopenharmony_ci } else { 11548c2ecf20Sopenharmony_ci ctx->base.ring = safexcel_select_ring(priv); 11558c2ecf20Sopenharmony_ci ctx->base.ctxr = dma_pool_zalloc(priv->context_pool, 11568c2ecf20Sopenharmony_ci EIP197_GFP_FLAGS(*base), 11578c2ecf20Sopenharmony_ci &ctx->base.ctxr_dma); 11588c2ecf20Sopenharmony_ci if (!ctx->base.ctxr) 11598c2ecf20Sopenharmony_ci return -ENOMEM; 11608c2ecf20Sopenharmony_ci } 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci ring = ctx->base.ring; 11638c2ecf20Sopenharmony_ci 11648c2ecf20Sopenharmony_ci spin_lock_bh(&priv->ring[ring].queue_lock); 11658c2ecf20Sopenharmony_ci ret = crypto_enqueue_request(&priv->ring[ring].queue, base); 11668c2ecf20Sopenharmony_ci spin_unlock_bh(&priv->ring[ring].queue_lock); 11678c2ecf20Sopenharmony_ci 11688c2ecf20Sopenharmony_ci queue_work(priv->ring[ring].workqueue, 11698c2ecf20Sopenharmony_ci &priv->ring[ring].work_data.work); 11708c2ecf20Sopenharmony_ci 11718c2ecf20Sopenharmony_ci return ret; 11728c2ecf20Sopenharmony_ci} 11738c2ecf20Sopenharmony_ci 11748c2ecf20Sopenharmony_cistatic int safexcel_encrypt(struct skcipher_request *req) 11758c2ecf20Sopenharmony_ci{ 11768c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 11778c2ecf20Sopenharmony_ci SAFEXCEL_ENCRYPT); 11788c2ecf20Sopenharmony_ci} 11798c2ecf20Sopenharmony_ci 11808c2ecf20Sopenharmony_cistatic int safexcel_decrypt(struct skcipher_request *req) 11818c2ecf20Sopenharmony_ci{ 11828c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 11838c2ecf20Sopenharmony_ci SAFEXCEL_DECRYPT); 11848c2ecf20Sopenharmony_ci} 11858c2ecf20Sopenharmony_ci 11868c2ecf20Sopenharmony_cistatic int safexcel_skcipher_cra_init(struct crypto_tfm *tfm) 11878c2ecf20Sopenharmony_ci{ 11888c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 11898c2ecf20Sopenharmony_ci struct safexcel_alg_template *tmpl = 11908c2ecf20Sopenharmony_ci container_of(tfm->__crt_alg, struct safexcel_alg_template, 11918c2ecf20Sopenharmony_ci alg.skcipher.base); 11928c2ecf20Sopenharmony_ci 11938c2ecf20Sopenharmony_ci crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), 11948c2ecf20Sopenharmony_ci sizeof(struct safexcel_cipher_req)); 11958c2ecf20Sopenharmony_ci 11968c2ecf20Sopenharmony_ci ctx->base.priv = tmpl->priv; 11978c2ecf20Sopenharmony_ci 11988c2ecf20Sopenharmony_ci ctx->base.send = safexcel_skcipher_send; 11998c2ecf20Sopenharmony_ci ctx->base.handle_result = safexcel_skcipher_handle_result; 12008c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD; 12018c2ecf20Sopenharmony_ci ctx->ctrinit = 1; 12028c2ecf20Sopenharmony_ci return 0; 12038c2ecf20Sopenharmony_ci} 12048c2ecf20Sopenharmony_ci 12058c2ecf20Sopenharmony_cistatic int safexcel_cipher_cra_exit(struct crypto_tfm *tfm) 12068c2ecf20Sopenharmony_ci{ 12078c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 12088c2ecf20Sopenharmony_ci 12098c2ecf20Sopenharmony_ci memzero_explicit(ctx->key, sizeof(ctx->key)); 12108c2ecf20Sopenharmony_ci 12118c2ecf20Sopenharmony_ci /* context not allocated, skip invalidation */ 12128c2ecf20Sopenharmony_ci if (!ctx->base.ctxr) 12138c2ecf20Sopenharmony_ci return -ENOMEM; 12148c2ecf20Sopenharmony_ci 12158c2ecf20Sopenharmony_ci memzero_explicit(ctx->base.ctxr->data, sizeof(ctx->base.ctxr->data)); 12168c2ecf20Sopenharmony_ci return 0; 12178c2ecf20Sopenharmony_ci} 12188c2ecf20Sopenharmony_ci 12198c2ecf20Sopenharmony_cistatic void safexcel_skcipher_cra_exit(struct crypto_tfm *tfm) 12208c2ecf20Sopenharmony_ci{ 12218c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 12228c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 12238c2ecf20Sopenharmony_ci int ret; 12248c2ecf20Sopenharmony_ci 12258c2ecf20Sopenharmony_ci if (safexcel_cipher_cra_exit(tfm)) 12268c2ecf20Sopenharmony_ci return; 12278c2ecf20Sopenharmony_ci 12288c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE) { 12298c2ecf20Sopenharmony_ci ret = safexcel_skcipher_exit_inv(tfm); 12308c2ecf20Sopenharmony_ci if (ret) 12318c2ecf20Sopenharmony_ci dev_warn(priv->dev, "skcipher: invalidation error %d\n", 12328c2ecf20Sopenharmony_ci ret); 12338c2ecf20Sopenharmony_ci } else { 12348c2ecf20Sopenharmony_ci dma_pool_free(priv->context_pool, ctx->base.ctxr, 12358c2ecf20Sopenharmony_ci ctx->base.ctxr_dma); 12368c2ecf20Sopenharmony_ci } 12378c2ecf20Sopenharmony_ci} 12388c2ecf20Sopenharmony_ci 12398c2ecf20Sopenharmony_cistatic void safexcel_aead_cra_exit(struct crypto_tfm *tfm) 12408c2ecf20Sopenharmony_ci{ 12418c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 12428c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 12438c2ecf20Sopenharmony_ci int ret; 12448c2ecf20Sopenharmony_ci 12458c2ecf20Sopenharmony_ci if (safexcel_cipher_cra_exit(tfm)) 12468c2ecf20Sopenharmony_ci return; 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE) { 12498c2ecf20Sopenharmony_ci ret = safexcel_aead_exit_inv(tfm); 12508c2ecf20Sopenharmony_ci if (ret) 12518c2ecf20Sopenharmony_ci dev_warn(priv->dev, "aead: invalidation error %d\n", 12528c2ecf20Sopenharmony_ci ret); 12538c2ecf20Sopenharmony_ci } else { 12548c2ecf20Sopenharmony_ci dma_pool_free(priv->context_pool, ctx->base.ctxr, 12558c2ecf20Sopenharmony_ci ctx->base.ctxr_dma); 12568c2ecf20Sopenharmony_ci } 12578c2ecf20Sopenharmony_ci} 12588c2ecf20Sopenharmony_ci 12598c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_ecb_cra_init(struct crypto_tfm *tfm) 12608c2ecf20Sopenharmony_ci{ 12618c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 12628c2ecf20Sopenharmony_ci 12638c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 12648c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_AES; 12658c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 12668c2ecf20Sopenharmony_ci ctx->blocksz = 0; 12678c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 12688c2ecf20Sopenharmony_ci return 0; 12698c2ecf20Sopenharmony_ci} 12708c2ecf20Sopenharmony_ci 12718c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ecb_aes = { 12728c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 12738c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES, 12748c2ecf20Sopenharmony_ci .alg.skcipher = { 12758c2ecf20Sopenharmony_ci .setkey = safexcel_skcipher_aes_setkey, 12768c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 12778c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 12788c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 12798c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 12808c2ecf20Sopenharmony_ci .base = { 12818c2ecf20Sopenharmony_ci .cra_name = "ecb(aes)", 12828c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-ecb-aes", 12838c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 12848c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 12858c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 12868c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 12878c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 12888c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 12898c2ecf20Sopenharmony_ci .cra_alignmask = 0, 12908c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_aes_ecb_cra_init, 12918c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 12928c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 12938c2ecf20Sopenharmony_ci }, 12948c2ecf20Sopenharmony_ci }, 12958c2ecf20Sopenharmony_ci}; 12968c2ecf20Sopenharmony_ci 12978c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_cbc_cra_init(struct crypto_tfm *tfm) 12988c2ecf20Sopenharmony_ci{ 12998c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 13008c2ecf20Sopenharmony_ci 13018c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 13028c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_AES; 13038c2ecf20Sopenharmony_ci ctx->blocksz = AES_BLOCK_SIZE; 13048c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 13058c2ecf20Sopenharmony_ci return 0; 13068c2ecf20Sopenharmony_ci} 13078c2ecf20Sopenharmony_ci 13088c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cbc_aes = { 13098c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 13108c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES, 13118c2ecf20Sopenharmony_ci .alg.skcipher = { 13128c2ecf20Sopenharmony_ci .setkey = safexcel_skcipher_aes_setkey, 13138c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 13148c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 13158c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 13168c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 13178c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 13188c2ecf20Sopenharmony_ci .base = { 13198c2ecf20Sopenharmony_ci .cra_name = "cbc(aes)", 13208c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-cbc-aes", 13218c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 13228c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 13238c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 13248c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 13258c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 13268c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 13278c2ecf20Sopenharmony_ci .cra_alignmask = 0, 13288c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_aes_cbc_cra_init, 13298c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 13308c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 13318c2ecf20Sopenharmony_ci }, 13328c2ecf20Sopenharmony_ci }, 13338c2ecf20Sopenharmony_ci}; 13348c2ecf20Sopenharmony_ci 13358c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_cfb_cra_init(struct crypto_tfm *tfm) 13368c2ecf20Sopenharmony_ci{ 13378c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 13388c2ecf20Sopenharmony_ci 13398c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 13408c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_AES; 13418c2ecf20Sopenharmony_ci ctx->blocksz = AES_BLOCK_SIZE; 13428c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; 13438c2ecf20Sopenharmony_ci return 0; 13448c2ecf20Sopenharmony_ci} 13458c2ecf20Sopenharmony_ci 13468c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cfb_aes = { 13478c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 13488c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB, 13498c2ecf20Sopenharmony_ci .alg.skcipher = { 13508c2ecf20Sopenharmony_ci .setkey = safexcel_skcipher_aes_setkey, 13518c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 13528c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 13538c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 13548c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 13558c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 13568c2ecf20Sopenharmony_ci .base = { 13578c2ecf20Sopenharmony_ci .cra_name = "cfb(aes)", 13588c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-cfb-aes", 13598c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 13608c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 13618c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 13628c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 13638c2ecf20Sopenharmony_ci .cra_blocksize = 1, 13648c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 13658c2ecf20Sopenharmony_ci .cra_alignmask = 0, 13668c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_aes_cfb_cra_init, 13678c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 13688c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 13698c2ecf20Sopenharmony_ci }, 13708c2ecf20Sopenharmony_ci }, 13718c2ecf20Sopenharmony_ci}; 13728c2ecf20Sopenharmony_ci 13738c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_ofb_cra_init(struct crypto_tfm *tfm) 13748c2ecf20Sopenharmony_ci{ 13758c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 13768c2ecf20Sopenharmony_ci 13778c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 13788c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_AES; 13798c2ecf20Sopenharmony_ci ctx->blocksz = AES_BLOCK_SIZE; 13808c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; 13818c2ecf20Sopenharmony_ci return 0; 13828c2ecf20Sopenharmony_ci} 13838c2ecf20Sopenharmony_ci 13848c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ofb_aes = { 13858c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 13868c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB, 13878c2ecf20Sopenharmony_ci .alg.skcipher = { 13888c2ecf20Sopenharmony_ci .setkey = safexcel_skcipher_aes_setkey, 13898c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 13908c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 13918c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 13928c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 13938c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 13948c2ecf20Sopenharmony_ci .base = { 13958c2ecf20Sopenharmony_ci .cra_name = "ofb(aes)", 13968c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-ofb-aes", 13978c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 13988c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 13998c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 14008c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 14018c2ecf20Sopenharmony_ci .cra_blocksize = 1, 14028c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 14038c2ecf20Sopenharmony_ci .cra_alignmask = 0, 14048c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_aes_ofb_cra_init, 14058c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 14068c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 14078c2ecf20Sopenharmony_ci }, 14088c2ecf20Sopenharmony_ci }, 14098c2ecf20Sopenharmony_ci}; 14108c2ecf20Sopenharmony_ci 14118c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm, 14128c2ecf20Sopenharmony_ci const u8 *key, unsigned int len) 14138c2ecf20Sopenharmony_ci{ 14148c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 14158c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 14168c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 14178c2ecf20Sopenharmony_ci struct crypto_aes_ctx aes; 14188c2ecf20Sopenharmony_ci int ret, i; 14198c2ecf20Sopenharmony_ci unsigned int keylen; 14208c2ecf20Sopenharmony_ci 14218c2ecf20Sopenharmony_ci /* last 4 bytes of key are the nonce! */ 14228c2ecf20Sopenharmony_ci ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 14238c2ecf20Sopenharmony_ci /* exclude the nonce here */ 14248c2ecf20Sopenharmony_ci keylen = len - CTR_RFC3686_NONCE_SIZE; 14258c2ecf20Sopenharmony_ci ret = aes_expandkey(&aes, key, keylen); 14268c2ecf20Sopenharmony_ci if (ret) 14278c2ecf20Sopenharmony_ci return ret; 14288c2ecf20Sopenharmony_ci 14298c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 14308c2ecf20Sopenharmony_ci for (i = 0; i < keylen / sizeof(u32); i++) { 14318c2ecf20Sopenharmony_ci if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 14328c2ecf20Sopenharmony_ci ctx->base.needs_inv = true; 14338c2ecf20Sopenharmony_ci break; 14348c2ecf20Sopenharmony_ci } 14358c2ecf20Sopenharmony_ci } 14368c2ecf20Sopenharmony_ci } 14378c2ecf20Sopenharmony_ci 14388c2ecf20Sopenharmony_ci for (i = 0; i < keylen / sizeof(u32); i++) 14398c2ecf20Sopenharmony_ci ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 14408c2ecf20Sopenharmony_ci 14418c2ecf20Sopenharmony_ci ctx->key_len = keylen; 14428c2ecf20Sopenharmony_ci 14438c2ecf20Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 14448c2ecf20Sopenharmony_ci return 0; 14458c2ecf20Sopenharmony_ci} 14468c2ecf20Sopenharmony_ci 14478c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_ctr_cra_init(struct crypto_tfm *tfm) 14488c2ecf20Sopenharmony_ci{ 14498c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 14508c2ecf20Sopenharmony_ci 14518c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 14528c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_AES; 14538c2ecf20Sopenharmony_ci ctx->blocksz = AES_BLOCK_SIZE; 14548c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 14558c2ecf20Sopenharmony_ci return 0; 14568c2ecf20Sopenharmony_ci} 14578c2ecf20Sopenharmony_ci 14588c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ctr_aes = { 14598c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 14608c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES, 14618c2ecf20Sopenharmony_ci .alg.skcipher = { 14628c2ecf20Sopenharmony_ci .setkey = safexcel_skcipher_aesctr_setkey, 14638c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 14648c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 14658c2ecf20Sopenharmony_ci /* Add nonce size */ 14668c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 14678c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 14688c2ecf20Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 14698c2ecf20Sopenharmony_ci .base = { 14708c2ecf20Sopenharmony_ci .cra_name = "rfc3686(ctr(aes))", 14718c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-ctr-aes", 14728c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 14738c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 14748c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 14758c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 14768c2ecf20Sopenharmony_ci .cra_blocksize = 1, 14778c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 14788c2ecf20Sopenharmony_ci .cra_alignmask = 0, 14798c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_aes_ctr_cra_init, 14808c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 14818c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 14828c2ecf20Sopenharmony_ci }, 14838c2ecf20Sopenharmony_ci }, 14848c2ecf20Sopenharmony_ci}; 14858c2ecf20Sopenharmony_ci 14868c2ecf20Sopenharmony_cistatic int safexcel_des_setkey(struct crypto_skcipher *ctfm, const u8 *key, 14878c2ecf20Sopenharmony_ci unsigned int len) 14888c2ecf20Sopenharmony_ci{ 14898c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 14908c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 14918c2ecf20Sopenharmony_ci int ret; 14928c2ecf20Sopenharmony_ci 14938c2ecf20Sopenharmony_ci ret = verify_skcipher_des_key(ctfm, key); 14948c2ecf20Sopenharmony_ci if (ret) 14958c2ecf20Sopenharmony_ci return ret; 14968c2ecf20Sopenharmony_ci 14978c2ecf20Sopenharmony_ci /* if context exits and key changed, need to invalidate it */ 14988c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 14998c2ecf20Sopenharmony_ci if (memcmp(ctx->key, key, len)) 15008c2ecf20Sopenharmony_ci ctx->base.needs_inv = true; 15018c2ecf20Sopenharmony_ci 15028c2ecf20Sopenharmony_ci memcpy(ctx->key, key, len); 15038c2ecf20Sopenharmony_ci ctx->key_len = len; 15048c2ecf20Sopenharmony_ci 15058c2ecf20Sopenharmony_ci return 0; 15068c2ecf20Sopenharmony_ci} 15078c2ecf20Sopenharmony_ci 15088c2ecf20Sopenharmony_cistatic int safexcel_skcipher_des_cbc_cra_init(struct crypto_tfm *tfm) 15098c2ecf20Sopenharmony_ci{ 15108c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 15118c2ecf20Sopenharmony_ci 15128c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 15138c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_DES; 15148c2ecf20Sopenharmony_ci ctx->blocksz = DES_BLOCK_SIZE; 15158c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 15168c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 15178c2ecf20Sopenharmony_ci return 0; 15188c2ecf20Sopenharmony_ci} 15198c2ecf20Sopenharmony_ci 15208c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cbc_des = { 15218c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 15228c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES, 15238c2ecf20Sopenharmony_ci .alg.skcipher = { 15248c2ecf20Sopenharmony_ci .setkey = safexcel_des_setkey, 15258c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 15268c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 15278c2ecf20Sopenharmony_ci .min_keysize = DES_KEY_SIZE, 15288c2ecf20Sopenharmony_ci .max_keysize = DES_KEY_SIZE, 15298c2ecf20Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 15308c2ecf20Sopenharmony_ci .base = { 15318c2ecf20Sopenharmony_ci .cra_name = "cbc(des)", 15328c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-cbc-des", 15338c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 15348c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 15358c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 15368c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 15378c2ecf20Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 15388c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 15398c2ecf20Sopenharmony_ci .cra_alignmask = 0, 15408c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_des_cbc_cra_init, 15418c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 15428c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 15438c2ecf20Sopenharmony_ci }, 15448c2ecf20Sopenharmony_ci }, 15458c2ecf20Sopenharmony_ci}; 15468c2ecf20Sopenharmony_ci 15478c2ecf20Sopenharmony_cistatic int safexcel_skcipher_des_ecb_cra_init(struct crypto_tfm *tfm) 15488c2ecf20Sopenharmony_ci{ 15498c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 15508c2ecf20Sopenharmony_ci 15518c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 15528c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_DES; 15538c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 15548c2ecf20Sopenharmony_ci ctx->blocksz = 0; 15558c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 15568c2ecf20Sopenharmony_ci return 0; 15578c2ecf20Sopenharmony_ci} 15588c2ecf20Sopenharmony_ci 15598c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ecb_des = { 15608c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 15618c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES, 15628c2ecf20Sopenharmony_ci .alg.skcipher = { 15638c2ecf20Sopenharmony_ci .setkey = safexcel_des_setkey, 15648c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 15658c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 15668c2ecf20Sopenharmony_ci .min_keysize = DES_KEY_SIZE, 15678c2ecf20Sopenharmony_ci .max_keysize = DES_KEY_SIZE, 15688c2ecf20Sopenharmony_ci .base = { 15698c2ecf20Sopenharmony_ci .cra_name = "ecb(des)", 15708c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-ecb-des", 15718c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 15728c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 15738c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 15748c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 15758c2ecf20Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 15768c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 15778c2ecf20Sopenharmony_ci .cra_alignmask = 0, 15788c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_des_ecb_cra_init, 15798c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 15808c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 15818c2ecf20Sopenharmony_ci }, 15828c2ecf20Sopenharmony_ci }, 15838c2ecf20Sopenharmony_ci}; 15848c2ecf20Sopenharmony_ci 15858c2ecf20Sopenharmony_cistatic int safexcel_des3_ede_setkey(struct crypto_skcipher *ctfm, 15868c2ecf20Sopenharmony_ci const u8 *key, unsigned int len) 15878c2ecf20Sopenharmony_ci{ 15888c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 15898c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 15908c2ecf20Sopenharmony_ci int err; 15918c2ecf20Sopenharmony_ci 15928c2ecf20Sopenharmony_ci err = verify_skcipher_des3_key(ctfm, key); 15938c2ecf20Sopenharmony_ci if (err) 15948c2ecf20Sopenharmony_ci return err; 15958c2ecf20Sopenharmony_ci 15968c2ecf20Sopenharmony_ci /* if context exits and key changed, need to invalidate it */ 15978c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 15988c2ecf20Sopenharmony_ci if (memcmp(ctx->key, key, len)) 15998c2ecf20Sopenharmony_ci ctx->base.needs_inv = true; 16008c2ecf20Sopenharmony_ci 16018c2ecf20Sopenharmony_ci memcpy(ctx->key, key, len); 16028c2ecf20Sopenharmony_ci ctx->key_len = len; 16038c2ecf20Sopenharmony_ci 16048c2ecf20Sopenharmony_ci return 0; 16058c2ecf20Sopenharmony_ci} 16068c2ecf20Sopenharmony_ci 16078c2ecf20Sopenharmony_cistatic int safexcel_skcipher_des3_cbc_cra_init(struct crypto_tfm *tfm) 16088c2ecf20Sopenharmony_ci{ 16098c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 16108c2ecf20Sopenharmony_ci 16118c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 16128c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; 16138c2ecf20Sopenharmony_ci ctx->blocksz = DES3_EDE_BLOCK_SIZE; 16148c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 16158c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 16168c2ecf20Sopenharmony_ci return 0; 16178c2ecf20Sopenharmony_ci} 16188c2ecf20Sopenharmony_ci 16198c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cbc_des3_ede = { 16208c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 16218c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES, 16228c2ecf20Sopenharmony_ci .alg.skcipher = { 16238c2ecf20Sopenharmony_ci .setkey = safexcel_des3_ede_setkey, 16248c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 16258c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 16268c2ecf20Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 16278c2ecf20Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 16288c2ecf20Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 16298c2ecf20Sopenharmony_ci .base = { 16308c2ecf20Sopenharmony_ci .cra_name = "cbc(des3_ede)", 16318c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-cbc-des3_ede", 16328c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 16338c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 16348c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 16358c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 16368c2ecf20Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 16378c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 16388c2ecf20Sopenharmony_ci .cra_alignmask = 0, 16398c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_des3_cbc_cra_init, 16408c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 16418c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 16428c2ecf20Sopenharmony_ci }, 16438c2ecf20Sopenharmony_ci }, 16448c2ecf20Sopenharmony_ci}; 16458c2ecf20Sopenharmony_ci 16468c2ecf20Sopenharmony_cistatic int safexcel_skcipher_des3_ecb_cra_init(struct crypto_tfm *tfm) 16478c2ecf20Sopenharmony_ci{ 16488c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 16498c2ecf20Sopenharmony_ci 16508c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 16518c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; 16528c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 16538c2ecf20Sopenharmony_ci ctx->blocksz = 0; 16548c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 16558c2ecf20Sopenharmony_ci return 0; 16568c2ecf20Sopenharmony_ci} 16578c2ecf20Sopenharmony_ci 16588c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ecb_des3_ede = { 16598c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 16608c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES, 16618c2ecf20Sopenharmony_ci .alg.skcipher = { 16628c2ecf20Sopenharmony_ci .setkey = safexcel_des3_ede_setkey, 16638c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 16648c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 16658c2ecf20Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 16668c2ecf20Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 16678c2ecf20Sopenharmony_ci .base = { 16688c2ecf20Sopenharmony_ci .cra_name = "ecb(des3_ede)", 16698c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-ecb-des3_ede", 16708c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 16718c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 16728c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 16738c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 16748c2ecf20Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 16758c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 16768c2ecf20Sopenharmony_ci .cra_alignmask = 0, 16778c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_des3_ecb_cra_init, 16788c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 16798c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 16808c2ecf20Sopenharmony_ci }, 16818c2ecf20Sopenharmony_ci }, 16828c2ecf20Sopenharmony_ci}; 16838c2ecf20Sopenharmony_ci 16848c2ecf20Sopenharmony_cistatic int safexcel_aead_encrypt(struct aead_request *req) 16858c2ecf20Sopenharmony_ci{ 16868c2ecf20Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 16878c2ecf20Sopenharmony_ci 16888c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 16898c2ecf20Sopenharmony_ci} 16908c2ecf20Sopenharmony_ci 16918c2ecf20Sopenharmony_cistatic int safexcel_aead_decrypt(struct aead_request *req) 16928c2ecf20Sopenharmony_ci{ 16938c2ecf20Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 16948c2ecf20Sopenharmony_ci 16958c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 16968c2ecf20Sopenharmony_ci} 16978c2ecf20Sopenharmony_ci 16988c2ecf20Sopenharmony_cistatic int safexcel_aead_cra_init(struct crypto_tfm *tfm) 16998c2ecf20Sopenharmony_ci{ 17008c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 17018c2ecf20Sopenharmony_ci struct safexcel_alg_template *tmpl = 17028c2ecf20Sopenharmony_ci container_of(tfm->__crt_alg, struct safexcel_alg_template, 17038c2ecf20Sopenharmony_ci alg.aead.base); 17048c2ecf20Sopenharmony_ci 17058c2ecf20Sopenharmony_ci crypto_aead_set_reqsize(__crypto_aead_cast(tfm), 17068c2ecf20Sopenharmony_ci sizeof(struct safexcel_cipher_req)); 17078c2ecf20Sopenharmony_ci 17088c2ecf20Sopenharmony_ci ctx->base.priv = tmpl->priv; 17098c2ecf20Sopenharmony_ci 17108c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_AES; /* default */ 17118c2ecf20Sopenharmony_ci ctx->blocksz = AES_BLOCK_SIZE; 17128c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD; 17138c2ecf20Sopenharmony_ci ctx->ctrinit = 1; 17148c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; /* default */ 17158c2ecf20Sopenharmony_ci ctx->aead = true; 17168c2ecf20Sopenharmony_ci ctx->base.send = safexcel_aead_send; 17178c2ecf20Sopenharmony_ci ctx->base.handle_result = safexcel_aead_handle_result; 17188c2ecf20Sopenharmony_ci return 0; 17198c2ecf20Sopenharmony_ci} 17208c2ecf20Sopenharmony_ci 17218c2ecf20Sopenharmony_cistatic int safexcel_aead_sha1_cra_init(struct crypto_tfm *tfm) 17228c2ecf20Sopenharmony_ci{ 17238c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 17248c2ecf20Sopenharmony_ci 17258c2ecf20Sopenharmony_ci safexcel_aead_cra_init(tfm); 17268c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; 17278c2ecf20Sopenharmony_ci ctx->state_sz = SHA1_DIGEST_SIZE; 17288c2ecf20Sopenharmony_ci return 0; 17298c2ecf20Sopenharmony_ci} 17308c2ecf20Sopenharmony_ci 17318c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_aes = { 17328c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 17338c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1, 17348c2ecf20Sopenharmony_ci .alg.aead = { 17358c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 17368c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 17378c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 17388c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 17398c2ecf20Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 17408c2ecf20Sopenharmony_ci .base = { 17418c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha1),cbc(aes))", 17428c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-aes", 17438c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 17448c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 17458c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 17468c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 17478c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 17488c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 17498c2ecf20Sopenharmony_ci .cra_alignmask = 0, 17508c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha1_cra_init, 17518c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 17528c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 17538c2ecf20Sopenharmony_ci }, 17548c2ecf20Sopenharmony_ci }, 17558c2ecf20Sopenharmony_ci}; 17568c2ecf20Sopenharmony_ci 17578c2ecf20Sopenharmony_cistatic int safexcel_aead_sha256_cra_init(struct crypto_tfm *tfm) 17588c2ecf20Sopenharmony_ci{ 17598c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 17608c2ecf20Sopenharmony_ci 17618c2ecf20Sopenharmony_ci safexcel_aead_cra_init(tfm); 17628c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256; 17638c2ecf20Sopenharmony_ci ctx->state_sz = SHA256_DIGEST_SIZE; 17648c2ecf20Sopenharmony_ci return 0; 17658c2ecf20Sopenharmony_ci} 17668c2ecf20Sopenharmony_ci 17678c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_aes = { 17688c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 17698c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 17708c2ecf20Sopenharmony_ci .alg.aead = { 17718c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 17728c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 17738c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 17748c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 17758c2ecf20Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 17768c2ecf20Sopenharmony_ci .base = { 17778c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha256),cbc(aes))", 17788c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-aes", 17798c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 17808c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 17818c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 17828c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 17838c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 17848c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 17858c2ecf20Sopenharmony_ci .cra_alignmask = 0, 17868c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha256_cra_init, 17878c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 17888c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 17898c2ecf20Sopenharmony_ci }, 17908c2ecf20Sopenharmony_ci }, 17918c2ecf20Sopenharmony_ci}; 17928c2ecf20Sopenharmony_ci 17938c2ecf20Sopenharmony_cistatic int safexcel_aead_sha224_cra_init(struct crypto_tfm *tfm) 17948c2ecf20Sopenharmony_ci{ 17958c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 17968c2ecf20Sopenharmony_ci 17978c2ecf20Sopenharmony_ci safexcel_aead_cra_init(tfm); 17988c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224; 17998c2ecf20Sopenharmony_ci ctx->state_sz = SHA256_DIGEST_SIZE; 18008c2ecf20Sopenharmony_ci return 0; 18018c2ecf20Sopenharmony_ci} 18028c2ecf20Sopenharmony_ci 18038c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_aes = { 18048c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 18058c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 18068c2ecf20Sopenharmony_ci .alg.aead = { 18078c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 18088c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 18098c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 18108c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 18118c2ecf20Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 18128c2ecf20Sopenharmony_ci .base = { 18138c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha224),cbc(aes))", 18148c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-aes", 18158c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 18168c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 18178c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 18188c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 18198c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 18208c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 18218c2ecf20Sopenharmony_ci .cra_alignmask = 0, 18228c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha224_cra_init, 18238c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 18248c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 18258c2ecf20Sopenharmony_ci }, 18268c2ecf20Sopenharmony_ci }, 18278c2ecf20Sopenharmony_ci}; 18288c2ecf20Sopenharmony_ci 18298c2ecf20Sopenharmony_cistatic int safexcel_aead_sha512_cra_init(struct crypto_tfm *tfm) 18308c2ecf20Sopenharmony_ci{ 18318c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 18328c2ecf20Sopenharmony_ci 18338c2ecf20Sopenharmony_ci safexcel_aead_cra_init(tfm); 18348c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512; 18358c2ecf20Sopenharmony_ci ctx->state_sz = SHA512_DIGEST_SIZE; 18368c2ecf20Sopenharmony_ci return 0; 18378c2ecf20Sopenharmony_ci} 18388c2ecf20Sopenharmony_ci 18398c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_aes = { 18408c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 18418c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 18428c2ecf20Sopenharmony_ci .alg.aead = { 18438c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 18448c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 18458c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 18468c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 18478c2ecf20Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 18488c2ecf20Sopenharmony_ci .base = { 18498c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha512),cbc(aes))", 18508c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-aes", 18518c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 18528c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 18538c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 18548c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 18558c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 18568c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 18578c2ecf20Sopenharmony_ci .cra_alignmask = 0, 18588c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha512_cra_init, 18598c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 18608c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 18618c2ecf20Sopenharmony_ci }, 18628c2ecf20Sopenharmony_ci }, 18638c2ecf20Sopenharmony_ci}; 18648c2ecf20Sopenharmony_ci 18658c2ecf20Sopenharmony_cistatic int safexcel_aead_sha384_cra_init(struct crypto_tfm *tfm) 18668c2ecf20Sopenharmony_ci{ 18678c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 18688c2ecf20Sopenharmony_ci 18698c2ecf20Sopenharmony_ci safexcel_aead_cra_init(tfm); 18708c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384; 18718c2ecf20Sopenharmony_ci ctx->state_sz = SHA512_DIGEST_SIZE; 18728c2ecf20Sopenharmony_ci return 0; 18738c2ecf20Sopenharmony_ci} 18748c2ecf20Sopenharmony_ci 18758c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_aes = { 18768c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 18778c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 18788c2ecf20Sopenharmony_ci .alg.aead = { 18798c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 18808c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 18818c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 18828c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 18838c2ecf20Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 18848c2ecf20Sopenharmony_ci .base = { 18858c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha384),cbc(aes))", 18868c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-aes", 18878c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 18888c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 18898c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 18908c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 18918c2ecf20Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 18928c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 18938c2ecf20Sopenharmony_ci .cra_alignmask = 0, 18948c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha384_cra_init, 18958c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 18968c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 18978c2ecf20Sopenharmony_ci }, 18988c2ecf20Sopenharmony_ci }, 18998c2ecf20Sopenharmony_ci}; 19008c2ecf20Sopenharmony_ci 19018c2ecf20Sopenharmony_cistatic int safexcel_aead_sha1_des3_cra_init(struct crypto_tfm *tfm) 19028c2ecf20Sopenharmony_ci{ 19038c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 19048c2ecf20Sopenharmony_ci 19058c2ecf20Sopenharmony_ci safexcel_aead_sha1_cra_init(tfm); 19068c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; /* override default */ 19078c2ecf20Sopenharmony_ci ctx->blocksz = DES3_EDE_BLOCK_SIZE; 19088c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 19098c2ecf20Sopenharmony_ci return 0; 19108c2ecf20Sopenharmony_ci} 19118c2ecf20Sopenharmony_ci 19128c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des3_ede = { 19138c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 19148c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, 19158c2ecf20Sopenharmony_ci .alg.aead = { 19168c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 19178c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 19188c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 19198c2ecf20Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 19208c2ecf20Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 19218c2ecf20Sopenharmony_ci .base = { 19228c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", 19238c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des3_ede", 19248c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 19258c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 19268c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 19278c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 19288c2ecf20Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 19298c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 19308c2ecf20Sopenharmony_ci .cra_alignmask = 0, 19318c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha1_des3_cra_init, 19328c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 19338c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 19348c2ecf20Sopenharmony_ci }, 19358c2ecf20Sopenharmony_ci }, 19368c2ecf20Sopenharmony_ci}; 19378c2ecf20Sopenharmony_ci 19388c2ecf20Sopenharmony_cistatic int safexcel_aead_sha256_des3_cra_init(struct crypto_tfm *tfm) 19398c2ecf20Sopenharmony_ci{ 19408c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 19418c2ecf20Sopenharmony_ci 19428c2ecf20Sopenharmony_ci safexcel_aead_sha256_cra_init(tfm); 19438c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; /* override default */ 19448c2ecf20Sopenharmony_ci ctx->blocksz = DES3_EDE_BLOCK_SIZE; 19458c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 19468c2ecf20Sopenharmony_ci return 0; 19478c2ecf20Sopenharmony_ci} 19488c2ecf20Sopenharmony_ci 19498c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede = { 19508c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 19518c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 19528c2ecf20Sopenharmony_ci .alg.aead = { 19538c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 19548c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 19558c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 19568c2ecf20Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 19578c2ecf20Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 19588c2ecf20Sopenharmony_ci .base = { 19598c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", 19608c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des3_ede", 19618c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 19628c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 19638c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 19648c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 19658c2ecf20Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 19668c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 19678c2ecf20Sopenharmony_ci .cra_alignmask = 0, 19688c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha256_des3_cra_init, 19698c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 19708c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 19718c2ecf20Sopenharmony_ci }, 19728c2ecf20Sopenharmony_ci }, 19738c2ecf20Sopenharmony_ci}; 19748c2ecf20Sopenharmony_ci 19758c2ecf20Sopenharmony_cistatic int safexcel_aead_sha224_des3_cra_init(struct crypto_tfm *tfm) 19768c2ecf20Sopenharmony_ci{ 19778c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 19788c2ecf20Sopenharmony_ci 19798c2ecf20Sopenharmony_ci safexcel_aead_sha224_cra_init(tfm); 19808c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; /* override default */ 19818c2ecf20Sopenharmony_ci ctx->blocksz = DES3_EDE_BLOCK_SIZE; 19828c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 19838c2ecf20Sopenharmony_ci return 0; 19848c2ecf20Sopenharmony_ci} 19858c2ecf20Sopenharmony_ci 19868c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede = { 19878c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 19888c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 19898c2ecf20Sopenharmony_ci .alg.aead = { 19908c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 19918c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 19928c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 19938c2ecf20Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 19948c2ecf20Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 19958c2ecf20Sopenharmony_ci .base = { 19968c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha224),cbc(des3_ede))", 19978c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des3_ede", 19988c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 19998c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 20008c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 20018c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 20028c2ecf20Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 20038c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 20048c2ecf20Sopenharmony_ci .cra_alignmask = 0, 20058c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha224_des3_cra_init, 20068c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 20078c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 20088c2ecf20Sopenharmony_ci }, 20098c2ecf20Sopenharmony_ci }, 20108c2ecf20Sopenharmony_ci}; 20118c2ecf20Sopenharmony_ci 20128c2ecf20Sopenharmony_cistatic int safexcel_aead_sha512_des3_cra_init(struct crypto_tfm *tfm) 20138c2ecf20Sopenharmony_ci{ 20148c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 20158c2ecf20Sopenharmony_ci 20168c2ecf20Sopenharmony_ci safexcel_aead_sha512_cra_init(tfm); 20178c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; /* override default */ 20188c2ecf20Sopenharmony_ci ctx->blocksz = DES3_EDE_BLOCK_SIZE; 20198c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 20208c2ecf20Sopenharmony_ci return 0; 20218c2ecf20Sopenharmony_ci} 20228c2ecf20Sopenharmony_ci 20238c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede = { 20248c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 20258c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 20268c2ecf20Sopenharmony_ci .alg.aead = { 20278c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 20288c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 20298c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 20308c2ecf20Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 20318c2ecf20Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 20328c2ecf20Sopenharmony_ci .base = { 20338c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha512),cbc(des3_ede))", 20348c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des3_ede", 20358c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 20368c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 20378c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 20388c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 20398c2ecf20Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 20408c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 20418c2ecf20Sopenharmony_ci .cra_alignmask = 0, 20428c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha512_des3_cra_init, 20438c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 20448c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 20458c2ecf20Sopenharmony_ci }, 20468c2ecf20Sopenharmony_ci }, 20478c2ecf20Sopenharmony_ci}; 20488c2ecf20Sopenharmony_ci 20498c2ecf20Sopenharmony_cistatic int safexcel_aead_sha384_des3_cra_init(struct crypto_tfm *tfm) 20508c2ecf20Sopenharmony_ci{ 20518c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 20528c2ecf20Sopenharmony_ci 20538c2ecf20Sopenharmony_ci safexcel_aead_sha384_cra_init(tfm); 20548c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_3DES; /* override default */ 20558c2ecf20Sopenharmony_ci ctx->blocksz = DES3_EDE_BLOCK_SIZE; 20568c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 20578c2ecf20Sopenharmony_ci return 0; 20588c2ecf20Sopenharmony_ci} 20598c2ecf20Sopenharmony_ci 20608c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede = { 20618c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 20628c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 20638c2ecf20Sopenharmony_ci .alg.aead = { 20648c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 20658c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 20668c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 20678c2ecf20Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 20688c2ecf20Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 20698c2ecf20Sopenharmony_ci .base = { 20708c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha384),cbc(des3_ede))", 20718c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des3_ede", 20728c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 20738c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 20748c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 20758c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 20768c2ecf20Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 20778c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 20788c2ecf20Sopenharmony_ci .cra_alignmask = 0, 20798c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha384_des3_cra_init, 20808c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 20818c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 20828c2ecf20Sopenharmony_ci }, 20838c2ecf20Sopenharmony_ci }, 20848c2ecf20Sopenharmony_ci}; 20858c2ecf20Sopenharmony_ci 20868c2ecf20Sopenharmony_cistatic int safexcel_aead_sha1_des_cra_init(struct crypto_tfm *tfm) 20878c2ecf20Sopenharmony_ci{ 20888c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 20898c2ecf20Sopenharmony_ci 20908c2ecf20Sopenharmony_ci safexcel_aead_sha1_cra_init(tfm); 20918c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_DES; /* override default */ 20928c2ecf20Sopenharmony_ci ctx->blocksz = DES_BLOCK_SIZE; 20938c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 20948c2ecf20Sopenharmony_ci return 0; 20958c2ecf20Sopenharmony_ci} 20968c2ecf20Sopenharmony_ci 20978c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des = { 20988c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 20998c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, 21008c2ecf20Sopenharmony_ci .alg.aead = { 21018c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 21028c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 21038c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 21048c2ecf20Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 21058c2ecf20Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 21068c2ecf20Sopenharmony_ci .base = { 21078c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha1),cbc(des))", 21088c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des", 21098c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 21108c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 21118c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 21128c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 21138c2ecf20Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 21148c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 21158c2ecf20Sopenharmony_ci .cra_alignmask = 0, 21168c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha1_des_cra_init, 21178c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 21188c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 21198c2ecf20Sopenharmony_ci }, 21208c2ecf20Sopenharmony_ci }, 21218c2ecf20Sopenharmony_ci}; 21228c2ecf20Sopenharmony_ci 21238c2ecf20Sopenharmony_cistatic int safexcel_aead_sha256_des_cra_init(struct crypto_tfm *tfm) 21248c2ecf20Sopenharmony_ci{ 21258c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 21268c2ecf20Sopenharmony_ci 21278c2ecf20Sopenharmony_ci safexcel_aead_sha256_cra_init(tfm); 21288c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_DES; /* override default */ 21298c2ecf20Sopenharmony_ci ctx->blocksz = DES_BLOCK_SIZE; 21308c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 21318c2ecf20Sopenharmony_ci return 0; 21328c2ecf20Sopenharmony_ci} 21338c2ecf20Sopenharmony_ci 21348c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des = { 21358c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 21368c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 21378c2ecf20Sopenharmony_ci .alg.aead = { 21388c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 21398c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 21408c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 21418c2ecf20Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 21428c2ecf20Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 21438c2ecf20Sopenharmony_ci .base = { 21448c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha256),cbc(des))", 21458c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des", 21468c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 21478c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 21488c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 21498c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 21508c2ecf20Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 21518c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 21528c2ecf20Sopenharmony_ci .cra_alignmask = 0, 21538c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha256_des_cra_init, 21548c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 21558c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 21568c2ecf20Sopenharmony_ci }, 21578c2ecf20Sopenharmony_ci }, 21588c2ecf20Sopenharmony_ci}; 21598c2ecf20Sopenharmony_ci 21608c2ecf20Sopenharmony_cistatic int safexcel_aead_sha224_des_cra_init(struct crypto_tfm *tfm) 21618c2ecf20Sopenharmony_ci{ 21628c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 21638c2ecf20Sopenharmony_ci 21648c2ecf20Sopenharmony_ci safexcel_aead_sha224_cra_init(tfm); 21658c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_DES; /* override default */ 21668c2ecf20Sopenharmony_ci ctx->blocksz = DES_BLOCK_SIZE; 21678c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 21688c2ecf20Sopenharmony_ci return 0; 21698c2ecf20Sopenharmony_ci} 21708c2ecf20Sopenharmony_ci 21718c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des = { 21728c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 21738c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 21748c2ecf20Sopenharmony_ci .alg.aead = { 21758c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 21768c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 21778c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 21788c2ecf20Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 21798c2ecf20Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 21808c2ecf20Sopenharmony_ci .base = { 21818c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha224),cbc(des))", 21828c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des", 21838c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 21848c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 21858c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 21868c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 21878c2ecf20Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 21888c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 21898c2ecf20Sopenharmony_ci .cra_alignmask = 0, 21908c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha224_des_cra_init, 21918c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 21928c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 21938c2ecf20Sopenharmony_ci }, 21948c2ecf20Sopenharmony_ci }, 21958c2ecf20Sopenharmony_ci}; 21968c2ecf20Sopenharmony_ci 21978c2ecf20Sopenharmony_cistatic int safexcel_aead_sha512_des_cra_init(struct crypto_tfm *tfm) 21988c2ecf20Sopenharmony_ci{ 21998c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 22008c2ecf20Sopenharmony_ci 22018c2ecf20Sopenharmony_ci safexcel_aead_sha512_cra_init(tfm); 22028c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_DES; /* override default */ 22038c2ecf20Sopenharmony_ci ctx->blocksz = DES_BLOCK_SIZE; 22048c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 22058c2ecf20Sopenharmony_ci return 0; 22068c2ecf20Sopenharmony_ci} 22078c2ecf20Sopenharmony_ci 22088c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des = { 22098c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 22108c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 22118c2ecf20Sopenharmony_ci .alg.aead = { 22128c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 22138c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 22148c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 22158c2ecf20Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 22168c2ecf20Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 22178c2ecf20Sopenharmony_ci .base = { 22188c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha512),cbc(des))", 22198c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des", 22208c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 22218c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 22228c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 22238c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 22248c2ecf20Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 22258c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 22268c2ecf20Sopenharmony_ci .cra_alignmask = 0, 22278c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha512_des_cra_init, 22288c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 22298c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 22308c2ecf20Sopenharmony_ci }, 22318c2ecf20Sopenharmony_ci }, 22328c2ecf20Sopenharmony_ci}; 22338c2ecf20Sopenharmony_ci 22348c2ecf20Sopenharmony_cistatic int safexcel_aead_sha384_des_cra_init(struct crypto_tfm *tfm) 22358c2ecf20Sopenharmony_ci{ 22368c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 22378c2ecf20Sopenharmony_ci 22388c2ecf20Sopenharmony_ci safexcel_aead_sha384_cra_init(tfm); 22398c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_DES; /* override default */ 22408c2ecf20Sopenharmony_ci ctx->blocksz = DES_BLOCK_SIZE; 22418c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 22428c2ecf20Sopenharmony_ci return 0; 22438c2ecf20Sopenharmony_ci} 22448c2ecf20Sopenharmony_ci 22458c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des = { 22468c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 22478c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 22488c2ecf20Sopenharmony_ci .alg.aead = { 22498c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 22508c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 22518c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 22528c2ecf20Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 22538c2ecf20Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 22548c2ecf20Sopenharmony_ci .base = { 22558c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha384),cbc(des))", 22568c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des", 22578c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 22588c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 22598c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 22608c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 22618c2ecf20Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 22628c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 22638c2ecf20Sopenharmony_ci .cra_alignmask = 0, 22648c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha384_des_cra_init, 22658c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 22668c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 22678c2ecf20Sopenharmony_ci }, 22688c2ecf20Sopenharmony_ci }, 22698c2ecf20Sopenharmony_ci}; 22708c2ecf20Sopenharmony_ci 22718c2ecf20Sopenharmony_cistatic int safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm *tfm) 22728c2ecf20Sopenharmony_ci{ 22738c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 22748c2ecf20Sopenharmony_ci 22758c2ecf20Sopenharmony_ci safexcel_aead_sha1_cra_init(tfm); 22768c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 22778c2ecf20Sopenharmony_ci return 0; 22788c2ecf20Sopenharmony_ci} 22798c2ecf20Sopenharmony_ci 22808c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_aes = { 22818c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 22828c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1, 22838c2ecf20Sopenharmony_ci .alg.aead = { 22848c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 22858c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 22868c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 22878c2ecf20Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 22888c2ecf20Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 22898c2ecf20Sopenharmony_ci .base = { 22908c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))", 22918c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-aes", 22928c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 22938c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 22948c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 22958c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 22968c2ecf20Sopenharmony_ci .cra_blocksize = 1, 22978c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 22988c2ecf20Sopenharmony_ci .cra_alignmask = 0, 22998c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha1_ctr_cra_init, 23008c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 23018c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 23028c2ecf20Sopenharmony_ci }, 23038c2ecf20Sopenharmony_ci }, 23048c2ecf20Sopenharmony_ci}; 23058c2ecf20Sopenharmony_ci 23068c2ecf20Sopenharmony_cistatic int safexcel_aead_sha256_ctr_cra_init(struct crypto_tfm *tfm) 23078c2ecf20Sopenharmony_ci{ 23088c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 23098c2ecf20Sopenharmony_ci 23108c2ecf20Sopenharmony_ci safexcel_aead_sha256_cra_init(tfm); 23118c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 23128c2ecf20Sopenharmony_ci return 0; 23138c2ecf20Sopenharmony_ci} 23148c2ecf20Sopenharmony_ci 23158c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes = { 23168c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 23178c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 23188c2ecf20Sopenharmony_ci .alg.aead = { 23198c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 23208c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 23218c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 23228c2ecf20Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 23238c2ecf20Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 23248c2ecf20Sopenharmony_ci .base = { 23258c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))", 23268c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha256-ctr-aes", 23278c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 23288c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 23298c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 23308c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 23318c2ecf20Sopenharmony_ci .cra_blocksize = 1, 23328c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 23338c2ecf20Sopenharmony_ci .cra_alignmask = 0, 23348c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha256_ctr_cra_init, 23358c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 23368c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 23378c2ecf20Sopenharmony_ci }, 23388c2ecf20Sopenharmony_ci }, 23398c2ecf20Sopenharmony_ci}; 23408c2ecf20Sopenharmony_ci 23418c2ecf20Sopenharmony_cistatic int safexcel_aead_sha224_ctr_cra_init(struct crypto_tfm *tfm) 23428c2ecf20Sopenharmony_ci{ 23438c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 23448c2ecf20Sopenharmony_ci 23458c2ecf20Sopenharmony_ci safexcel_aead_sha224_cra_init(tfm); 23468c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 23478c2ecf20Sopenharmony_ci return 0; 23488c2ecf20Sopenharmony_ci} 23498c2ecf20Sopenharmony_ci 23508c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_ctr_aes = { 23518c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 23528c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 23538c2ecf20Sopenharmony_ci .alg.aead = { 23548c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 23558c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 23568c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 23578c2ecf20Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 23588c2ecf20Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 23598c2ecf20Sopenharmony_ci .base = { 23608c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))", 23618c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha224-ctr-aes", 23628c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 23638c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 23648c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 23658c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 23668c2ecf20Sopenharmony_ci .cra_blocksize = 1, 23678c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 23688c2ecf20Sopenharmony_ci .cra_alignmask = 0, 23698c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha224_ctr_cra_init, 23708c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 23718c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 23728c2ecf20Sopenharmony_ci }, 23738c2ecf20Sopenharmony_ci }, 23748c2ecf20Sopenharmony_ci}; 23758c2ecf20Sopenharmony_ci 23768c2ecf20Sopenharmony_cistatic int safexcel_aead_sha512_ctr_cra_init(struct crypto_tfm *tfm) 23778c2ecf20Sopenharmony_ci{ 23788c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 23798c2ecf20Sopenharmony_ci 23808c2ecf20Sopenharmony_ci safexcel_aead_sha512_cra_init(tfm); 23818c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 23828c2ecf20Sopenharmony_ci return 0; 23838c2ecf20Sopenharmony_ci} 23848c2ecf20Sopenharmony_ci 23858c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes = { 23868c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 23878c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 23888c2ecf20Sopenharmony_ci .alg.aead = { 23898c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 23908c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 23918c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 23928c2ecf20Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 23938c2ecf20Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 23948c2ecf20Sopenharmony_ci .base = { 23958c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha512),rfc3686(ctr(aes)))", 23968c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha512-ctr-aes", 23978c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 23988c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 23998c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 24008c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 24018c2ecf20Sopenharmony_ci .cra_blocksize = 1, 24028c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 24038c2ecf20Sopenharmony_ci .cra_alignmask = 0, 24048c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha512_ctr_cra_init, 24058c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 24068c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 24078c2ecf20Sopenharmony_ci }, 24088c2ecf20Sopenharmony_ci }, 24098c2ecf20Sopenharmony_ci}; 24108c2ecf20Sopenharmony_ci 24118c2ecf20Sopenharmony_cistatic int safexcel_aead_sha384_ctr_cra_init(struct crypto_tfm *tfm) 24128c2ecf20Sopenharmony_ci{ 24138c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 24148c2ecf20Sopenharmony_ci 24158c2ecf20Sopenharmony_ci safexcel_aead_sha384_cra_init(tfm); 24168c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 24178c2ecf20Sopenharmony_ci return 0; 24188c2ecf20Sopenharmony_ci} 24198c2ecf20Sopenharmony_ci 24208c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes = { 24218c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 24228c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 24238c2ecf20Sopenharmony_ci .alg.aead = { 24248c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 24258c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 24268c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 24278c2ecf20Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 24288c2ecf20Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 24298c2ecf20Sopenharmony_ci .base = { 24308c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha384),rfc3686(ctr(aes)))", 24318c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha384-ctr-aes", 24328c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 24338c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 24348c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 24358c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 24368c2ecf20Sopenharmony_ci .cra_blocksize = 1, 24378c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 24388c2ecf20Sopenharmony_ci .cra_alignmask = 0, 24398c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sha384_ctr_cra_init, 24408c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 24418c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 24428c2ecf20Sopenharmony_ci }, 24438c2ecf20Sopenharmony_ci }, 24448c2ecf20Sopenharmony_ci}; 24458c2ecf20Sopenharmony_ci 24468c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm, 24478c2ecf20Sopenharmony_ci const u8 *key, unsigned int len) 24488c2ecf20Sopenharmony_ci{ 24498c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 24508c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 24518c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 24528c2ecf20Sopenharmony_ci struct crypto_aes_ctx aes; 24538c2ecf20Sopenharmony_ci int ret, i; 24548c2ecf20Sopenharmony_ci unsigned int keylen; 24558c2ecf20Sopenharmony_ci 24568c2ecf20Sopenharmony_ci /* Check for illegal XTS keys */ 24578c2ecf20Sopenharmony_ci ret = xts_verify_key(ctfm, key, len); 24588c2ecf20Sopenharmony_ci if (ret) 24598c2ecf20Sopenharmony_ci return ret; 24608c2ecf20Sopenharmony_ci 24618c2ecf20Sopenharmony_ci /* Only half of the key data is cipher key */ 24628c2ecf20Sopenharmony_ci keylen = (len >> 1); 24638c2ecf20Sopenharmony_ci ret = aes_expandkey(&aes, key, keylen); 24648c2ecf20Sopenharmony_ci if (ret) 24658c2ecf20Sopenharmony_ci return ret; 24668c2ecf20Sopenharmony_ci 24678c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 24688c2ecf20Sopenharmony_ci for (i = 0; i < keylen / sizeof(u32); i++) { 24698c2ecf20Sopenharmony_ci if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 24708c2ecf20Sopenharmony_ci ctx->base.needs_inv = true; 24718c2ecf20Sopenharmony_ci break; 24728c2ecf20Sopenharmony_ci } 24738c2ecf20Sopenharmony_ci } 24748c2ecf20Sopenharmony_ci } 24758c2ecf20Sopenharmony_ci 24768c2ecf20Sopenharmony_ci for (i = 0; i < keylen / sizeof(u32); i++) 24778c2ecf20Sopenharmony_ci ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 24788c2ecf20Sopenharmony_ci 24798c2ecf20Sopenharmony_ci /* The other half is the tweak key */ 24808c2ecf20Sopenharmony_ci ret = aes_expandkey(&aes, (u8 *)(key + keylen), keylen); 24818c2ecf20Sopenharmony_ci if (ret) 24828c2ecf20Sopenharmony_ci return ret; 24838c2ecf20Sopenharmony_ci 24848c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 24858c2ecf20Sopenharmony_ci for (i = 0; i < keylen / sizeof(u32); i++) { 24868c2ecf20Sopenharmony_ci if (le32_to_cpu(ctx->key[i + keylen / sizeof(u32)]) != 24878c2ecf20Sopenharmony_ci aes.key_enc[i]) { 24888c2ecf20Sopenharmony_ci ctx->base.needs_inv = true; 24898c2ecf20Sopenharmony_ci break; 24908c2ecf20Sopenharmony_ci } 24918c2ecf20Sopenharmony_ci } 24928c2ecf20Sopenharmony_ci } 24938c2ecf20Sopenharmony_ci 24948c2ecf20Sopenharmony_ci for (i = 0; i < keylen / sizeof(u32); i++) 24958c2ecf20Sopenharmony_ci ctx->key[i + keylen / sizeof(u32)] = 24968c2ecf20Sopenharmony_ci cpu_to_le32(aes.key_enc[i]); 24978c2ecf20Sopenharmony_ci 24988c2ecf20Sopenharmony_ci ctx->key_len = keylen << 1; 24998c2ecf20Sopenharmony_ci 25008c2ecf20Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 25018c2ecf20Sopenharmony_ci return 0; 25028c2ecf20Sopenharmony_ci} 25038c2ecf20Sopenharmony_ci 25048c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_xts_cra_init(struct crypto_tfm *tfm) 25058c2ecf20Sopenharmony_ci{ 25068c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 25078c2ecf20Sopenharmony_ci 25088c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 25098c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_AES; 25108c2ecf20Sopenharmony_ci ctx->blocksz = AES_BLOCK_SIZE; 25118c2ecf20Sopenharmony_ci ctx->xts = 1; 25128c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS; 25138c2ecf20Sopenharmony_ci return 0; 25148c2ecf20Sopenharmony_ci} 25158c2ecf20Sopenharmony_ci 25168c2ecf20Sopenharmony_cistatic int safexcel_encrypt_xts(struct skcipher_request *req) 25178c2ecf20Sopenharmony_ci{ 25188c2ecf20Sopenharmony_ci if (req->cryptlen < XTS_BLOCK_SIZE) 25198c2ecf20Sopenharmony_ci return -EINVAL; 25208c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 25218c2ecf20Sopenharmony_ci SAFEXCEL_ENCRYPT); 25228c2ecf20Sopenharmony_ci} 25238c2ecf20Sopenharmony_ci 25248c2ecf20Sopenharmony_cistatic int safexcel_decrypt_xts(struct skcipher_request *req) 25258c2ecf20Sopenharmony_ci{ 25268c2ecf20Sopenharmony_ci if (req->cryptlen < XTS_BLOCK_SIZE) 25278c2ecf20Sopenharmony_ci return -EINVAL; 25288c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 25298c2ecf20Sopenharmony_ci SAFEXCEL_DECRYPT); 25308c2ecf20Sopenharmony_ci} 25318c2ecf20Sopenharmony_ci 25328c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_xts_aes = { 25338c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 25348c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XTS, 25358c2ecf20Sopenharmony_ci .alg.skcipher = { 25368c2ecf20Sopenharmony_ci .setkey = safexcel_skcipher_aesxts_setkey, 25378c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt_xts, 25388c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt_xts, 25398c2ecf20Sopenharmony_ci /* XTS actually uses 2 AES keys glued together */ 25408c2ecf20Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE * 2, 25418c2ecf20Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE * 2, 25428c2ecf20Sopenharmony_ci .ivsize = XTS_BLOCK_SIZE, 25438c2ecf20Sopenharmony_ci .base = { 25448c2ecf20Sopenharmony_ci .cra_name = "xts(aes)", 25458c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-xts-aes", 25468c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 25478c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 25488c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 25498c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 25508c2ecf20Sopenharmony_ci .cra_blocksize = XTS_BLOCK_SIZE, 25518c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 25528c2ecf20Sopenharmony_ci .cra_alignmask = 0, 25538c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_aes_xts_cra_init, 25548c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 25558c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 25568c2ecf20Sopenharmony_ci }, 25578c2ecf20Sopenharmony_ci }, 25588c2ecf20Sopenharmony_ci}; 25598c2ecf20Sopenharmony_ci 25608c2ecf20Sopenharmony_cistatic int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, 25618c2ecf20Sopenharmony_ci unsigned int len) 25628c2ecf20Sopenharmony_ci{ 25638c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 25648c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 25658c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 25668c2ecf20Sopenharmony_ci struct crypto_aes_ctx aes; 25678c2ecf20Sopenharmony_ci u32 hashkey[AES_BLOCK_SIZE >> 2]; 25688c2ecf20Sopenharmony_ci int ret, i; 25698c2ecf20Sopenharmony_ci 25708c2ecf20Sopenharmony_ci ret = aes_expandkey(&aes, key, len); 25718c2ecf20Sopenharmony_ci if (ret) { 25728c2ecf20Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 25738c2ecf20Sopenharmony_ci return ret; 25748c2ecf20Sopenharmony_ci } 25758c2ecf20Sopenharmony_ci 25768c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 25778c2ecf20Sopenharmony_ci for (i = 0; i < len / sizeof(u32); i++) { 25788c2ecf20Sopenharmony_ci if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 25798c2ecf20Sopenharmony_ci ctx->base.needs_inv = true; 25808c2ecf20Sopenharmony_ci break; 25818c2ecf20Sopenharmony_ci } 25828c2ecf20Sopenharmony_ci } 25838c2ecf20Sopenharmony_ci } 25848c2ecf20Sopenharmony_ci 25858c2ecf20Sopenharmony_ci for (i = 0; i < len / sizeof(u32); i++) 25868c2ecf20Sopenharmony_ci ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 25878c2ecf20Sopenharmony_ci 25888c2ecf20Sopenharmony_ci ctx->key_len = len; 25898c2ecf20Sopenharmony_ci 25908c2ecf20Sopenharmony_ci /* Compute hash key by encrypting zeroes with cipher key */ 25918c2ecf20Sopenharmony_ci crypto_cipher_clear_flags(ctx->hkaes, CRYPTO_TFM_REQ_MASK); 25928c2ecf20Sopenharmony_ci crypto_cipher_set_flags(ctx->hkaes, crypto_aead_get_flags(ctfm) & 25938c2ecf20Sopenharmony_ci CRYPTO_TFM_REQ_MASK); 25948c2ecf20Sopenharmony_ci ret = crypto_cipher_setkey(ctx->hkaes, key, len); 25958c2ecf20Sopenharmony_ci if (ret) 25968c2ecf20Sopenharmony_ci return ret; 25978c2ecf20Sopenharmony_ci 25988c2ecf20Sopenharmony_ci memset(hashkey, 0, AES_BLOCK_SIZE); 25998c2ecf20Sopenharmony_ci crypto_cipher_encrypt_one(ctx->hkaes, (u8 *)hashkey, (u8 *)hashkey); 26008c2ecf20Sopenharmony_ci 26018c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 26028c2ecf20Sopenharmony_ci for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) { 26038c2ecf20Sopenharmony_ci if (be32_to_cpu(ctx->base.ipad.be[i]) != hashkey[i]) { 26048c2ecf20Sopenharmony_ci ctx->base.needs_inv = true; 26058c2ecf20Sopenharmony_ci break; 26068c2ecf20Sopenharmony_ci } 26078c2ecf20Sopenharmony_ci } 26088c2ecf20Sopenharmony_ci } 26098c2ecf20Sopenharmony_ci 26108c2ecf20Sopenharmony_ci for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) 26118c2ecf20Sopenharmony_ci ctx->base.ipad.be[i] = cpu_to_be32(hashkey[i]); 26128c2ecf20Sopenharmony_ci 26138c2ecf20Sopenharmony_ci memzero_explicit(hashkey, AES_BLOCK_SIZE); 26148c2ecf20Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 26158c2ecf20Sopenharmony_ci return 0; 26168c2ecf20Sopenharmony_ci} 26178c2ecf20Sopenharmony_ci 26188c2ecf20Sopenharmony_cistatic int safexcel_aead_gcm_cra_init(struct crypto_tfm *tfm) 26198c2ecf20Sopenharmony_ci{ 26208c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 26218c2ecf20Sopenharmony_ci 26228c2ecf20Sopenharmony_ci safexcel_aead_cra_init(tfm); 26238c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_GHASH; 26248c2ecf20Sopenharmony_ci ctx->state_sz = GHASH_BLOCK_SIZE; 26258c2ecf20Sopenharmony_ci ctx->xcm = EIP197_XCM_MODE_GCM; 26268c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ 26278c2ecf20Sopenharmony_ci 26288c2ecf20Sopenharmony_ci ctx->hkaes = crypto_alloc_cipher("aes", 0, 0); 26298c2ecf20Sopenharmony_ci return PTR_ERR_OR_ZERO(ctx->hkaes); 26308c2ecf20Sopenharmony_ci} 26318c2ecf20Sopenharmony_ci 26328c2ecf20Sopenharmony_cistatic void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm) 26338c2ecf20Sopenharmony_ci{ 26348c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 26358c2ecf20Sopenharmony_ci 26368c2ecf20Sopenharmony_ci crypto_free_cipher(ctx->hkaes); 26378c2ecf20Sopenharmony_ci safexcel_aead_cra_exit(tfm); 26388c2ecf20Sopenharmony_ci} 26398c2ecf20Sopenharmony_ci 26408c2ecf20Sopenharmony_cistatic int safexcel_aead_gcm_setauthsize(struct crypto_aead *tfm, 26418c2ecf20Sopenharmony_ci unsigned int authsize) 26428c2ecf20Sopenharmony_ci{ 26438c2ecf20Sopenharmony_ci return crypto_gcm_check_authsize(authsize); 26448c2ecf20Sopenharmony_ci} 26458c2ecf20Sopenharmony_ci 26468c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_gcm = { 26478c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 26488c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 26498c2ecf20Sopenharmony_ci .alg.aead = { 26508c2ecf20Sopenharmony_ci .setkey = safexcel_aead_gcm_setkey, 26518c2ecf20Sopenharmony_ci .setauthsize = safexcel_aead_gcm_setauthsize, 26528c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 26538c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 26548c2ecf20Sopenharmony_ci .ivsize = GCM_AES_IV_SIZE, 26558c2ecf20Sopenharmony_ci .maxauthsize = GHASH_DIGEST_SIZE, 26568c2ecf20Sopenharmony_ci .base = { 26578c2ecf20Sopenharmony_ci .cra_name = "gcm(aes)", 26588c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-gcm-aes", 26598c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 26608c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 26618c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 26628c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 26638c2ecf20Sopenharmony_ci .cra_blocksize = 1, 26648c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 26658c2ecf20Sopenharmony_ci .cra_alignmask = 0, 26668c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_gcm_cra_init, 26678c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_gcm_cra_exit, 26688c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 26698c2ecf20Sopenharmony_ci }, 26708c2ecf20Sopenharmony_ci }, 26718c2ecf20Sopenharmony_ci}; 26728c2ecf20Sopenharmony_ci 26738c2ecf20Sopenharmony_cistatic int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, 26748c2ecf20Sopenharmony_ci unsigned int len) 26758c2ecf20Sopenharmony_ci{ 26768c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 26778c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 26788c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 26798c2ecf20Sopenharmony_ci struct crypto_aes_ctx aes; 26808c2ecf20Sopenharmony_ci int ret, i; 26818c2ecf20Sopenharmony_ci 26828c2ecf20Sopenharmony_ci ret = aes_expandkey(&aes, key, len); 26838c2ecf20Sopenharmony_ci if (ret) { 26848c2ecf20Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 26858c2ecf20Sopenharmony_ci return ret; 26868c2ecf20Sopenharmony_ci } 26878c2ecf20Sopenharmony_ci 26888c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 26898c2ecf20Sopenharmony_ci for (i = 0; i < len / sizeof(u32); i++) { 26908c2ecf20Sopenharmony_ci if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 26918c2ecf20Sopenharmony_ci ctx->base.needs_inv = true; 26928c2ecf20Sopenharmony_ci break; 26938c2ecf20Sopenharmony_ci } 26948c2ecf20Sopenharmony_ci } 26958c2ecf20Sopenharmony_ci } 26968c2ecf20Sopenharmony_ci 26978c2ecf20Sopenharmony_ci for (i = 0; i < len / sizeof(u32); i++) { 26988c2ecf20Sopenharmony_ci ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 26998c2ecf20Sopenharmony_ci ctx->base.ipad.be[i + 2 * AES_BLOCK_SIZE / sizeof(u32)] = 27008c2ecf20Sopenharmony_ci cpu_to_be32(aes.key_enc[i]); 27018c2ecf20Sopenharmony_ci } 27028c2ecf20Sopenharmony_ci 27038c2ecf20Sopenharmony_ci ctx->key_len = len; 27048c2ecf20Sopenharmony_ci ctx->state_sz = 2 * AES_BLOCK_SIZE + len; 27058c2ecf20Sopenharmony_ci 27068c2ecf20Sopenharmony_ci if (len == AES_KEYSIZE_192) 27078c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192; 27088c2ecf20Sopenharmony_ci else if (len == AES_KEYSIZE_256) 27098c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256; 27108c2ecf20Sopenharmony_ci else 27118c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; 27128c2ecf20Sopenharmony_ci 27138c2ecf20Sopenharmony_ci memzero_explicit(&aes, sizeof(aes)); 27148c2ecf20Sopenharmony_ci return 0; 27158c2ecf20Sopenharmony_ci} 27168c2ecf20Sopenharmony_ci 27178c2ecf20Sopenharmony_cistatic int safexcel_aead_ccm_cra_init(struct crypto_tfm *tfm) 27188c2ecf20Sopenharmony_ci{ 27198c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 27208c2ecf20Sopenharmony_ci 27218c2ecf20Sopenharmony_ci safexcel_aead_cra_init(tfm); 27228c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; 27238c2ecf20Sopenharmony_ci ctx->state_sz = 3 * AES_BLOCK_SIZE; 27248c2ecf20Sopenharmony_ci ctx->xcm = EIP197_XCM_MODE_CCM; 27258c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ 27268c2ecf20Sopenharmony_ci ctx->ctrinit = 0; 27278c2ecf20Sopenharmony_ci return 0; 27288c2ecf20Sopenharmony_ci} 27298c2ecf20Sopenharmony_ci 27308c2ecf20Sopenharmony_cistatic int safexcel_aead_ccm_setauthsize(struct crypto_aead *tfm, 27318c2ecf20Sopenharmony_ci unsigned int authsize) 27328c2ecf20Sopenharmony_ci{ 27338c2ecf20Sopenharmony_ci /* Borrowed from crypto/ccm.c */ 27348c2ecf20Sopenharmony_ci switch (authsize) { 27358c2ecf20Sopenharmony_ci case 4: 27368c2ecf20Sopenharmony_ci case 6: 27378c2ecf20Sopenharmony_ci case 8: 27388c2ecf20Sopenharmony_ci case 10: 27398c2ecf20Sopenharmony_ci case 12: 27408c2ecf20Sopenharmony_ci case 14: 27418c2ecf20Sopenharmony_ci case 16: 27428c2ecf20Sopenharmony_ci break; 27438c2ecf20Sopenharmony_ci default: 27448c2ecf20Sopenharmony_ci return -EINVAL; 27458c2ecf20Sopenharmony_ci } 27468c2ecf20Sopenharmony_ci 27478c2ecf20Sopenharmony_ci return 0; 27488c2ecf20Sopenharmony_ci} 27498c2ecf20Sopenharmony_ci 27508c2ecf20Sopenharmony_cistatic int safexcel_ccm_encrypt(struct aead_request *req) 27518c2ecf20Sopenharmony_ci{ 27528c2ecf20Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 27538c2ecf20Sopenharmony_ci 27548c2ecf20Sopenharmony_ci if (req->iv[0] < 1 || req->iv[0] > 7) 27558c2ecf20Sopenharmony_ci return -EINVAL; 27568c2ecf20Sopenharmony_ci 27578c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 27588c2ecf20Sopenharmony_ci} 27598c2ecf20Sopenharmony_ci 27608c2ecf20Sopenharmony_cistatic int safexcel_ccm_decrypt(struct aead_request *req) 27618c2ecf20Sopenharmony_ci{ 27628c2ecf20Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 27638c2ecf20Sopenharmony_ci 27648c2ecf20Sopenharmony_ci if (req->iv[0] < 1 || req->iv[0] > 7) 27658c2ecf20Sopenharmony_ci return -EINVAL; 27668c2ecf20Sopenharmony_ci 27678c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 27688c2ecf20Sopenharmony_ci} 27698c2ecf20Sopenharmony_ci 27708c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ccm = { 27718c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 27728c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, 27738c2ecf20Sopenharmony_ci .alg.aead = { 27748c2ecf20Sopenharmony_ci .setkey = safexcel_aead_ccm_setkey, 27758c2ecf20Sopenharmony_ci .setauthsize = safexcel_aead_ccm_setauthsize, 27768c2ecf20Sopenharmony_ci .encrypt = safexcel_ccm_encrypt, 27778c2ecf20Sopenharmony_ci .decrypt = safexcel_ccm_decrypt, 27788c2ecf20Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 27798c2ecf20Sopenharmony_ci .maxauthsize = AES_BLOCK_SIZE, 27808c2ecf20Sopenharmony_ci .base = { 27818c2ecf20Sopenharmony_ci .cra_name = "ccm(aes)", 27828c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-ccm-aes", 27838c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 27848c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 27858c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 27868c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 27878c2ecf20Sopenharmony_ci .cra_blocksize = 1, 27888c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 27898c2ecf20Sopenharmony_ci .cra_alignmask = 0, 27908c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_ccm_cra_init, 27918c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 27928c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 27938c2ecf20Sopenharmony_ci }, 27948c2ecf20Sopenharmony_ci }, 27958c2ecf20Sopenharmony_ci}; 27968c2ecf20Sopenharmony_ci 27978c2ecf20Sopenharmony_cistatic void safexcel_chacha20_setkey(struct safexcel_cipher_ctx *ctx, 27988c2ecf20Sopenharmony_ci const u8 *key) 27998c2ecf20Sopenharmony_ci{ 28008c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 28018c2ecf20Sopenharmony_ci 28028c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 28038c2ecf20Sopenharmony_ci if (memcmp(ctx->key, key, CHACHA_KEY_SIZE)) 28048c2ecf20Sopenharmony_ci ctx->base.needs_inv = true; 28058c2ecf20Sopenharmony_ci 28068c2ecf20Sopenharmony_ci memcpy(ctx->key, key, CHACHA_KEY_SIZE); 28078c2ecf20Sopenharmony_ci ctx->key_len = CHACHA_KEY_SIZE; 28088c2ecf20Sopenharmony_ci} 28098c2ecf20Sopenharmony_ci 28108c2ecf20Sopenharmony_cistatic int safexcel_skcipher_chacha20_setkey(struct crypto_skcipher *ctfm, 28118c2ecf20Sopenharmony_ci const u8 *key, unsigned int len) 28128c2ecf20Sopenharmony_ci{ 28138c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 28148c2ecf20Sopenharmony_ci 28158c2ecf20Sopenharmony_ci if (len != CHACHA_KEY_SIZE) 28168c2ecf20Sopenharmony_ci return -EINVAL; 28178c2ecf20Sopenharmony_ci 28188c2ecf20Sopenharmony_ci safexcel_chacha20_setkey(ctx, key); 28198c2ecf20Sopenharmony_ci 28208c2ecf20Sopenharmony_ci return 0; 28218c2ecf20Sopenharmony_ci} 28228c2ecf20Sopenharmony_ci 28238c2ecf20Sopenharmony_cistatic int safexcel_skcipher_chacha20_cra_init(struct crypto_tfm *tfm) 28248c2ecf20Sopenharmony_ci{ 28258c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 28268c2ecf20Sopenharmony_ci 28278c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 28288c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_CHACHA20; 28298c2ecf20Sopenharmony_ci ctx->ctrinit = 0; 28308c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32; 28318c2ecf20Sopenharmony_ci return 0; 28328c2ecf20Sopenharmony_ci} 28338c2ecf20Sopenharmony_ci 28348c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_chacha20 = { 28358c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 28368c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_CHACHA20, 28378c2ecf20Sopenharmony_ci .alg.skcipher = { 28388c2ecf20Sopenharmony_ci .setkey = safexcel_skcipher_chacha20_setkey, 28398c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 28408c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 28418c2ecf20Sopenharmony_ci .min_keysize = CHACHA_KEY_SIZE, 28428c2ecf20Sopenharmony_ci .max_keysize = CHACHA_KEY_SIZE, 28438c2ecf20Sopenharmony_ci .ivsize = CHACHA_IV_SIZE, 28448c2ecf20Sopenharmony_ci .base = { 28458c2ecf20Sopenharmony_ci .cra_name = "chacha20", 28468c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-chacha20", 28478c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 28488c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 28498c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 28508c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 28518c2ecf20Sopenharmony_ci .cra_blocksize = 1, 28528c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 28538c2ecf20Sopenharmony_ci .cra_alignmask = 0, 28548c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_chacha20_cra_init, 28558c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 28568c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 28578c2ecf20Sopenharmony_ci }, 28588c2ecf20Sopenharmony_ci }, 28598c2ecf20Sopenharmony_ci}; 28608c2ecf20Sopenharmony_ci 28618c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapoly_setkey(struct crypto_aead *ctfm, 28628c2ecf20Sopenharmony_ci const u8 *key, unsigned int len) 28638c2ecf20Sopenharmony_ci{ 28648c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_aead_ctx(ctfm); 28658c2ecf20Sopenharmony_ci 28668c2ecf20Sopenharmony_ci if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP && 28678c2ecf20Sopenharmony_ci len > EIP197_AEAD_IPSEC_NONCE_SIZE) { 28688c2ecf20Sopenharmony_ci /* ESP variant has nonce appended to key */ 28698c2ecf20Sopenharmony_ci len -= EIP197_AEAD_IPSEC_NONCE_SIZE; 28708c2ecf20Sopenharmony_ci ctx->nonce = *(u32 *)(key + len); 28718c2ecf20Sopenharmony_ci } 28728c2ecf20Sopenharmony_ci if (len != CHACHA_KEY_SIZE) 28738c2ecf20Sopenharmony_ci return -EINVAL; 28748c2ecf20Sopenharmony_ci 28758c2ecf20Sopenharmony_ci safexcel_chacha20_setkey(ctx, key); 28768c2ecf20Sopenharmony_ci 28778c2ecf20Sopenharmony_ci return 0; 28788c2ecf20Sopenharmony_ci} 28798c2ecf20Sopenharmony_ci 28808c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapoly_setauthsize(struct crypto_aead *tfm, 28818c2ecf20Sopenharmony_ci unsigned int authsize) 28828c2ecf20Sopenharmony_ci{ 28838c2ecf20Sopenharmony_ci if (authsize != POLY1305_DIGEST_SIZE) 28848c2ecf20Sopenharmony_ci return -EINVAL; 28858c2ecf20Sopenharmony_ci return 0; 28868c2ecf20Sopenharmony_ci} 28878c2ecf20Sopenharmony_ci 28888c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapoly_crypt(struct aead_request *req, 28898c2ecf20Sopenharmony_ci enum safexcel_cipher_direction dir) 28908c2ecf20Sopenharmony_ci{ 28918c2ecf20Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 28928c2ecf20Sopenharmony_ci struct crypto_aead *aead = crypto_aead_reqtfm(req); 28938c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(aead); 28948c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 28958c2ecf20Sopenharmony_ci struct aead_request *subreq = aead_request_ctx(req); 28968c2ecf20Sopenharmony_ci u32 key[CHACHA_KEY_SIZE / sizeof(u32) + 1]; 28978c2ecf20Sopenharmony_ci int ret = 0; 28988c2ecf20Sopenharmony_ci 28998c2ecf20Sopenharmony_ci /* 29008c2ecf20Sopenharmony_ci * Instead of wasting time detecting umpteen silly corner cases, 29018c2ecf20Sopenharmony_ci * just dump all "small" requests to the fallback implementation. 29028c2ecf20Sopenharmony_ci * HW would not be faster on such small requests anyway. 29038c2ecf20Sopenharmony_ci */ 29048c2ecf20Sopenharmony_ci if (likely((ctx->aead != EIP197_AEAD_TYPE_IPSEC_ESP || 29058c2ecf20Sopenharmony_ci req->assoclen >= EIP197_AEAD_IPSEC_IV_SIZE) && 29068c2ecf20Sopenharmony_ci req->cryptlen > POLY1305_DIGEST_SIZE)) { 29078c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, creq, dir); 29088c2ecf20Sopenharmony_ci } 29098c2ecf20Sopenharmony_ci 29108c2ecf20Sopenharmony_ci /* HW cannot do full (AAD+payload) zero length, use fallback */ 29118c2ecf20Sopenharmony_ci memcpy(key, ctx->key, CHACHA_KEY_SIZE); 29128c2ecf20Sopenharmony_ci if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 29138c2ecf20Sopenharmony_ci /* ESP variant has nonce appended to the key */ 29148c2ecf20Sopenharmony_ci key[CHACHA_KEY_SIZE / sizeof(u32)] = ctx->nonce; 29158c2ecf20Sopenharmony_ci ret = crypto_aead_setkey(ctx->fback, (u8 *)key, 29168c2ecf20Sopenharmony_ci CHACHA_KEY_SIZE + 29178c2ecf20Sopenharmony_ci EIP197_AEAD_IPSEC_NONCE_SIZE); 29188c2ecf20Sopenharmony_ci } else { 29198c2ecf20Sopenharmony_ci ret = crypto_aead_setkey(ctx->fback, (u8 *)key, 29208c2ecf20Sopenharmony_ci CHACHA_KEY_SIZE); 29218c2ecf20Sopenharmony_ci } 29228c2ecf20Sopenharmony_ci if (ret) { 29238c2ecf20Sopenharmony_ci crypto_aead_clear_flags(aead, CRYPTO_TFM_REQ_MASK); 29248c2ecf20Sopenharmony_ci crypto_aead_set_flags(aead, crypto_aead_get_flags(ctx->fback) & 29258c2ecf20Sopenharmony_ci CRYPTO_TFM_REQ_MASK); 29268c2ecf20Sopenharmony_ci return ret; 29278c2ecf20Sopenharmony_ci } 29288c2ecf20Sopenharmony_ci 29298c2ecf20Sopenharmony_ci aead_request_set_tfm(subreq, ctx->fback); 29308c2ecf20Sopenharmony_ci aead_request_set_callback(subreq, req->base.flags, req->base.complete, 29318c2ecf20Sopenharmony_ci req->base.data); 29328c2ecf20Sopenharmony_ci aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 29338c2ecf20Sopenharmony_ci req->iv); 29348c2ecf20Sopenharmony_ci aead_request_set_ad(subreq, req->assoclen); 29358c2ecf20Sopenharmony_ci 29368c2ecf20Sopenharmony_ci return (dir == SAFEXCEL_ENCRYPT) ? 29378c2ecf20Sopenharmony_ci crypto_aead_encrypt(subreq) : 29388c2ecf20Sopenharmony_ci crypto_aead_decrypt(subreq); 29398c2ecf20Sopenharmony_ci} 29408c2ecf20Sopenharmony_ci 29418c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapoly_encrypt(struct aead_request *req) 29428c2ecf20Sopenharmony_ci{ 29438c2ecf20Sopenharmony_ci return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_ENCRYPT); 29448c2ecf20Sopenharmony_ci} 29458c2ecf20Sopenharmony_ci 29468c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapoly_decrypt(struct aead_request *req) 29478c2ecf20Sopenharmony_ci{ 29488c2ecf20Sopenharmony_ci return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_DECRYPT); 29498c2ecf20Sopenharmony_ci} 29508c2ecf20Sopenharmony_ci 29518c2ecf20Sopenharmony_cistatic int safexcel_aead_fallback_cra_init(struct crypto_tfm *tfm) 29528c2ecf20Sopenharmony_ci{ 29538c2ecf20Sopenharmony_ci struct crypto_aead *aead = __crypto_aead_cast(tfm); 29548c2ecf20Sopenharmony_ci struct aead_alg *alg = crypto_aead_alg(aead); 29558c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 29568c2ecf20Sopenharmony_ci 29578c2ecf20Sopenharmony_ci safexcel_aead_cra_init(tfm); 29588c2ecf20Sopenharmony_ci 29598c2ecf20Sopenharmony_ci /* Allocate fallback implementation */ 29608c2ecf20Sopenharmony_ci ctx->fback = crypto_alloc_aead(alg->base.cra_name, 0, 29618c2ecf20Sopenharmony_ci CRYPTO_ALG_ASYNC | 29628c2ecf20Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK); 29638c2ecf20Sopenharmony_ci if (IS_ERR(ctx->fback)) 29648c2ecf20Sopenharmony_ci return PTR_ERR(ctx->fback); 29658c2ecf20Sopenharmony_ci 29668c2ecf20Sopenharmony_ci crypto_aead_set_reqsize(aead, max(sizeof(struct safexcel_cipher_req), 29678c2ecf20Sopenharmony_ci sizeof(struct aead_request) + 29688c2ecf20Sopenharmony_ci crypto_aead_reqsize(ctx->fback))); 29698c2ecf20Sopenharmony_ci 29708c2ecf20Sopenharmony_ci return 0; 29718c2ecf20Sopenharmony_ci} 29728c2ecf20Sopenharmony_ci 29738c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapoly_cra_init(struct crypto_tfm *tfm) 29748c2ecf20Sopenharmony_ci{ 29758c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 29768c2ecf20Sopenharmony_ci 29778c2ecf20Sopenharmony_ci safexcel_aead_fallback_cra_init(tfm); 29788c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_CHACHA20; 29798c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32 | 29808c2ecf20Sopenharmony_ci CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK; 29818c2ecf20Sopenharmony_ci ctx->ctrinit = 0; 29828c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_POLY1305; 29838c2ecf20Sopenharmony_ci ctx->state_sz = 0; /* Precomputed by HW */ 29848c2ecf20Sopenharmony_ci return 0; 29858c2ecf20Sopenharmony_ci} 29868c2ecf20Sopenharmony_ci 29878c2ecf20Sopenharmony_cistatic void safexcel_aead_fallback_cra_exit(struct crypto_tfm *tfm) 29888c2ecf20Sopenharmony_ci{ 29898c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 29908c2ecf20Sopenharmony_ci 29918c2ecf20Sopenharmony_ci crypto_free_aead(ctx->fback); 29928c2ecf20Sopenharmony_ci safexcel_aead_cra_exit(tfm); 29938c2ecf20Sopenharmony_ci} 29948c2ecf20Sopenharmony_ci 29958c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_chachapoly = { 29968c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 29978c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, 29988c2ecf20Sopenharmony_ci .alg.aead = { 29998c2ecf20Sopenharmony_ci .setkey = safexcel_aead_chachapoly_setkey, 30008c2ecf20Sopenharmony_ci .setauthsize = safexcel_aead_chachapoly_setauthsize, 30018c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_chachapoly_encrypt, 30028c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_chachapoly_decrypt, 30038c2ecf20Sopenharmony_ci .ivsize = CHACHAPOLY_IV_SIZE, 30048c2ecf20Sopenharmony_ci .maxauthsize = POLY1305_DIGEST_SIZE, 30058c2ecf20Sopenharmony_ci .base = { 30068c2ecf20Sopenharmony_ci .cra_name = "rfc7539(chacha20,poly1305)", 30078c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-chacha20-poly1305", 30088c2ecf20Sopenharmony_ci /* +1 to put it above HW chacha + SW poly */ 30098c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, 30108c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 30118c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 30128c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY | 30138c2ecf20Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 30148c2ecf20Sopenharmony_ci .cra_blocksize = 1, 30158c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 30168c2ecf20Sopenharmony_ci .cra_alignmask = 0, 30178c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_chachapoly_cra_init, 30188c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_fallback_cra_exit, 30198c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 30208c2ecf20Sopenharmony_ci }, 30218c2ecf20Sopenharmony_ci }, 30228c2ecf20Sopenharmony_ci}; 30238c2ecf20Sopenharmony_ci 30248c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm *tfm) 30258c2ecf20Sopenharmony_ci{ 30268c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 30278c2ecf20Sopenharmony_ci int ret; 30288c2ecf20Sopenharmony_ci 30298c2ecf20Sopenharmony_ci ret = safexcel_aead_chachapoly_cra_init(tfm); 30308c2ecf20Sopenharmony_ci ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 30318c2ecf20Sopenharmony_ci ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 30328c2ecf20Sopenharmony_ci return ret; 30338c2ecf20Sopenharmony_ci} 30348c2ecf20Sopenharmony_ci 30358c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_chachapoly_esp = { 30368c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 30378c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, 30388c2ecf20Sopenharmony_ci .alg.aead = { 30398c2ecf20Sopenharmony_ci .setkey = safexcel_aead_chachapoly_setkey, 30408c2ecf20Sopenharmony_ci .setauthsize = safexcel_aead_chachapoly_setauthsize, 30418c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_chachapoly_encrypt, 30428c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_chachapoly_decrypt, 30438c2ecf20Sopenharmony_ci .ivsize = CHACHAPOLY_IV_SIZE - EIP197_AEAD_IPSEC_NONCE_SIZE, 30448c2ecf20Sopenharmony_ci .maxauthsize = POLY1305_DIGEST_SIZE, 30458c2ecf20Sopenharmony_ci .base = { 30468c2ecf20Sopenharmony_ci .cra_name = "rfc7539esp(chacha20,poly1305)", 30478c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-chacha20-poly1305-esp", 30488c2ecf20Sopenharmony_ci /* +1 to put it above HW chacha + SW poly */ 30498c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, 30508c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 30518c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 30528c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY | 30538c2ecf20Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 30548c2ecf20Sopenharmony_ci .cra_blocksize = 1, 30558c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 30568c2ecf20Sopenharmony_ci .cra_alignmask = 0, 30578c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_chachapolyesp_cra_init, 30588c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_fallback_cra_exit, 30598c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 30608c2ecf20Sopenharmony_ci }, 30618c2ecf20Sopenharmony_ci }, 30628c2ecf20Sopenharmony_ci}; 30638c2ecf20Sopenharmony_ci 30648c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4_setkey(struct crypto_skcipher *ctfm, 30658c2ecf20Sopenharmony_ci const u8 *key, unsigned int len) 30668c2ecf20Sopenharmony_ci{ 30678c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 30688c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 30698c2ecf20Sopenharmony_ci struct safexcel_crypto_priv *priv = ctx->base.priv; 30708c2ecf20Sopenharmony_ci 30718c2ecf20Sopenharmony_ci if (len != SM4_KEY_SIZE) 30728c2ecf20Sopenharmony_ci return -EINVAL; 30738c2ecf20Sopenharmony_ci 30748c2ecf20Sopenharmony_ci if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 30758c2ecf20Sopenharmony_ci if (memcmp(ctx->key, key, SM4_KEY_SIZE)) 30768c2ecf20Sopenharmony_ci ctx->base.needs_inv = true; 30778c2ecf20Sopenharmony_ci 30788c2ecf20Sopenharmony_ci memcpy(ctx->key, key, SM4_KEY_SIZE); 30798c2ecf20Sopenharmony_ci ctx->key_len = SM4_KEY_SIZE; 30808c2ecf20Sopenharmony_ci 30818c2ecf20Sopenharmony_ci return 0; 30828c2ecf20Sopenharmony_ci} 30838c2ecf20Sopenharmony_ci 30848c2ecf20Sopenharmony_cistatic int safexcel_sm4_blk_encrypt(struct skcipher_request *req) 30858c2ecf20Sopenharmony_ci{ 30868c2ecf20Sopenharmony_ci /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 30878c2ecf20Sopenharmony_ci if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 30888c2ecf20Sopenharmony_ci return -EINVAL; 30898c2ecf20Sopenharmony_ci else 30908c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 30918c2ecf20Sopenharmony_ci SAFEXCEL_ENCRYPT); 30928c2ecf20Sopenharmony_ci} 30938c2ecf20Sopenharmony_ci 30948c2ecf20Sopenharmony_cistatic int safexcel_sm4_blk_decrypt(struct skcipher_request *req) 30958c2ecf20Sopenharmony_ci{ 30968c2ecf20Sopenharmony_ci /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 30978c2ecf20Sopenharmony_ci if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 30988c2ecf20Sopenharmony_ci return -EINVAL; 30998c2ecf20Sopenharmony_ci else 31008c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 31018c2ecf20Sopenharmony_ci SAFEXCEL_DECRYPT); 31028c2ecf20Sopenharmony_ci} 31038c2ecf20Sopenharmony_ci 31048c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm *tfm) 31058c2ecf20Sopenharmony_ci{ 31068c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 31078c2ecf20Sopenharmony_ci 31088c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 31098c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 31108c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 31118c2ecf20Sopenharmony_ci ctx->blocksz = 0; 31128c2ecf20Sopenharmony_ci ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 31138c2ecf20Sopenharmony_ci return 0; 31148c2ecf20Sopenharmony_ci} 31158c2ecf20Sopenharmony_ci 31168c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ecb_sm4 = { 31178c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 31188c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4, 31198c2ecf20Sopenharmony_ci .alg.skcipher = { 31208c2ecf20Sopenharmony_ci .setkey = safexcel_skcipher_sm4_setkey, 31218c2ecf20Sopenharmony_ci .encrypt = safexcel_sm4_blk_encrypt, 31228c2ecf20Sopenharmony_ci .decrypt = safexcel_sm4_blk_decrypt, 31238c2ecf20Sopenharmony_ci .min_keysize = SM4_KEY_SIZE, 31248c2ecf20Sopenharmony_ci .max_keysize = SM4_KEY_SIZE, 31258c2ecf20Sopenharmony_ci .base = { 31268c2ecf20Sopenharmony_ci .cra_name = "ecb(sm4)", 31278c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-ecb-sm4", 31288c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 31298c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 31308c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 31318c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 31328c2ecf20Sopenharmony_ci .cra_blocksize = SM4_BLOCK_SIZE, 31338c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 31348c2ecf20Sopenharmony_ci .cra_alignmask = 0, 31358c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_sm4_ecb_cra_init, 31368c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 31378c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 31388c2ecf20Sopenharmony_ci }, 31398c2ecf20Sopenharmony_ci }, 31408c2ecf20Sopenharmony_ci}; 31418c2ecf20Sopenharmony_ci 31428c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm *tfm) 31438c2ecf20Sopenharmony_ci{ 31448c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 31458c2ecf20Sopenharmony_ci 31468c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 31478c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 31488c2ecf20Sopenharmony_ci ctx->blocksz = SM4_BLOCK_SIZE; 31498c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 31508c2ecf20Sopenharmony_ci return 0; 31518c2ecf20Sopenharmony_ci} 31528c2ecf20Sopenharmony_ci 31538c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cbc_sm4 = { 31548c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 31558c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4, 31568c2ecf20Sopenharmony_ci .alg.skcipher = { 31578c2ecf20Sopenharmony_ci .setkey = safexcel_skcipher_sm4_setkey, 31588c2ecf20Sopenharmony_ci .encrypt = safexcel_sm4_blk_encrypt, 31598c2ecf20Sopenharmony_ci .decrypt = safexcel_sm4_blk_decrypt, 31608c2ecf20Sopenharmony_ci .min_keysize = SM4_KEY_SIZE, 31618c2ecf20Sopenharmony_ci .max_keysize = SM4_KEY_SIZE, 31628c2ecf20Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 31638c2ecf20Sopenharmony_ci .base = { 31648c2ecf20Sopenharmony_ci .cra_name = "cbc(sm4)", 31658c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-cbc-sm4", 31668c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 31678c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 31688c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 31698c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 31708c2ecf20Sopenharmony_ci .cra_blocksize = SM4_BLOCK_SIZE, 31718c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 31728c2ecf20Sopenharmony_ci .cra_alignmask = 0, 31738c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_sm4_cbc_cra_init, 31748c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 31758c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 31768c2ecf20Sopenharmony_ci }, 31778c2ecf20Sopenharmony_ci }, 31788c2ecf20Sopenharmony_ci}; 31798c2ecf20Sopenharmony_ci 31808c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4_ofb_cra_init(struct crypto_tfm *tfm) 31818c2ecf20Sopenharmony_ci{ 31828c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 31838c2ecf20Sopenharmony_ci 31848c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 31858c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 31868c2ecf20Sopenharmony_ci ctx->blocksz = SM4_BLOCK_SIZE; 31878c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; 31888c2ecf20Sopenharmony_ci return 0; 31898c2ecf20Sopenharmony_ci} 31908c2ecf20Sopenharmony_ci 31918c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ofb_sm4 = { 31928c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 31938c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, 31948c2ecf20Sopenharmony_ci .alg.skcipher = { 31958c2ecf20Sopenharmony_ci .setkey = safexcel_skcipher_sm4_setkey, 31968c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 31978c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 31988c2ecf20Sopenharmony_ci .min_keysize = SM4_KEY_SIZE, 31998c2ecf20Sopenharmony_ci .max_keysize = SM4_KEY_SIZE, 32008c2ecf20Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 32018c2ecf20Sopenharmony_ci .base = { 32028c2ecf20Sopenharmony_ci .cra_name = "ofb(sm4)", 32038c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-ofb-sm4", 32048c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 32058c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 32068c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 32078c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 32088c2ecf20Sopenharmony_ci .cra_blocksize = 1, 32098c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 32108c2ecf20Sopenharmony_ci .cra_alignmask = 0, 32118c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_sm4_ofb_cra_init, 32128c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 32138c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 32148c2ecf20Sopenharmony_ci }, 32158c2ecf20Sopenharmony_ci }, 32168c2ecf20Sopenharmony_ci}; 32178c2ecf20Sopenharmony_ci 32188c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4_cfb_cra_init(struct crypto_tfm *tfm) 32198c2ecf20Sopenharmony_ci{ 32208c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 32218c2ecf20Sopenharmony_ci 32228c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 32238c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 32248c2ecf20Sopenharmony_ci ctx->blocksz = SM4_BLOCK_SIZE; 32258c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; 32268c2ecf20Sopenharmony_ci return 0; 32278c2ecf20Sopenharmony_ci} 32288c2ecf20Sopenharmony_ci 32298c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cfb_sm4 = { 32308c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 32318c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, 32328c2ecf20Sopenharmony_ci .alg.skcipher = { 32338c2ecf20Sopenharmony_ci .setkey = safexcel_skcipher_sm4_setkey, 32348c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 32358c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 32368c2ecf20Sopenharmony_ci .min_keysize = SM4_KEY_SIZE, 32378c2ecf20Sopenharmony_ci .max_keysize = SM4_KEY_SIZE, 32388c2ecf20Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 32398c2ecf20Sopenharmony_ci .base = { 32408c2ecf20Sopenharmony_ci .cra_name = "cfb(sm4)", 32418c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-cfb-sm4", 32428c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 32438c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 32448c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 32458c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 32468c2ecf20Sopenharmony_ci .cra_blocksize = 1, 32478c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 32488c2ecf20Sopenharmony_ci .cra_alignmask = 0, 32498c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_sm4_cfb_cra_init, 32508c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 32518c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 32528c2ecf20Sopenharmony_ci }, 32538c2ecf20Sopenharmony_ci }, 32548c2ecf20Sopenharmony_ci}; 32558c2ecf20Sopenharmony_ci 32568c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4ctr_setkey(struct crypto_skcipher *ctfm, 32578c2ecf20Sopenharmony_ci const u8 *key, unsigned int len) 32588c2ecf20Sopenharmony_ci{ 32598c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 32608c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 32618c2ecf20Sopenharmony_ci 32628c2ecf20Sopenharmony_ci /* last 4 bytes of key are the nonce! */ 32638c2ecf20Sopenharmony_ci ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 32648c2ecf20Sopenharmony_ci /* exclude the nonce here */ 32658c2ecf20Sopenharmony_ci len -= CTR_RFC3686_NONCE_SIZE; 32668c2ecf20Sopenharmony_ci 32678c2ecf20Sopenharmony_ci return safexcel_skcipher_sm4_setkey(ctfm, key, len); 32688c2ecf20Sopenharmony_ci} 32698c2ecf20Sopenharmony_ci 32708c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4_ctr_cra_init(struct crypto_tfm *tfm) 32718c2ecf20Sopenharmony_ci{ 32728c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 32738c2ecf20Sopenharmony_ci 32748c2ecf20Sopenharmony_ci safexcel_skcipher_cra_init(tfm); 32758c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 32768c2ecf20Sopenharmony_ci ctx->blocksz = SM4_BLOCK_SIZE; 32778c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 32788c2ecf20Sopenharmony_ci return 0; 32798c2ecf20Sopenharmony_ci} 32808c2ecf20Sopenharmony_ci 32818c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ctr_sm4 = { 32828c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 32838c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4, 32848c2ecf20Sopenharmony_ci .alg.skcipher = { 32858c2ecf20Sopenharmony_ci .setkey = safexcel_skcipher_sm4ctr_setkey, 32868c2ecf20Sopenharmony_ci .encrypt = safexcel_encrypt, 32878c2ecf20Sopenharmony_ci .decrypt = safexcel_decrypt, 32888c2ecf20Sopenharmony_ci /* Add nonce size */ 32898c2ecf20Sopenharmony_ci .min_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 32908c2ecf20Sopenharmony_ci .max_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 32918c2ecf20Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 32928c2ecf20Sopenharmony_ci .base = { 32938c2ecf20Sopenharmony_ci .cra_name = "rfc3686(ctr(sm4))", 32948c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-ctr-sm4", 32958c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 32968c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 32978c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 32988c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 32998c2ecf20Sopenharmony_ci .cra_blocksize = 1, 33008c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 33018c2ecf20Sopenharmony_ci .cra_alignmask = 0, 33028c2ecf20Sopenharmony_ci .cra_init = safexcel_skcipher_sm4_ctr_cra_init, 33038c2ecf20Sopenharmony_ci .cra_exit = safexcel_skcipher_cra_exit, 33048c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 33058c2ecf20Sopenharmony_ci }, 33068c2ecf20Sopenharmony_ci }, 33078c2ecf20Sopenharmony_ci}; 33088c2ecf20Sopenharmony_ci 33098c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4_blk_encrypt(struct aead_request *req) 33108c2ecf20Sopenharmony_ci{ 33118c2ecf20Sopenharmony_ci /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 33128c2ecf20Sopenharmony_ci if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 33138c2ecf20Sopenharmony_ci return -EINVAL; 33148c2ecf20Sopenharmony_ci 33158c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, aead_request_ctx(req), 33168c2ecf20Sopenharmony_ci SAFEXCEL_ENCRYPT); 33178c2ecf20Sopenharmony_ci} 33188c2ecf20Sopenharmony_ci 33198c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4_blk_decrypt(struct aead_request *req) 33208c2ecf20Sopenharmony_ci{ 33218c2ecf20Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 33228c2ecf20Sopenharmony_ci 33238c2ecf20Sopenharmony_ci /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 33248c2ecf20Sopenharmony_ci if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) 33258c2ecf20Sopenharmony_ci return -EINVAL; 33268c2ecf20Sopenharmony_ci 33278c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, aead_request_ctx(req), 33288c2ecf20Sopenharmony_ci SAFEXCEL_DECRYPT); 33298c2ecf20Sopenharmony_ci} 33308c2ecf20Sopenharmony_ci 33318c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4cbc_sha1_cra_init(struct crypto_tfm *tfm) 33328c2ecf20Sopenharmony_ci{ 33338c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33348c2ecf20Sopenharmony_ci 33358c2ecf20Sopenharmony_ci safexcel_aead_cra_init(tfm); 33368c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 33378c2ecf20Sopenharmony_ci ctx->blocksz = SM4_BLOCK_SIZE; 33388c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; 33398c2ecf20Sopenharmony_ci ctx->state_sz = SHA1_DIGEST_SIZE; 33408c2ecf20Sopenharmony_ci return 0; 33418c2ecf20Sopenharmony_ci} 33428c2ecf20Sopenharmony_ci 33438c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4 = { 33448c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 33458c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, 33468c2ecf20Sopenharmony_ci .alg.aead = { 33478c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 33488c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_sm4_blk_encrypt, 33498c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_sm4_blk_decrypt, 33508c2ecf20Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 33518c2ecf20Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 33528c2ecf20Sopenharmony_ci .base = { 33538c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha1),cbc(sm4))", 33548c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-sm4", 33558c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 33568c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 33578c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 33588c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 33598c2ecf20Sopenharmony_ci .cra_blocksize = SM4_BLOCK_SIZE, 33608c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 33618c2ecf20Sopenharmony_ci .cra_alignmask = 0, 33628c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sm4cbc_sha1_cra_init, 33638c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 33648c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 33658c2ecf20Sopenharmony_ci }, 33668c2ecf20Sopenharmony_ci }, 33678c2ecf20Sopenharmony_ci}; 33688c2ecf20Sopenharmony_ci 33698c2ecf20Sopenharmony_cistatic int safexcel_aead_fallback_setkey(struct crypto_aead *ctfm, 33708c2ecf20Sopenharmony_ci const u8 *key, unsigned int len) 33718c2ecf20Sopenharmony_ci{ 33728c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 33738c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33748c2ecf20Sopenharmony_ci 33758c2ecf20Sopenharmony_ci /* Keep fallback cipher synchronized */ 33768c2ecf20Sopenharmony_ci return crypto_aead_setkey(ctx->fback, (u8 *)key, len) ?: 33778c2ecf20Sopenharmony_ci safexcel_aead_setkey(ctfm, key, len); 33788c2ecf20Sopenharmony_ci} 33798c2ecf20Sopenharmony_ci 33808c2ecf20Sopenharmony_cistatic int safexcel_aead_fallback_setauthsize(struct crypto_aead *ctfm, 33818c2ecf20Sopenharmony_ci unsigned int authsize) 33828c2ecf20Sopenharmony_ci{ 33838c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 33848c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33858c2ecf20Sopenharmony_ci 33868c2ecf20Sopenharmony_ci /* Keep fallback cipher synchronized */ 33878c2ecf20Sopenharmony_ci return crypto_aead_setauthsize(ctx->fback, authsize); 33888c2ecf20Sopenharmony_ci} 33898c2ecf20Sopenharmony_ci 33908c2ecf20Sopenharmony_cistatic int safexcel_aead_fallback_crypt(struct aead_request *req, 33918c2ecf20Sopenharmony_ci enum safexcel_cipher_direction dir) 33928c2ecf20Sopenharmony_ci{ 33938c2ecf20Sopenharmony_ci struct crypto_aead *aead = crypto_aead_reqtfm(req); 33948c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(aead); 33958c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33968c2ecf20Sopenharmony_ci struct aead_request *subreq = aead_request_ctx(req); 33978c2ecf20Sopenharmony_ci 33988c2ecf20Sopenharmony_ci aead_request_set_tfm(subreq, ctx->fback); 33998c2ecf20Sopenharmony_ci aead_request_set_callback(subreq, req->base.flags, req->base.complete, 34008c2ecf20Sopenharmony_ci req->base.data); 34018c2ecf20Sopenharmony_ci aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 34028c2ecf20Sopenharmony_ci req->iv); 34038c2ecf20Sopenharmony_ci aead_request_set_ad(subreq, req->assoclen); 34048c2ecf20Sopenharmony_ci 34058c2ecf20Sopenharmony_ci return (dir == SAFEXCEL_ENCRYPT) ? 34068c2ecf20Sopenharmony_ci crypto_aead_encrypt(subreq) : 34078c2ecf20Sopenharmony_ci crypto_aead_decrypt(subreq); 34088c2ecf20Sopenharmony_ci} 34098c2ecf20Sopenharmony_ci 34108c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request *req) 34118c2ecf20Sopenharmony_ci{ 34128c2ecf20Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 34138c2ecf20Sopenharmony_ci 34148c2ecf20Sopenharmony_ci /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 34158c2ecf20Sopenharmony_ci if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 34168c2ecf20Sopenharmony_ci return -EINVAL; 34178c2ecf20Sopenharmony_ci else if (req->cryptlen || req->assoclen) /* If input length > 0 only */ 34188c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 34198c2ecf20Sopenharmony_ci 34208c2ecf20Sopenharmony_ci /* HW cannot do full (AAD+payload) zero length, use fallback */ 34218c2ecf20Sopenharmony_ci return safexcel_aead_fallback_crypt(req, SAFEXCEL_ENCRYPT); 34228c2ecf20Sopenharmony_ci} 34238c2ecf20Sopenharmony_ci 34248c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request *req) 34258c2ecf20Sopenharmony_ci{ 34268c2ecf20Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 34278c2ecf20Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 34288c2ecf20Sopenharmony_ci 34298c2ecf20Sopenharmony_ci /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 34308c2ecf20Sopenharmony_ci if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) 34318c2ecf20Sopenharmony_ci return -EINVAL; 34328c2ecf20Sopenharmony_ci else if (req->cryptlen > crypto_aead_authsize(tfm) || req->assoclen) 34338c2ecf20Sopenharmony_ci /* If input length > 0 only */ 34348c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 34358c2ecf20Sopenharmony_ci 34368c2ecf20Sopenharmony_ci /* HW cannot do full (AAD+payload) zero length, use fallback */ 34378c2ecf20Sopenharmony_ci return safexcel_aead_fallback_crypt(req, SAFEXCEL_DECRYPT); 34388c2ecf20Sopenharmony_ci} 34398c2ecf20Sopenharmony_ci 34408c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm *tfm) 34418c2ecf20Sopenharmony_ci{ 34428c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 34438c2ecf20Sopenharmony_ci 34448c2ecf20Sopenharmony_ci safexcel_aead_fallback_cra_init(tfm); 34458c2ecf20Sopenharmony_ci ctx->alg = SAFEXCEL_SM4; 34468c2ecf20Sopenharmony_ci ctx->blocksz = SM4_BLOCK_SIZE; 34478c2ecf20Sopenharmony_ci ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3; 34488c2ecf20Sopenharmony_ci ctx->state_sz = SM3_DIGEST_SIZE; 34498c2ecf20Sopenharmony_ci return 0; 34508c2ecf20Sopenharmony_ci} 34518c2ecf20Sopenharmony_ci 34528c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4 = { 34538c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 34548c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, 34558c2ecf20Sopenharmony_ci .alg.aead = { 34568c2ecf20Sopenharmony_ci .setkey = safexcel_aead_fallback_setkey, 34578c2ecf20Sopenharmony_ci .setauthsize = safexcel_aead_fallback_setauthsize, 34588c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_sm4cbc_sm3_encrypt, 34598c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_sm4cbc_sm3_decrypt, 34608c2ecf20Sopenharmony_ci .ivsize = SM4_BLOCK_SIZE, 34618c2ecf20Sopenharmony_ci .maxauthsize = SM3_DIGEST_SIZE, 34628c2ecf20Sopenharmony_ci .base = { 34638c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sm3),cbc(sm4))", 34648c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sm3-cbc-sm4", 34658c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 34668c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 34678c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 34688c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY | 34698c2ecf20Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK, 34708c2ecf20Sopenharmony_ci .cra_blocksize = SM4_BLOCK_SIZE, 34718c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 34728c2ecf20Sopenharmony_ci .cra_alignmask = 0, 34738c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sm4cbc_sm3_cra_init, 34748c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_fallback_cra_exit, 34758c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 34768c2ecf20Sopenharmony_ci }, 34778c2ecf20Sopenharmony_ci }, 34788c2ecf20Sopenharmony_ci}; 34798c2ecf20Sopenharmony_ci 34808c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm *tfm) 34818c2ecf20Sopenharmony_ci{ 34828c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 34838c2ecf20Sopenharmony_ci 34848c2ecf20Sopenharmony_ci safexcel_aead_sm4cbc_sha1_cra_init(tfm); 34858c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 34868c2ecf20Sopenharmony_ci return 0; 34878c2ecf20Sopenharmony_ci} 34888c2ecf20Sopenharmony_ci 34898c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4 = { 34908c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 34918c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, 34928c2ecf20Sopenharmony_ci .alg.aead = { 34938c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 34948c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 34958c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 34968c2ecf20Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 34978c2ecf20Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 34988c2ecf20Sopenharmony_ci .base = { 34998c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sha1),rfc3686(ctr(sm4)))", 35008c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-sm4", 35018c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 35028c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 35038c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 35048c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 35058c2ecf20Sopenharmony_ci .cra_blocksize = 1, 35068c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 35078c2ecf20Sopenharmony_ci .cra_alignmask = 0, 35088c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sm4ctr_sha1_cra_init, 35098c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 35108c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 35118c2ecf20Sopenharmony_ci }, 35128c2ecf20Sopenharmony_ci }, 35138c2ecf20Sopenharmony_ci}; 35148c2ecf20Sopenharmony_ci 35158c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm *tfm) 35168c2ecf20Sopenharmony_ci{ 35178c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 35188c2ecf20Sopenharmony_ci 35198c2ecf20Sopenharmony_ci safexcel_aead_sm4cbc_sm3_cra_init(tfm); 35208c2ecf20Sopenharmony_ci ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 35218c2ecf20Sopenharmony_ci return 0; 35228c2ecf20Sopenharmony_ci} 35238c2ecf20Sopenharmony_ci 35248c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4 = { 35258c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 35268c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, 35278c2ecf20Sopenharmony_ci .alg.aead = { 35288c2ecf20Sopenharmony_ci .setkey = safexcel_aead_setkey, 35298c2ecf20Sopenharmony_ci .encrypt = safexcel_aead_encrypt, 35308c2ecf20Sopenharmony_ci .decrypt = safexcel_aead_decrypt, 35318c2ecf20Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 35328c2ecf20Sopenharmony_ci .maxauthsize = SM3_DIGEST_SIZE, 35338c2ecf20Sopenharmony_ci .base = { 35348c2ecf20Sopenharmony_ci .cra_name = "authenc(hmac(sm3),rfc3686(ctr(sm4)))", 35358c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-authenc-hmac-sm3-ctr-sm4", 35368c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 35378c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 35388c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 35398c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 35408c2ecf20Sopenharmony_ci .cra_blocksize = 1, 35418c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 35428c2ecf20Sopenharmony_ci .cra_alignmask = 0, 35438c2ecf20Sopenharmony_ci .cra_init = safexcel_aead_sm4ctr_sm3_cra_init, 35448c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 35458c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 35468c2ecf20Sopenharmony_ci }, 35478c2ecf20Sopenharmony_ci }, 35488c2ecf20Sopenharmony_ci}; 35498c2ecf20Sopenharmony_ci 35508c2ecf20Sopenharmony_cistatic int safexcel_rfc4106_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, 35518c2ecf20Sopenharmony_ci unsigned int len) 35528c2ecf20Sopenharmony_ci{ 35538c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 35548c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 35558c2ecf20Sopenharmony_ci 35568c2ecf20Sopenharmony_ci /* last 4 bytes of key are the nonce! */ 35578c2ecf20Sopenharmony_ci ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 35588c2ecf20Sopenharmony_ci 35598c2ecf20Sopenharmony_ci len -= CTR_RFC3686_NONCE_SIZE; 35608c2ecf20Sopenharmony_ci return safexcel_aead_gcm_setkey(ctfm, key, len); 35618c2ecf20Sopenharmony_ci} 35628c2ecf20Sopenharmony_ci 35638c2ecf20Sopenharmony_cistatic int safexcel_rfc4106_gcm_setauthsize(struct crypto_aead *tfm, 35648c2ecf20Sopenharmony_ci unsigned int authsize) 35658c2ecf20Sopenharmony_ci{ 35668c2ecf20Sopenharmony_ci return crypto_rfc4106_check_authsize(authsize); 35678c2ecf20Sopenharmony_ci} 35688c2ecf20Sopenharmony_ci 35698c2ecf20Sopenharmony_cistatic int safexcel_rfc4106_encrypt(struct aead_request *req) 35708c2ecf20Sopenharmony_ci{ 35718c2ecf20Sopenharmony_ci return crypto_ipsec_check_assoclen(req->assoclen) ?: 35728c2ecf20Sopenharmony_ci safexcel_aead_encrypt(req); 35738c2ecf20Sopenharmony_ci} 35748c2ecf20Sopenharmony_ci 35758c2ecf20Sopenharmony_cistatic int safexcel_rfc4106_decrypt(struct aead_request *req) 35768c2ecf20Sopenharmony_ci{ 35778c2ecf20Sopenharmony_ci return crypto_ipsec_check_assoclen(req->assoclen) ?: 35788c2ecf20Sopenharmony_ci safexcel_aead_decrypt(req); 35798c2ecf20Sopenharmony_ci} 35808c2ecf20Sopenharmony_ci 35818c2ecf20Sopenharmony_cistatic int safexcel_rfc4106_gcm_cra_init(struct crypto_tfm *tfm) 35828c2ecf20Sopenharmony_ci{ 35838c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 35848c2ecf20Sopenharmony_ci int ret; 35858c2ecf20Sopenharmony_ci 35868c2ecf20Sopenharmony_ci ret = safexcel_aead_gcm_cra_init(tfm); 35878c2ecf20Sopenharmony_ci ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 35888c2ecf20Sopenharmony_ci ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 35898c2ecf20Sopenharmony_ci return ret; 35908c2ecf20Sopenharmony_ci} 35918c2ecf20Sopenharmony_ci 35928c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_rfc4106_gcm = { 35938c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 35948c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 35958c2ecf20Sopenharmony_ci .alg.aead = { 35968c2ecf20Sopenharmony_ci .setkey = safexcel_rfc4106_gcm_setkey, 35978c2ecf20Sopenharmony_ci .setauthsize = safexcel_rfc4106_gcm_setauthsize, 35988c2ecf20Sopenharmony_ci .encrypt = safexcel_rfc4106_encrypt, 35998c2ecf20Sopenharmony_ci .decrypt = safexcel_rfc4106_decrypt, 36008c2ecf20Sopenharmony_ci .ivsize = GCM_RFC4106_IV_SIZE, 36018c2ecf20Sopenharmony_ci .maxauthsize = GHASH_DIGEST_SIZE, 36028c2ecf20Sopenharmony_ci .base = { 36038c2ecf20Sopenharmony_ci .cra_name = "rfc4106(gcm(aes))", 36048c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-rfc4106-gcm-aes", 36058c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 36068c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 36078c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 36088c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 36098c2ecf20Sopenharmony_ci .cra_blocksize = 1, 36108c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 36118c2ecf20Sopenharmony_ci .cra_alignmask = 0, 36128c2ecf20Sopenharmony_ci .cra_init = safexcel_rfc4106_gcm_cra_init, 36138c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_gcm_cra_exit, 36148c2ecf20Sopenharmony_ci }, 36158c2ecf20Sopenharmony_ci }, 36168c2ecf20Sopenharmony_ci}; 36178c2ecf20Sopenharmony_ci 36188c2ecf20Sopenharmony_cistatic int safexcel_rfc4543_gcm_setauthsize(struct crypto_aead *tfm, 36198c2ecf20Sopenharmony_ci unsigned int authsize) 36208c2ecf20Sopenharmony_ci{ 36218c2ecf20Sopenharmony_ci if (authsize != GHASH_DIGEST_SIZE) 36228c2ecf20Sopenharmony_ci return -EINVAL; 36238c2ecf20Sopenharmony_ci 36248c2ecf20Sopenharmony_ci return 0; 36258c2ecf20Sopenharmony_ci} 36268c2ecf20Sopenharmony_ci 36278c2ecf20Sopenharmony_cistatic int safexcel_rfc4543_gcm_cra_init(struct crypto_tfm *tfm) 36288c2ecf20Sopenharmony_ci{ 36298c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 36308c2ecf20Sopenharmony_ci int ret; 36318c2ecf20Sopenharmony_ci 36328c2ecf20Sopenharmony_ci ret = safexcel_aead_gcm_cra_init(tfm); 36338c2ecf20Sopenharmony_ci ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP_GMAC; 36348c2ecf20Sopenharmony_ci return ret; 36358c2ecf20Sopenharmony_ci} 36368c2ecf20Sopenharmony_ci 36378c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_rfc4543_gcm = { 36388c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 36398c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 36408c2ecf20Sopenharmony_ci .alg.aead = { 36418c2ecf20Sopenharmony_ci .setkey = safexcel_rfc4106_gcm_setkey, 36428c2ecf20Sopenharmony_ci .setauthsize = safexcel_rfc4543_gcm_setauthsize, 36438c2ecf20Sopenharmony_ci .encrypt = safexcel_rfc4106_encrypt, 36448c2ecf20Sopenharmony_ci .decrypt = safexcel_rfc4106_decrypt, 36458c2ecf20Sopenharmony_ci .ivsize = GCM_RFC4543_IV_SIZE, 36468c2ecf20Sopenharmony_ci .maxauthsize = GHASH_DIGEST_SIZE, 36478c2ecf20Sopenharmony_ci .base = { 36488c2ecf20Sopenharmony_ci .cra_name = "rfc4543(gcm(aes))", 36498c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-rfc4543-gcm-aes", 36508c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 36518c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 36528c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 36538c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 36548c2ecf20Sopenharmony_ci .cra_blocksize = 1, 36558c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 36568c2ecf20Sopenharmony_ci .cra_alignmask = 0, 36578c2ecf20Sopenharmony_ci .cra_init = safexcel_rfc4543_gcm_cra_init, 36588c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_gcm_cra_exit, 36598c2ecf20Sopenharmony_ci }, 36608c2ecf20Sopenharmony_ci }, 36618c2ecf20Sopenharmony_ci}; 36628c2ecf20Sopenharmony_ci 36638c2ecf20Sopenharmony_cistatic int safexcel_rfc4309_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, 36648c2ecf20Sopenharmony_ci unsigned int len) 36658c2ecf20Sopenharmony_ci{ 36668c2ecf20Sopenharmony_ci struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 36678c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 36688c2ecf20Sopenharmony_ci 36698c2ecf20Sopenharmony_ci /* First byte of the nonce = L = always 3 for RFC4309 (4 byte ctr) */ 36708c2ecf20Sopenharmony_ci *(u8 *)&ctx->nonce = EIP197_AEAD_IPSEC_COUNTER_SIZE - 1; 36718c2ecf20Sopenharmony_ci /* last 3 bytes of key are the nonce! */ 36728c2ecf20Sopenharmony_ci memcpy((u8 *)&ctx->nonce + 1, key + len - 36738c2ecf20Sopenharmony_ci EIP197_AEAD_IPSEC_CCM_NONCE_SIZE, 36748c2ecf20Sopenharmony_ci EIP197_AEAD_IPSEC_CCM_NONCE_SIZE); 36758c2ecf20Sopenharmony_ci 36768c2ecf20Sopenharmony_ci len -= EIP197_AEAD_IPSEC_CCM_NONCE_SIZE; 36778c2ecf20Sopenharmony_ci return safexcel_aead_ccm_setkey(ctfm, key, len); 36788c2ecf20Sopenharmony_ci} 36798c2ecf20Sopenharmony_ci 36808c2ecf20Sopenharmony_cistatic int safexcel_rfc4309_ccm_setauthsize(struct crypto_aead *tfm, 36818c2ecf20Sopenharmony_ci unsigned int authsize) 36828c2ecf20Sopenharmony_ci{ 36838c2ecf20Sopenharmony_ci /* Borrowed from crypto/ccm.c */ 36848c2ecf20Sopenharmony_ci switch (authsize) { 36858c2ecf20Sopenharmony_ci case 8: 36868c2ecf20Sopenharmony_ci case 12: 36878c2ecf20Sopenharmony_ci case 16: 36888c2ecf20Sopenharmony_ci break; 36898c2ecf20Sopenharmony_ci default: 36908c2ecf20Sopenharmony_ci return -EINVAL; 36918c2ecf20Sopenharmony_ci } 36928c2ecf20Sopenharmony_ci 36938c2ecf20Sopenharmony_ci return 0; 36948c2ecf20Sopenharmony_ci} 36958c2ecf20Sopenharmony_ci 36968c2ecf20Sopenharmony_cistatic int safexcel_rfc4309_ccm_encrypt(struct aead_request *req) 36978c2ecf20Sopenharmony_ci{ 36988c2ecf20Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 36998c2ecf20Sopenharmony_ci 37008c2ecf20Sopenharmony_ci /* Borrowed from crypto/ccm.c */ 37018c2ecf20Sopenharmony_ci if (req->assoclen != 16 && req->assoclen != 20) 37028c2ecf20Sopenharmony_ci return -EINVAL; 37038c2ecf20Sopenharmony_ci 37048c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 37058c2ecf20Sopenharmony_ci} 37068c2ecf20Sopenharmony_ci 37078c2ecf20Sopenharmony_cistatic int safexcel_rfc4309_ccm_decrypt(struct aead_request *req) 37088c2ecf20Sopenharmony_ci{ 37098c2ecf20Sopenharmony_ci struct safexcel_cipher_req *creq = aead_request_ctx(req); 37108c2ecf20Sopenharmony_ci 37118c2ecf20Sopenharmony_ci /* Borrowed from crypto/ccm.c */ 37128c2ecf20Sopenharmony_ci if (req->assoclen != 16 && req->assoclen != 20) 37138c2ecf20Sopenharmony_ci return -EINVAL; 37148c2ecf20Sopenharmony_ci 37158c2ecf20Sopenharmony_ci return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 37168c2ecf20Sopenharmony_ci} 37178c2ecf20Sopenharmony_ci 37188c2ecf20Sopenharmony_cistatic int safexcel_rfc4309_ccm_cra_init(struct crypto_tfm *tfm) 37198c2ecf20Sopenharmony_ci{ 37208c2ecf20Sopenharmony_ci struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 37218c2ecf20Sopenharmony_ci int ret; 37228c2ecf20Sopenharmony_ci 37238c2ecf20Sopenharmony_ci ret = safexcel_aead_ccm_cra_init(tfm); 37248c2ecf20Sopenharmony_ci ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 37258c2ecf20Sopenharmony_ci ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 37268c2ecf20Sopenharmony_ci return ret; 37278c2ecf20Sopenharmony_ci} 37288c2ecf20Sopenharmony_ci 37298c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_rfc4309_ccm = { 37308c2ecf20Sopenharmony_ci .type = SAFEXCEL_ALG_TYPE_AEAD, 37318c2ecf20Sopenharmony_ci .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, 37328c2ecf20Sopenharmony_ci .alg.aead = { 37338c2ecf20Sopenharmony_ci .setkey = safexcel_rfc4309_ccm_setkey, 37348c2ecf20Sopenharmony_ci .setauthsize = safexcel_rfc4309_ccm_setauthsize, 37358c2ecf20Sopenharmony_ci .encrypt = safexcel_rfc4309_ccm_encrypt, 37368c2ecf20Sopenharmony_ci .decrypt = safexcel_rfc4309_ccm_decrypt, 37378c2ecf20Sopenharmony_ci .ivsize = EIP197_AEAD_IPSEC_IV_SIZE, 37388c2ecf20Sopenharmony_ci .maxauthsize = AES_BLOCK_SIZE, 37398c2ecf20Sopenharmony_ci .base = { 37408c2ecf20Sopenharmony_ci .cra_name = "rfc4309(ccm(aes))", 37418c2ecf20Sopenharmony_ci .cra_driver_name = "safexcel-rfc4309-ccm-aes", 37428c2ecf20Sopenharmony_ci .cra_priority = SAFEXCEL_CRA_PRIORITY, 37438c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_ASYNC | 37448c2ecf20Sopenharmony_ci CRYPTO_ALG_ALLOCATES_MEMORY | 37458c2ecf20Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY, 37468c2ecf20Sopenharmony_ci .cra_blocksize = 1, 37478c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 37488c2ecf20Sopenharmony_ci .cra_alignmask = 0, 37498c2ecf20Sopenharmony_ci .cra_init = safexcel_rfc4309_ccm_cra_init, 37508c2ecf20Sopenharmony_ci .cra_exit = safexcel_aead_cra_exit, 37518c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 37528c2ecf20Sopenharmony_ci }, 37538c2ecf20Sopenharmony_ci }, 37548c2ecf20Sopenharmony_ci}; 3755