1301422e3SAntoine Tenart // SPDX-License-Identifier: GPL-2.0 21b44c5a6SAntoine Ténart /* 31b44c5a6SAntoine Ténart * Copyright (C) 2017 Marvell 41b44c5a6SAntoine Ténart * 51b44c5a6SAntoine Ténart * Antoine Tenart <antoine.tenart@free-electrons.com> 61b44c5a6SAntoine Ténart */ 71b44c5a6SAntoine Ténart 84a593fb3SPascal van Leeuwen #include <asm/unaligned.h> 91b44c5a6SAntoine Ténart #include <linux/device.h> 101b44c5a6SAntoine Ténart #include <linux/dma-mapping.h> 111b44c5a6SAntoine Ténart #include <linux/dmapool.h> 12f6beaea3SAntoine Tenart #include <crypto/aead.h> 131b44c5a6SAntoine Ténart #include <crypto/aes.h> 14f6beaea3SAntoine Tenart #include <crypto/authenc.h> 154a593fb3SPascal van Leeuwen #include <crypto/chacha.h> 16f26882a3SPascal van Leeuwen #include <crypto/ctr.h> 1704007b0eSArd Biesheuvel #include <crypto/internal/des.h> 183e450886SPascal van Leeuwen #include <crypto/gcm.h> 193e450886SPascal van Leeuwen #include <crypto/ghash.h> 20a6061921SPascal van Leeuwen #include <crypto/poly1305.h> 21f6beaea3SAntoine Tenart #include <crypto/sha.h> 221769f704SPascal van Leeuwen #include <crypto/sm3.h> 23fcca797dSPascal van Leeuwen #include <crypto/sm4.h> 24c7da38a7SPascal van Leeuwen #include <crypto/xts.h> 251b44c5a6SAntoine Ténart #include <crypto/skcipher.h> 26f6beaea3SAntoine Tenart #include <crypto/internal/aead.h> 271eb7b403SOfer Heifetz #include <crypto/internal/skcipher.h> 281b44c5a6SAntoine Ténart 291b44c5a6SAntoine Ténart #include "safexcel.h" 301b44c5a6SAntoine Ténart 311b44c5a6SAntoine Ténart enum safexcel_cipher_direction { 321b44c5a6SAntoine Ténart SAFEXCEL_ENCRYPT, 331b44c5a6SAntoine Ténart SAFEXCEL_DECRYPT, 341b44c5a6SAntoine Ténart }; 351b44c5a6SAntoine Ténart 36a7dea8c0SOfer Heifetz enum safexcel_cipher_alg { 37a7dea8c0SOfer Heifetz SAFEXCEL_DES, 3862469879SOfer Heifetz SAFEXCEL_3DES, 39a7dea8c0SOfer Heifetz SAFEXCEL_AES, 404a593fb3SPascal van Leeuwen SAFEXCEL_CHACHA20, 41fcca797dSPascal van Leeuwen SAFEXCEL_SM4, 42a7dea8c0SOfer Heifetz }; 43a7dea8c0SOfer Heifetz 441b44c5a6SAntoine Ténart struct safexcel_cipher_ctx { 451b44c5a6SAntoine Ténart struct safexcel_context base; 461b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv; 471b44c5a6SAntoine Ténart 481b44c5a6SAntoine Ténart u32 mode; 49a7dea8c0SOfer Heifetz enum safexcel_cipher_alg alg; 5092c60cefSPascal van Leeuwen char aead; /* !=0=AEAD, 2=IPSec ESP AEAD, 3=IPsec ESP GMAC */ 51a6061921SPascal van Leeuwen char xcm; /* 0=authenc, 1=GCM, 2 reserved for CCM */ 521b44c5a6SAntoine Ténart 53c7da38a7SPascal van Leeuwen __le32 key[16]; 5454f9e8faSPascal van Leeuwen u32 nonce; 55c7da38a7SPascal van Leeuwen unsigned int key_len, xts; 56f6beaea3SAntoine Tenart 57f6beaea3SAntoine Tenart /* All the below is AEAD specific */ 58a7dea8c0SOfer Heifetz u32 hash_alg; 59f6beaea3SAntoine Tenart u32 state_sz; 6013a1bb93SPascal van Leeuwen __be32 ipad[SHA512_DIGEST_SIZE / sizeof(u32)]; 6113a1bb93SPascal van Leeuwen __be32 opad[SHA512_DIGEST_SIZE / sizeof(u32)]; 623e450886SPascal van Leeuwen 633e450886SPascal van Leeuwen struct crypto_cipher *hkaes; 64a6061921SPascal van Leeuwen struct crypto_aead *fback; 651b44c5a6SAntoine Ténart }; 661b44c5a6SAntoine Ténart 671eb7b403SOfer Heifetz struct safexcel_cipher_req { 68847ccfc5SOfer Heifetz enum safexcel_cipher_direction direction; 6989332590SAntoine Tenart /* Number of result descriptors associated to the request */ 7089332590SAntoine Tenart unsigned int rdescs; 711eb7b403SOfer Heifetz bool needs_inv; 7219b347b3SPascal van Leeuwen int nr_src, nr_dst; 731eb7b403SOfer Heifetz }; 741eb7b403SOfer Heifetz 750e17e362SPascal van Leeuwen static void safexcel_cipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 760e17e362SPascal van Leeuwen struct safexcel_command_desc *cdesc) 771b44c5a6SAntoine Ténart { 7854f9e8faSPascal van Leeuwen u32 block_sz = 0; 791b44c5a6SAntoine Ténart 80a19052d4SPascal van Leeuwen if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD || 8192c60cefSPascal van Leeuwen ctx->aead & EIP197_AEAD_TYPE_IPSEC_ESP) { /* _ESP and _ESP_GMAC */ 82493e289cSPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 83493e289cSPascal van Leeuwen 84493e289cSPascal van Leeuwen /* 32 bit nonce */ 85493e289cSPascal van Leeuwen cdesc->control_data.token[0] = ctx->nonce; 86493e289cSPascal van Leeuwen /* 64 bit IV part */ 87493e289cSPascal van Leeuwen memcpy(&cdesc->control_data.token[1], iv, 8); 88a19052d4SPascal van Leeuwen 89a9a89624SPascal van Leeuwen if (ctx->alg == SAFEXCEL_CHACHA20 || 90a9a89624SPascal van Leeuwen ctx->xcm == EIP197_XCM_MODE_CCM) { 91a19052d4SPascal van Leeuwen /* 32 bit counter, starting at 0 */ 92a19052d4SPascal van Leeuwen cdesc->control_data.token[3] = 0; 93a19052d4SPascal van Leeuwen } else { 94493e289cSPascal van Leeuwen /* 32 bit counter, start at 1 (big endian!) */ 9513a1bb93SPascal van Leeuwen cdesc->control_data.token[3] = 9613a1bb93SPascal van Leeuwen (__force u32)cpu_to_be32(1); 97a19052d4SPascal van Leeuwen } 98a19052d4SPascal van Leeuwen 99a19052d4SPascal van Leeuwen return; 100a19052d4SPascal van Leeuwen } else if (ctx->xcm == EIP197_XCM_MODE_GCM || 101a19052d4SPascal van Leeuwen (ctx->aead && ctx->alg == SAFEXCEL_CHACHA20)) { 102a19052d4SPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 103a19052d4SPascal van Leeuwen 104a19052d4SPascal van Leeuwen /* 96 bit IV part */ 105a19052d4SPascal van Leeuwen memcpy(&cdesc->control_data.token[0], iv, 12); 106a19052d4SPascal van Leeuwen 107a19052d4SPascal van Leeuwen if (ctx->alg == SAFEXCEL_CHACHA20) { 108a19052d4SPascal van Leeuwen /* 32 bit counter, starting at 0 */ 109a19052d4SPascal van Leeuwen cdesc->control_data.token[3] = 0; 110a19052d4SPascal van Leeuwen } else { 111a19052d4SPascal van Leeuwen /* 32 bit counter, start at 1 (big endian!) */ 11213a1bb93SPascal van Leeuwen *(__be32 *)&cdesc->control_data.token[3] = 11313a1bb93SPascal van Leeuwen cpu_to_be32(1); 114a19052d4SPascal van Leeuwen } 115493e289cSPascal van Leeuwen 116493e289cSPascal van Leeuwen return; 1174a593fb3SPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_CHACHA20) { 1184a593fb3SPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 1194a593fb3SPascal van Leeuwen 1204a593fb3SPascal van Leeuwen /* 96 bit nonce part */ 1214a593fb3SPascal van Leeuwen memcpy(&cdesc->control_data.token[0], &iv[4], 12); 1224a593fb3SPascal van Leeuwen /* 32 bit counter */ 1234a593fb3SPascal van Leeuwen cdesc->control_data.token[3] = *(u32 *)iv; 1243e450886SPascal van Leeuwen 1253e450886SPascal van Leeuwen return; 1264eb76fafSPascal van Leeuwen } else if (ctx->xcm == EIP197_XCM_MODE_CCM) { 1274eb76fafSPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 1284eb76fafSPascal van Leeuwen 1294eb76fafSPascal van Leeuwen /* Variable length IV part */ 1304eb76fafSPascal van Leeuwen memcpy(&cdesc->control_data.token[0], iv, 15 - iv[0]); 1314eb76fafSPascal van Leeuwen /* Start variable length counter at 0 */ 1324eb76fafSPascal van Leeuwen memset((u8 *)&cdesc->control_data.token[0] + 15 - iv[0], 1334eb76fafSPascal van Leeuwen 0, iv[0] + 1); 1344eb76fafSPascal van Leeuwen 1354eb76fafSPascal van Leeuwen return; 136493e289cSPascal van Leeuwen } 137493e289cSPascal van Leeuwen 13854f9e8faSPascal van Leeuwen if (ctx->mode != CONTEXT_CONTROL_CRYPTO_MODE_ECB) { 139a7dea8c0SOfer Heifetz switch (ctx->alg) { 140a7dea8c0SOfer Heifetz case SAFEXCEL_DES: 14157660b11SAntoine Tenart block_sz = DES_BLOCK_SIZE; 142a7dea8c0SOfer Heifetz cdesc->control_data.options |= EIP197_OPTION_2_TOKEN_IV_CMD; 143a7dea8c0SOfer Heifetz break; 14462469879SOfer Heifetz case SAFEXCEL_3DES: 14557660b11SAntoine Tenart block_sz = DES3_EDE_BLOCK_SIZE; 14662469879SOfer Heifetz cdesc->control_data.options |= EIP197_OPTION_2_TOKEN_IV_CMD; 14762469879SOfer Heifetz break; 148fcca797dSPascal van Leeuwen case SAFEXCEL_SM4: 149fcca797dSPascal van Leeuwen block_sz = SM4_BLOCK_SIZE; 150fcca797dSPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 151fcca797dSPascal van Leeuwen break; 152a7dea8c0SOfer Heifetz case SAFEXCEL_AES: 15357660b11SAntoine Tenart block_sz = AES_BLOCK_SIZE; 1541b44c5a6SAntoine Ténart cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 155a7dea8c0SOfer Heifetz break; 1564a593fb3SPascal van Leeuwen default: 1574a593fb3SPascal van Leeuwen break; 158a7dea8c0SOfer Heifetz } 15957660b11SAntoine Tenart memcpy(cdesc->control_data.token, iv, block_sz); 1601b44c5a6SAntoine Ténart } 16154f9e8faSPascal van Leeuwen } 1620e17e362SPascal van Leeuwen 1630e17e362SPascal van Leeuwen static void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 1640e17e362SPascal van Leeuwen struct safexcel_command_desc *cdesc, 1650e17e362SPascal van Leeuwen u32 length) 1660e17e362SPascal van Leeuwen { 1670e17e362SPascal van Leeuwen struct safexcel_token *token; 1680e17e362SPascal van Leeuwen 1690e17e362SPascal van Leeuwen safexcel_cipher_token(ctx, iv, cdesc); 1701b44c5a6SAntoine Ténart 17154f9e8faSPascal van Leeuwen /* skip over worst case IV of 4 dwords, no need to be exact */ 17254f9e8faSPascal van Leeuwen token = (struct safexcel_token *)(cdesc->control_data.token + 4); 1731b44c5a6SAntoine Ténart 1741b44c5a6SAntoine Ténart token[0].opcode = EIP197_TOKEN_OPCODE_DIRECTION; 1751b44c5a6SAntoine Ténart token[0].packet_length = length; 17615f64ee0SAntoine Tenart token[0].stat = EIP197_TOKEN_STAT_LAST_PACKET | 17715f64ee0SAntoine Tenart EIP197_TOKEN_STAT_LAST_HASH; 1781b44c5a6SAntoine Ténart token[0].instructions = EIP197_TOKEN_INS_LAST | 179a74d850fSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_CRYPTO | 1801b44c5a6SAntoine Ténart EIP197_TOKEN_INS_TYPE_OUTPUT; 1811b44c5a6SAntoine Ténart } 1821b44c5a6SAntoine Ténart 183f6beaea3SAntoine Tenart static void safexcel_aead_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 184f6beaea3SAntoine Tenart struct safexcel_command_desc *cdesc, 185f6beaea3SAntoine Tenart enum safexcel_cipher_direction direction, 186f6beaea3SAntoine Tenart u32 cryptlen, u32 assoclen, u32 digestsize) 187f6beaea3SAntoine Tenart { 188f6beaea3SAntoine Tenart struct safexcel_token *token; 189f6beaea3SAntoine Tenart 1900e17e362SPascal van Leeuwen safexcel_cipher_token(ctx, iv, cdesc); 191f6beaea3SAntoine Tenart 192f6beaea3SAntoine Tenart if (direction == SAFEXCEL_ENCRYPT) { 19354f9e8faSPascal van Leeuwen /* align end of instruction sequence to end of token */ 19454f9e8faSPascal van Leeuwen token = (struct safexcel_token *)(cdesc->control_data.token + 195a9a89624SPascal van Leeuwen EIP197_MAX_TOKENS - 14); 19654f9e8faSPascal van Leeuwen 197a9a89624SPascal van Leeuwen token[13].opcode = EIP197_TOKEN_OPCODE_INSERT; 198a9a89624SPascal van Leeuwen token[13].packet_length = digestsize; 199a9a89624SPascal van Leeuwen token[13].stat = EIP197_TOKEN_STAT_LAST_HASH | 200f6beaea3SAntoine Tenart EIP197_TOKEN_STAT_LAST_PACKET; 201a9a89624SPascal van Leeuwen token[13].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | 202f6beaea3SAntoine Tenart EIP197_TOKEN_INS_INSERT_HASH_DIGEST; 203f6beaea3SAntoine Tenart } else { 204d2d9e6fdSPascal van Leeuwen cryptlen -= digestsize; 205d2d9e6fdSPascal van Leeuwen 20654f9e8faSPascal van Leeuwen /* align end of instruction sequence to end of token */ 20754f9e8faSPascal van Leeuwen token = (struct safexcel_token *)(cdesc->control_data.token + 208a9a89624SPascal van Leeuwen EIP197_MAX_TOKENS - 15); 20954f9e8faSPascal van Leeuwen 210a9a89624SPascal van Leeuwen token[13].opcode = EIP197_TOKEN_OPCODE_RETRIEVE; 211a9a89624SPascal van Leeuwen token[13].packet_length = digestsize; 2124eb76fafSPascal van Leeuwen token[13].stat = EIP197_TOKEN_STAT_LAST_HASH | 213f6beaea3SAntoine Tenart EIP197_TOKEN_STAT_LAST_PACKET; 214a9a89624SPascal van Leeuwen token[13].instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST; 215a9a89624SPascal van Leeuwen 216a9a89624SPascal van Leeuwen token[14].opcode = EIP197_TOKEN_OPCODE_VERIFY; 217a9a89624SPascal van Leeuwen token[14].packet_length = digestsize | 218a9a89624SPascal van Leeuwen EIP197_TOKEN_HASH_RESULT_VERIFY; 219a9a89624SPascal van Leeuwen token[14].stat = EIP197_TOKEN_STAT_LAST_HASH | 220a9a89624SPascal van Leeuwen EIP197_TOKEN_STAT_LAST_PACKET; 221a9a89624SPascal van Leeuwen token[14].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT; 222f6beaea3SAntoine Tenart } 22354f9e8faSPascal van Leeuwen 224a6061921SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 22592c60cefSPascal van Leeuwen /* For ESP mode (and not GMAC), skip over the IV */ 226a9a89624SPascal van Leeuwen token[8].opcode = EIP197_TOKEN_OPCODE_DIRECTION; 227a9a89624SPascal van Leeuwen token[8].packet_length = EIP197_AEAD_IPSEC_IV_SIZE; 228a6061921SPascal van Leeuwen 229a6061921SPascal van Leeuwen assoclen -= EIP197_AEAD_IPSEC_IV_SIZE; 230a6061921SPascal van Leeuwen } 231a6061921SPascal van Leeuwen 2324eb76fafSPascal van Leeuwen token[6].opcode = EIP197_TOKEN_OPCODE_DIRECTION; 2334eb76fafSPascal van Leeuwen token[6].packet_length = assoclen; 234a6061921SPascal van Leeuwen token[6].instructions = EIP197_TOKEN_INS_LAST | 235a6061921SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH; 23654f9e8faSPascal van Leeuwen 237a6061921SPascal van Leeuwen if (likely(cryptlen || ctx->alg == SAFEXCEL_CHACHA20)) { 238a9a89624SPascal van Leeuwen token[11].opcode = EIP197_TOKEN_OPCODE_DIRECTION; 239a9a89624SPascal van Leeuwen token[11].packet_length = cryptlen; 240a9a89624SPascal van Leeuwen token[11].stat = EIP197_TOKEN_STAT_LAST_HASH; 24192c60cefSPascal van Leeuwen if (unlikely(ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) { 24292c60cefSPascal van Leeuwen token[6].instructions = EIP197_TOKEN_INS_TYPE_HASH; 24392c60cefSPascal van Leeuwen /* Do not send to crypt engine in case of GMAC */ 244a9a89624SPascal van Leeuwen token[11].instructions = EIP197_TOKEN_INS_LAST | 24592c60cefSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH | 24692c60cefSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_OUTPUT; 24792c60cefSPascal van Leeuwen } else { 248a9a89624SPascal van Leeuwen token[11].instructions = EIP197_TOKEN_INS_LAST | 24954f9e8faSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_CRYPTO | 25054f9e8faSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH | 25154f9e8faSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_OUTPUT; 25292c60cefSPascal van Leeuwen } 2534eb76fafSPascal van Leeuwen } else if (ctx->xcm != EIP197_XCM_MODE_CCM) { 2544eb76fafSPascal van Leeuwen token[6].stat = EIP197_TOKEN_STAT_LAST_HASH; 2550e17e362SPascal van Leeuwen } 2563e450886SPascal van Leeuwen 2574eb76fafSPascal van Leeuwen if (!ctx->xcm) 2584eb76fafSPascal van Leeuwen return; 2593e450886SPascal van Leeuwen 260a9a89624SPascal van Leeuwen token[9].opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES; 261a9a89624SPascal van Leeuwen token[9].packet_length = 0; 262a9a89624SPascal van Leeuwen token[9].instructions = AES_BLOCK_SIZE; 2633e450886SPascal van Leeuwen 264a9a89624SPascal van Leeuwen token[10].opcode = EIP197_TOKEN_OPCODE_INSERT; 265a9a89624SPascal van Leeuwen token[10].packet_length = AES_BLOCK_SIZE; 266a9a89624SPascal van Leeuwen token[10].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | 2673e450886SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_CRYPTO; 2684eb76fafSPascal van Leeuwen 269a6061921SPascal van Leeuwen if (ctx->xcm != EIP197_XCM_MODE_GCM) { 270a9a89624SPascal van Leeuwen u8 *final_iv = (u8 *)cdesc->control_data.token; 2714eb76fafSPascal van Leeuwen u8 *cbcmaciv = (u8 *)&token[1]; 27213a1bb93SPascal van Leeuwen __le32 *aadlen = (__le32 *)&token[5]; 2734eb76fafSPascal van Leeuwen 2744eb76fafSPascal van Leeuwen /* Construct IV block B0 for the CBC-MAC */ 2754eb76fafSPascal van Leeuwen token[0].opcode = EIP197_TOKEN_OPCODE_INSERT; 2764eb76fafSPascal van Leeuwen token[0].packet_length = AES_BLOCK_SIZE + 2774eb76fafSPascal van Leeuwen ((assoclen > 0) << 1); 2784eb76fafSPascal van Leeuwen token[0].instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN | 2794eb76fafSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH; 2804eb76fafSPascal van Leeuwen /* Variable length IV part */ 281a9a89624SPascal van Leeuwen memcpy(cbcmaciv, final_iv, 15 - final_iv[0]); 2824eb76fafSPascal van Leeuwen /* fixup flags byte */ 2834eb76fafSPascal van Leeuwen cbcmaciv[0] |= ((assoclen > 0) << 6) | ((digestsize - 2) << 2); 2844eb76fafSPascal van Leeuwen /* Clear upper bytes of variable message length to 0 */ 285a9a89624SPascal van Leeuwen memset(cbcmaciv + 15 - final_iv[0], 0, final_iv[0] - 1); 2864eb76fafSPascal van Leeuwen /* insert lower 2 bytes of message length */ 2874eb76fafSPascal van Leeuwen cbcmaciv[14] = cryptlen >> 8; 2884eb76fafSPascal van Leeuwen cbcmaciv[15] = cryptlen & 255; 2894eb76fafSPascal van Leeuwen 2904eb76fafSPascal van Leeuwen if (assoclen) { 29113a1bb93SPascal van Leeuwen *aadlen = cpu_to_le32((assoclen >> 8) | 29213a1bb93SPascal van Leeuwen ((assoclen & 0xff) << 8)); 2934eb76fafSPascal van Leeuwen assoclen += 2; 2944eb76fafSPascal van Leeuwen } 2954eb76fafSPascal van Leeuwen 2964eb76fafSPascal van Leeuwen token[6].instructions = EIP197_TOKEN_INS_TYPE_HASH; 2974eb76fafSPascal van Leeuwen 2984eb76fafSPascal van Leeuwen /* Align AAD data towards hash engine */ 2994eb76fafSPascal van Leeuwen token[7].opcode = EIP197_TOKEN_OPCODE_INSERT; 3004eb76fafSPascal van Leeuwen assoclen &= 15; 3014eb76fafSPascal van Leeuwen token[7].packet_length = assoclen ? 16 - assoclen : 0; 3024eb76fafSPascal van Leeuwen 3034eb76fafSPascal van Leeuwen if (likely(cryptlen)) { 3044eb76fafSPascal van Leeuwen token[7].instructions = EIP197_TOKEN_INS_TYPE_HASH; 3054eb76fafSPascal van Leeuwen 3064eb76fafSPascal van Leeuwen /* Align crypto data towards hash engine */ 307a9a89624SPascal van Leeuwen token[11].stat = 0; 3084eb76fafSPascal van Leeuwen 309a9a89624SPascal van Leeuwen token[12].opcode = EIP197_TOKEN_OPCODE_INSERT; 3104eb76fafSPascal van Leeuwen cryptlen &= 15; 311a9a89624SPascal van Leeuwen token[12].packet_length = cryptlen ? 16 - cryptlen : 0; 312a9a89624SPascal van Leeuwen token[12].stat = EIP197_TOKEN_STAT_LAST_HASH; 313a9a89624SPascal van Leeuwen token[12].instructions = EIP197_TOKEN_INS_TYPE_HASH; 3144eb76fafSPascal van Leeuwen } else { 3154eb76fafSPascal van Leeuwen token[7].stat = EIP197_TOKEN_STAT_LAST_HASH; 3164eb76fafSPascal van Leeuwen token[7].instructions = EIP197_TOKEN_INS_LAST | 3174eb76fafSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH; 3184eb76fafSPascal van Leeuwen } 3193e450886SPascal van Leeuwen } 320f6beaea3SAntoine Tenart } 321f6beaea3SAntoine Tenart 3228ac1283eSAntoine Tenart static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm, 3238ac1283eSAntoine Tenart const u8 *key, unsigned int len) 3241b44c5a6SAntoine Ténart { 3251b44c5a6SAntoine Ténart struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 3261b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 327871df319SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 3281b44c5a6SAntoine Ténart struct crypto_aes_ctx aes; 3291b44c5a6SAntoine Ténart int ret, i; 3301b44c5a6SAntoine Ténart 331363a90c2SArd Biesheuvel ret = aes_expandkey(&aes, key, len); 3321b44c5a6SAntoine Ténart if (ret) { 3331b44c5a6SAntoine Ténart crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 3341b44c5a6SAntoine Ténart return ret; 3351b44c5a6SAntoine Ténart } 3361b44c5a6SAntoine Ténart 33753c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 3381b44c5a6SAntoine Ténart for (i = 0; i < len / sizeof(u32); i++) { 33913a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 3401b44c5a6SAntoine Ténart ctx->base.needs_inv = true; 3411b44c5a6SAntoine Ténart break; 3421b44c5a6SAntoine Ténart } 3431b44c5a6SAntoine Ténart } 344c4daf4ccSOfer Heifetz } 3451b44c5a6SAntoine Ténart 3461b44c5a6SAntoine Ténart for (i = 0; i < len / sizeof(u32); i++) 3471b44c5a6SAntoine Ténart ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 3481b44c5a6SAntoine Ténart 3491b44c5a6SAntoine Ténart ctx->key_len = len; 3501b44c5a6SAntoine Ténart 3511b44c5a6SAntoine Ténart memzero_explicit(&aes, sizeof(aes)); 3521b44c5a6SAntoine Ténart return 0; 3531b44c5a6SAntoine Ténart } 3541b44c5a6SAntoine Ténart 35577cdd4efSPascal van Leeuwen static int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key, 356f6beaea3SAntoine Tenart unsigned int len) 357f6beaea3SAntoine Tenart { 358f6beaea3SAntoine Tenart struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 359f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 360f6beaea3SAntoine Tenart struct safexcel_ahash_export_state istate, ostate; 361f6beaea3SAntoine Tenart struct safexcel_crypto_priv *priv = ctx->priv; 362f6beaea3SAntoine Tenart struct crypto_authenc_keys keys; 3630e17e362SPascal van Leeuwen struct crypto_aes_ctx aes; 36413a1bb93SPascal van Leeuwen int err = -EINVAL, i; 365f6beaea3SAntoine Tenart 3661769f704SPascal van Leeuwen if (unlikely(crypto_authenc_extractkeys(&keys, key, len))) 367f6beaea3SAntoine Tenart goto badkey; 368f6beaea3SAntoine Tenart 3690e17e362SPascal van Leeuwen if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { 3701769f704SPascal van Leeuwen /* Must have at least space for the nonce here */ 3711769f704SPascal van Leeuwen if (unlikely(keys.enckeylen < CTR_RFC3686_NONCE_SIZE)) 372f6beaea3SAntoine Tenart goto badkey; 3730e17e362SPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 374f26882a3SPascal van Leeuwen ctx->nonce = *(u32 *)(keys.enckey + keys.enckeylen - 375f26882a3SPascal van Leeuwen CTR_RFC3686_NONCE_SIZE); 3760e17e362SPascal van Leeuwen /* exclude the nonce here */ 3771769f704SPascal van Leeuwen keys.enckeylen -= CTR_RFC3686_NONCE_SIZE; 3780e17e362SPascal van Leeuwen } 379f6beaea3SAntoine Tenart 380f6beaea3SAntoine Tenart /* Encryption key */ 3810e17e362SPascal van Leeuwen switch (ctx->alg) { 382bb7679b8SPascal van Leeuwen case SAFEXCEL_DES: 383bb7679b8SPascal van Leeuwen err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen); 384bb7679b8SPascal van Leeuwen if (unlikely(err)) 385bb7679b8SPascal van Leeuwen goto badkey_expflags; 386bb7679b8SPascal van Leeuwen break; 3870e17e362SPascal van Leeuwen case SAFEXCEL_3DES: 38821f5a15eSArd Biesheuvel err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen); 38977cdd4efSPascal van Leeuwen if (unlikely(err)) 3900e17e362SPascal van Leeuwen goto badkey_expflags; 3910e17e362SPascal van Leeuwen break; 3920e17e362SPascal van Leeuwen case SAFEXCEL_AES: 3930e17e362SPascal van Leeuwen err = aes_expandkey(&aes, keys.enckey, keys.enckeylen); 3940e17e362SPascal van Leeuwen if (unlikely(err)) 3950e17e362SPascal van Leeuwen goto badkey; 3960e17e362SPascal van Leeuwen break; 3971769f704SPascal van Leeuwen case SAFEXCEL_SM4: 3981769f704SPascal van Leeuwen if (unlikely(keys.enckeylen != SM4_KEY_SIZE)) 3991769f704SPascal van Leeuwen goto badkey; 4001769f704SPascal van Leeuwen break; 4010e17e362SPascal van Leeuwen default: 4020e17e362SPascal van Leeuwen dev_err(priv->dev, "aead: unsupported cipher algorithm\n"); 4030e17e362SPascal van Leeuwen goto badkey; 40477cdd4efSPascal van Leeuwen } 40577cdd4efSPascal van Leeuwen 40613a1bb93SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 40713a1bb93SPascal van Leeuwen for (i = 0; i < keys.enckeylen / sizeof(u32); i++) { 40813a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 409f6beaea3SAntoine Tenart ctx->base.needs_inv = true; 41013a1bb93SPascal van Leeuwen break; 41113a1bb93SPascal van Leeuwen } 41213a1bb93SPascal van Leeuwen } 41313a1bb93SPascal van Leeuwen } 414f6beaea3SAntoine Tenart 415f6beaea3SAntoine Tenart /* Auth key */ 416a7dea8c0SOfer Heifetz switch (ctx->hash_alg) { 41701ba061dSAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA1: 41801ba061dSAntoine Tenart if (safexcel_hmac_setkey("safexcel-sha1", keys.authkey, 41901ba061dSAntoine Tenart keys.authkeylen, &istate, &ostate)) 42001ba061dSAntoine Tenart goto badkey; 42101ba061dSAntoine Tenart break; 422678b2878SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA224: 423678b2878SAntoine Tenart if (safexcel_hmac_setkey("safexcel-sha224", keys.authkey, 424678b2878SAntoine Tenart keys.authkeylen, &istate, &ostate)) 425678b2878SAntoine Tenart goto badkey; 426678b2878SAntoine Tenart break; 427678b2878SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA256: 428f6beaea3SAntoine Tenart if (safexcel_hmac_setkey("safexcel-sha256", keys.authkey, 429f6beaea3SAntoine Tenart keys.authkeylen, &istate, &ostate)) 430f6beaea3SAntoine Tenart goto badkey; 431678b2878SAntoine Tenart break; 432ea23cb53SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA384: 433ea23cb53SAntoine Tenart if (safexcel_hmac_setkey("safexcel-sha384", keys.authkey, 434ea23cb53SAntoine Tenart keys.authkeylen, &istate, &ostate)) 435ea23cb53SAntoine Tenart goto badkey; 436ea23cb53SAntoine Tenart break; 43787eee125SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA512: 43887eee125SAntoine Tenart if (safexcel_hmac_setkey("safexcel-sha512", keys.authkey, 43987eee125SAntoine Tenart keys.authkeylen, &istate, &ostate)) 44087eee125SAntoine Tenart goto badkey; 44187eee125SAntoine Tenart break; 4421769f704SPascal van Leeuwen case CONTEXT_CONTROL_CRYPTO_ALG_SM3: 4431769f704SPascal van Leeuwen if (safexcel_hmac_setkey("safexcel-sm3", keys.authkey, 4441769f704SPascal van Leeuwen keys.authkeylen, &istate, &ostate)) 4451769f704SPascal van Leeuwen goto badkey; 4461769f704SPascal van Leeuwen break; 447678b2878SAntoine Tenart default: 4481a61af28SColin Ian King dev_err(priv->dev, "aead: unsupported hash algorithm\n"); 449678b2878SAntoine Tenart goto badkey; 450678b2878SAntoine Tenart } 451f6beaea3SAntoine Tenart 452f6beaea3SAntoine Tenart crypto_aead_set_flags(ctfm, crypto_aead_get_flags(ctfm) & 453f6beaea3SAntoine Tenart CRYPTO_TFM_RES_MASK); 454f6beaea3SAntoine Tenart 45553c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma && 456f6beaea3SAntoine Tenart (memcmp(ctx->ipad, istate.state, ctx->state_sz) || 457f6beaea3SAntoine Tenart memcmp(ctx->opad, ostate.state, ctx->state_sz))) 458f6beaea3SAntoine Tenart ctx->base.needs_inv = true; 459f6beaea3SAntoine Tenart 460f6beaea3SAntoine Tenart /* Now copy the keys into the context */ 46113a1bb93SPascal van Leeuwen for (i = 0; i < keys.enckeylen / sizeof(u32); i++) 46213a1bb93SPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 463f6beaea3SAntoine Tenart ctx->key_len = keys.enckeylen; 464f6beaea3SAntoine Tenart 465f6beaea3SAntoine Tenart memcpy(ctx->ipad, &istate.state, ctx->state_sz); 466f6beaea3SAntoine Tenart memcpy(ctx->opad, &ostate.state, ctx->state_sz); 467f6beaea3SAntoine Tenart 468f6beaea3SAntoine Tenart memzero_explicit(&keys, sizeof(keys)); 469f6beaea3SAntoine Tenart return 0; 470f6beaea3SAntoine Tenart 471f6beaea3SAntoine Tenart badkey: 472f6beaea3SAntoine Tenart crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 4730e17e362SPascal van Leeuwen badkey_expflags: 474f6beaea3SAntoine Tenart memzero_explicit(&keys, sizeof(keys)); 4750e17e362SPascal van Leeuwen return err; 476f6beaea3SAntoine Tenart } 477f6beaea3SAntoine Tenart 4781b44c5a6SAntoine Ténart static int safexcel_context_control(struct safexcel_cipher_ctx *ctx, 479847ccfc5SOfer Heifetz struct crypto_async_request *async, 4808ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 4811b44c5a6SAntoine Ténart struct safexcel_command_desc *cdesc) 4821b44c5a6SAntoine Ténart { 4831b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 484d2d9e6fdSPascal van Leeuwen int ctrl_size = ctx->key_len / sizeof(u32); 485d2d9e6fdSPascal van Leeuwen 486d2d9e6fdSPascal van Leeuwen cdesc->control_data.control1 = ctx->mode; 4871b44c5a6SAntoine Ténart 488f6beaea3SAntoine Tenart if (ctx->aead) { 489d2d9e6fdSPascal van Leeuwen /* Take in account the ipad+opad digests */ 4903e450886SPascal van Leeuwen if (ctx->xcm) { 4913e450886SPascal van Leeuwen ctrl_size += ctx->state_sz / sizeof(u32); 4923e450886SPascal van Leeuwen cdesc->control_data.control0 = 4933e450886SPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 4943e450886SPascal van Leeuwen CONTEXT_CONTROL_DIGEST_XCM | 4953e450886SPascal van Leeuwen ctx->hash_alg | 4963e450886SPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 497a6061921SPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_CHACHA20) { 498a6061921SPascal van Leeuwen /* Chacha20-Poly1305 */ 499a6061921SPascal van Leeuwen cdesc->control_data.control0 = 500a6061921SPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 501a6061921SPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 | 502a6061921SPascal van Leeuwen (sreq->direction == SAFEXCEL_ENCRYPT ? 503a6061921SPascal van Leeuwen CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT : 504a6061921SPascal van Leeuwen CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN) | 505a6061921SPascal van Leeuwen ctx->hash_alg | 506a6061921SPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 507a6061921SPascal van Leeuwen return 0; 5083e450886SPascal van Leeuwen } else { 509d2d9e6fdSPascal van Leeuwen ctrl_size += ctx->state_sz / sizeof(u32) * 2; 5103e450886SPascal van Leeuwen cdesc->control_data.control0 = 5113e450886SPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 5123e450886SPascal van Leeuwen CONTEXT_CONTROL_DIGEST_HMAC | 5133e450886SPascal van Leeuwen ctx->hash_alg | 5143e450886SPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 5153e450886SPascal van Leeuwen } 5164eb76fafSPascal van Leeuwen 51792c60cefSPascal van Leeuwen if (sreq->direction == SAFEXCEL_ENCRYPT && 51892c60cefSPascal van Leeuwen (ctx->xcm == EIP197_XCM_MODE_CCM || 51992c60cefSPascal van Leeuwen ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) 52092c60cefSPascal van Leeuwen cdesc->control_data.control0 |= 52192c60cefSPascal van Leeuwen CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT; 52292c60cefSPascal van Leeuwen else if (sreq->direction == SAFEXCEL_ENCRYPT) 52392c60cefSPascal van Leeuwen cdesc->control_data.control0 |= 52492c60cefSPascal van Leeuwen CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT; 52592c60cefSPascal van Leeuwen else if (ctx->xcm == EIP197_XCM_MODE_CCM) 52692c60cefSPascal van Leeuwen cdesc->control_data.control0 |= 52792c60cefSPascal van Leeuwen CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN; 528d2d9e6fdSPascal van Leeuwen else 5293e450886SPascal van Leeuwen cdesc->control_data.control0 |= 5303e450886SPascal van Leeuwen CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN; 531d2d9e6fdSPascal van Leeuwen } else { 532d2d9e6fdSPascal van Leeuwen if (sreq->direction == SAFEXCEL_ENCRYPT) 533d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 = 534d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_TYPE_CRYPTO_OUT | 535d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 536d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 537d2d9e6fdSPascal van Leeuwen else 538d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 = 539d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_TYPE_CRYPTO_IN | 540d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 541d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 542f6beaea3SAntoine Tenart } 5431b44c5a6SAntoine Ténart 544a7dea8c0SOfer Heifetz if (ctx->alg == SAFEXCEL_DES) { 545d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 546d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_DES; 54762469879SOfer Heifetz } else if (ctx->alg == SAFEXCEL_3DES) { 548d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 549d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_3DES; 550a7dea8c0SOfer Heifetz } else if (ctx->alg == SAFEXCEL_AES) { 551c7da38a7SPascal van Leeuwen switch (ctx->key_len >> ctx->xts) { 5521b44c5a6SAntoine Ténart case AES_KEYSIZE_128: 553d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 554d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_AES128; 5551b44c5a6SAntoine Ténart break; 5561b44c5a6SAntoine Ténart case AES_KEYSIZE_192: 557d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 558d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_AES192; 5591b44c5a6SAntoine Ténart break; 5601b44c5a6SAntoine Ténart case AES_KEYSIZE_256: 561d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 562d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_AES256; 5631b44c5a6SAntoine Ténart break; 5641b44c5a6SAntoine Ténart default: 5651b44c5a6SAntoine Ténart dev_err(priv->dev, "aes keysize not supported: %u\n", 566c7da38a7SPascal van Leeuwen ctx->key_len >> ctx->xts); 5671b44c5a6SAntoine Ténart return -EINVAL; 5681b44c5a6SAntoine Ténart } 5694a593fb3SPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_CHACHA20) { 5704a593fb3SPascal van Leeuwen cdesc->control_data.control0 |= 5714a593fb3SPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20; 572fcca797dSPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_SM4) { 573fcca797dSPascal van Leeuwen cdesc->control_data.control0 |= 574fcca797dSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_SM4; 575a7dea8c0SOfer Heifetz } 576fef0cfe5SAntoine Tenart 5771b44c5a6SAntoine Ténart return 0; 5781b44c5a6SAntoine Ténart } 5791b44c5a6SAntoine Ténart 5801eb7b403SOfer Heifetz static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring, 5811b44c5a6SAntoine Ténart struct crypto_async_request *async, 5828ac1283eSAntoine Tenart struct scatterlist *src, 5838ac1283eSAntoine Tenart struct scatterlist *dst, 5848ac1283eSAntoine Tenart unsigned int cryptlen, 5858ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 5861b44c5a6SAntoine Ténart bool *should_complete, int *ret) 5871b44c5a6SAntoine Ténart { 5885bdb6e6aSPascal van Leeuwen struct skcipher_request *areq = skcipher_request_cast(async); 5895bdb6e6aSPascal van Leeuwen struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq); 5905bdb6e6aSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(skcipher); 5911b44c5a6SAntoine Ténart struct safexcel_result_desc *rdesc; 5921b44c5a6SAntoine Ténart int ndesc = 0; 5931b44c5a6SAntoine Ténart 5941b44c5a6SAntoine Ténart *ret = 0; 5951b44c5a6SAntoine Ténart 59689332590SAntoine Tenart if (unlikely(!sreq->rdescs)) 59789332590SAntoine Tenart return 0; 59889332590SAntoine Tenart 59989332590SAntoine Tenart while (sreq->rdescs--) { 6001b44c5a6SAntoine Ténart rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr); 6011b44c5a6SAntoine Ténart if (IS_ERR(rdesc)) { 6021b44c5a6SAntoine Ténart dev_err(priv->dev, 6031b44c5a6SAntoine Ténart "cipher: result: could not retrieve the result descriptor\n"); 6041b44c5a6SAntoine Ténart *ret = PTR_ERR(rdesc); 6051b44c5a6SAntoine Ténart break; 6061b44c5a6SAntoine Ténart } 6071b44c5a6SAntoine Ténart 608bdfd1909SAntoine Tenart if (likely(!*ret)) 609bdfd1909SAntoine Tenart *ret = safexcel_rdesc_check_errors(priv, rdesc); 6101b44c5a6SAntoine Ténart 6111b44c5a6SAntoine Ténart ndesc++; 61289332590SAntoine Tenart } 6131b44c5a6SAntoine Ténart 6141b44c5a6SAntoine Ténart safexcel_complete(priv, ring); 6151b44c5a6SAntoine Ténart 6168ac1283eSAntoine Tenart if (src == dst) { 61719b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL); 6181b44c5a6SAntoine Ténart } else { 61919b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 62019b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE); 6211b44c5a6SAntoine Ténart } 6221b44c5a6SAntoine Ténart 6235bdb6e6aSPascal van Leeuwen /* 6245bdb6e6aSPascal van Leeuwen * Update IV in req from last crypto output word for CBC modes 6255bdb6e6aSPascal van Leeuwen */ 6265bdb6e6aSPascal van Leeuwen if ((!ctx->aead) && (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) && 6275bdb6e6aSPascal van Leeuwen (sreq->direction == SAFEXCEL_ENCRYPT)) { 6285bdb6e6aSPascal van Leeuwen /* For encrypt take the last output word */ 62919b347b3SPascal van Leeuwen sg_pcopy_to_buffer(dst, sreq->nr_dst, areq->iv, 6305bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher), 6315bdb6e6aSPascal van Leeuwen (cryptlen - 6325bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher))); 6335bdb6e6aSPascal van Leeuwen } 6345bdb6e6aSPascal van Leeuwen 6351b44c5a6SAntoine Ténart *should_complete = true; 6361b44c5a6SAntoine Ténart 6371b44c5a6SAntoine Ténart return ndesc; 6381b44c5a6SAntoine Ténart } 6391b44c5a6SAntoine Ténart 640a7dea8c0SOfer Heifetz static int safexcel_send_req(struct crypto_async_request *base, int ring, 6418ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 6428ac1283eSAntoine Tenart struct scatterlist *src, struct scatterlist *dst, 643f6beaea3SAntoine Tenart unsigned int cryptlen, unsigned int assoclen, 644f6beaea3SAntoine Tenart unsigned int digestsize, u8 *iv, int *commands, 6458ac1283eSAntoine Tenart int *results) 6461b44c5a6SAntoine Ténart { 6475bdb6e6aSPascal van Leeuwen struct skcipher_request *areq = skcipher_request_cast(base); 6485bdb6e6aSPascal van Leeuwen struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq); 6498ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 6501b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 6511b44c5a6SAntoine Ténart struct safexcel_command_desc *cdesc; 65219b347b3SPascal van Leeuwen struct safexcel_command_desc *first_cdesc = NULL; 653e5c8ee1fSAntoine Tenart struct safexcel_result_desc *rdesc, *first_rdesc = NULL; 6541b44c5a6SAntoine Ténart struct scatterlist *sg; 65519b347b3SPascal van Leeuwen unsigned int totlen; 65619b347b3SPascal van Leeuwen unsigned int totlen_src = cryptlen + assoclen; 65719b347b3SPascal van Leeuwen unsigned int totlen_dst = totlen_src; 65819b347b3SPascal van Leeuwen int n_cdesc = 0, n_rdesc = 0; 65919b347b3SPascal van Leeuwen int queued, i, ret = 0; 66019b347b3SPascal van Leeuwen bool first = true; 6611b44c5a6SAntoine Ténart 66219b347b3SPascal van Leeuwen sreq->nr_src = sg_nents_for_len(src, totlen_src); 66319b347b3SPascal van Leeuwen 66419b347b3SPascal van Leeuwen if (ctx->aead) { 66519b347b3SPascal van Leeuwen /* 66619b347b3SPascal van Leeuwen * AEAD has auth tag appended to output for encrypt and 66719b347b3SPascal van Leeuwen * removed from the output for decrypt! 66819b347b3SPascal van Leeuwen */ 66919b347b3SPascal van Leeuwen if (sreq->direction == SAFEXCEL_DECRYPT) 67019b347b3SPascal van Leeuwen totlen_dst -= digestsize; 67119b347b3SPascal van Leeuwen else 67219b347b3SPascal van Leeuwen totlen_dst += digestsize; 67319b347b3SPascal van Leeuwen 67419b347b3SPascal van Leeuwen memcpy(ctx->base.ctxr->data + ctx->key_len / sizeof(u32), 67519b347b3SPascal van Leeuwen ctx->ipad, ctx->state_sz); 6763e450886SPascal van Leeuwen if (!ctx->xcm) 6773e450886SPascal van Leeuwen memcpy(ctx->base.ctxr->data + (ctx->key_len + 6783e450886SPascal van Leeuwen ctx->state_sz) / sizeof(u32), ctx->opad, 6793e450886SPascal van Leeuwen ctx->state_sz); 68019b347b3SPascal van Leeuwen } else if ((ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) && 6815bdb6e6aSPascal van Leeuwen (sreq->direction == SAFEXCEL_DECRYPT)) { 6825bdb6e6aSPascal van Leeuwen /* 6835bdb6e6aSPascal van Leeuwen * Save IV from last crypto input word for CBC modes in decrypt 6845bdb6e6aSPascal van Leeuwen * direction. Need to do this first in case of inplace operation 6855bdb6e6aSPascal van Leeuwen * as it will be overwritten. 6865bdb6e6aSPascal van Leeuwen */ 68719b347b3SPascal van Leeuwen sg_pcopy_to_buffer(src, sreq->nr_src, areq->iv, 6885bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher), 68919b347b3SPascal van Leeuwen (totlen_src - 6905bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher))); 6915bdb6e6aSPascal van Leeuwen } 6925bdb6e6aSPascal van Leeuwen 69319b347b3SPascal van Leeuwen sreq->nr_dst = sg_nents_for_len(dst, totlen_dst); 6941b44c5a6SAntoine Ténart 69519b347b3SPascal van Leeuwen /* 69619b347b3SPascal van Leeuwen * Remember actual input length, source buffer length may be 69719b347b3SPascal van Leeuwen * updated in case of inline operation below. 69819b347b3SPascal van Leeuwen */ 69919b347b3SPascal van Leeuwen totlen = totlen_src; 70019b347b3SPascal van Leeuwen queued = totlen_src; 70119b347b3SPascal van Leeuwen 70219b347b3SPascal van Leeuwen if (src == dst) { 70319b347b3SPascal van Leeuwen sreq->nr_src = max(sreq->nr_src, sreq->nr_dst); 70419b347b3SPascal van Leeuwen sreq->nr_dst = sreq->nr_src; 70519b347b3SPascal van Leeuwen if (unlikely((totlen_src || totlen_dst) && 70619b347b3SPascal van Leeuwen (sreq->nr_src <= 0))) { 70719b347b3SPascal van Leeuwen dev_err(priv->dev, "In-place buffer not large enough (need %d bytes)!", 70819b347b3SPascal van Leeuwen max(totlen_src, totlen_dst)); 7091b44c5a6SAntoine Ténart return -EINVAL; 7101b44c5a6SAntoine Ténart } 71119b347b3SPascal van Leeuwen dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL); 71219b347b3SPascal van Leeuwen } else { 71319b347b3SPascal van Leeuwen if (unlikely(totlen_src && (sreq->nr_src <= 0))) { 71419b347b3SPascal van Leeuwen dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!", 71519b347b3SPascal van Leeuwen totlen_src); 71619b347b3SPascal van Leeuwen return -EINVAL; 71719b347b3SPascal van Leeuwen } 71819b347b3SPascal van Leeuwen dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 71919b347b3SPascal van Leeuwen 72019b347b3SPascal van Leeuwen if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) { 72119b347b3SPascal van Leeuwen dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!", 72219b347b3SPascal van Leeuwen totlen_dst); 72319b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, 72419b347b3SPascal van Leeuwen DMA_TO_DEVICE); 72519b347b3SPascal van Leeuwen return -EINVAL; 72619b347b3SPascal van Leeuwen } 72719b347b3SPascal van Leeuwen dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE); 7281b44c5a6SAntoine Ténart } 7291b44c5a6SAntoine Ténart 7301b44c5a6SAntoine Ténart memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len); 7311b44c5a6SAntoine Ténart 73219b347b3SPascal van Leeuwen /* The EIP cannot deal with zero length input packets! */ 73319b347b3SPascal van Leeuwen if (totlen == 0) 73419b347b3SPascal van Leeuwen totlen = 1; 735f6beaea3SAntoine Tenart 7361b44c5a6SAntoine Ténart /* command descriptors */ 73719b347b3SPascal van Leeuwen for_each_sg(src, sg, sreq->nr_src, i) { 7381b44c5a6SAntoine Ténart int len = sg_dma_len(sg); 7391b44c5a6SAntoine Ténart 7401b44c5a6SAntoine Ténart /* Do not overflow the request */ 7411b44c5a6SAntoine Ténart if (queued - len < 0) 7421b44c5a6SAntoine Ténart len = queued; 7431b44c5a6SAntoine Ténart 74419b347b3SPascal van Leeuwen cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc, 74519b347b3SPascal van Leeuwen !(queued - len), 746f6beaea3SAntoine Tenart sg_dma_address(sg), len, totlen, 7471b44c5a6SAntoine Ténart ctx->base.ctxr_dma); 7481b44c5a6SAntoine Ténart if (IS_ERR(cdesc)) { 7491b44c5a6SAntoine Ténart /* No space left in the command descriptor ring */ 7501b44c5a6SAntoine Ténart ret = PTR_ERR(cdesc); 7511b44c5a6SAntoine Ténart goto cdesc_rollback; 7521b44c5a6SAntoine Ténart } 7531b44c5a6SAntoine Ténart n_cdesc++; 7541b44c5a6SAntoine Ténart 7551b44c5a6SAntoine Ténart if (n_cdesc == 1) { 75619b347b3SPascal van Leeuwen first_cdesc = cdesc; 7571b44c5a6SAntoine Ténart } 7581b44c5a6SAntoine Ténart 7591b44c5a6SAntoine Ténart queued -= len; 7601b44c5a6SAntoine Ténart if (!queued) 7611b44c5a6SAntoine Ténart break; 7621b44c5a6SAntoine Ténart } 7631b44c5a6SAntoine Ténart 76419b347b3SPascal van Leeuwen if (unlikely(!n_cdesc)) { 76519b347b3SPascal van Leeuwen /* 76619b347b3SPascal van Leeuwen * Special case: zero length input buffer. 76719b347b3SPascal van Leeuwen * The engine always needs the 1st command descriptor, however! 76819b347b3SPascal van Leeuwen */ 76919b347b3SPascal van Leeuwen first_cdesc = safexcel_add_cdesc(priv, ring, 1, 1, 0, 0, totlen, 77019b347b3SPascal van Leeuwen ctx->base.ctxr_dma); 77119b347b3SPascal van Leeuwen n_cdesc = 1; 77219b347b3SPascal van Leeuwen } 77319b347b3SPascal van Leeuwen 77419b347b3SPascal van Leeuwen /* Add context control words and token to first command descriptor */ 77519b347b3SPascal van Leeuwen safexcel_context_control(ctx, base, sreq, first_cdesc); 77619b347b3SPascal van Leeuwen if (ctx->aead) 77719b347b3SPascal van Leeuwen safexcel_aead_token(ctx, iv, first_cdesc, 77819b347b3SPascal van Leeuwen sreq->direction, cryptlen, 77919b347b3SPascal van Leeuwen assoclen, digestsize); 78019b347b3SPascal van Leeuwen else 78119b347b3SPascal van Leeuwen safexcel_skcipher_token(ctx, iv, first_cdesc, 78219b347b3SPascal van Leeuwen cryptlen); 78319b347b3SPascal van Leeuwen 7841b44c5a6SAntoine Ténart /* result descriptors */ 78519b347b3SPascal van Leeuwen for_each_sg(dst, sg, sreq->nr_dst, i) { 78619b347b3SPascal van Leeuwen bool last = (i == sreq->nr_dst - 1); 7871b44c5a6SAntoine Ténart u32 len = sg_dma_len(sg); 7881b44c5a6SAntoine Ténart 78919b347b3SPascal van Leeuwen /* only allow the part of the buffer we know we need */ 79019b347b3SPascal van Leeuwen if (len > totlen_dst) 79119b347b3SPascal van Leeuwen len = totlen_dst; 79219b347b3SPascal van Leeuwen if (unlikely(!len)) 79319b347b3SPascal van Leeuwen break; 79419b347b3SPascal van Leeuwen totlen_dst -= len; 79519b347b3SPascal van Leeuwen 79619b347b3SPascal van Leeuwen /* skip over AAD space in buffer - not written */ 79719b347b3SPascal van Leeuwen if (assoclen) { 79819b347b3SPascal van Leeuwen if (assoclen >= len) { 79919b347b3SPascal van Leeuwen assoclen -= len; 80019b347b3SPascal van Leeuwen continue; 80119b347b3SPascal van Leeuwen } 8021b44c5a6SAntoine Ténart rdesc = safexcel_add_rdesc(priv, ring, first, last, 80319b347b3SPascal van Leeuwen sg_dma_address(sg) + 80419b347b3SPascal van Leeuwen assoclen, 80519b347b3SPascal van Leeuwen len - assoclen); 80619b347b3SPascal van Leeuwen assoclen = 0; 80719b347b3SPascal van Leeuwen } else { 80819b347b3SPascal van Leeuwen rdesc = safexcel_add_rdesc(priv, ring, first, last, 80919b347b3SPascal van Leeuwen sg_dma_address(sg), 81019b347b3SPascal van Leeuwen len); 81119b347b3SPascal van Leeuwen } 8121b44c5a6SAntoine Ténart if (IS_ERR(rdesc)) { 8131b44c5a6SAntoine Ténart /* No space left in the result descriptor ring */ 8141b44c5a6SAntoine Ténart ret = PTR_ERR(rdesc); 8151b44c5a6SAntoine Ténart goto rdesc_rollback; 8161b44c5a6SAntoine Ténart } 81719b347b3SPascal van Leeuwen if (first) { 8189744fec9SOfer Heifetz first_rdesc = rdesc; 81919b347b3SPascal van Leeuwen first = false; 82019b347b3SPascal van Leeuwen } 8211b44c5a6SAntoine Ténart n_rdesc++; 8221b44c5a6SAntoine Ténart } 8231b44c5a6SAntoine Ténart 82419b347b3SPascal van Leeuwen if (unlikely(first)) { 82519b347b3SPascal van Leeuwen /* 82619b347b3SPascal van Leeuwen * Special case: AEAD decrypt with only AAD data. 82719b347b3SPascal van Leeuwen * In this case there is NO output data from the engine, 82819b347b3SPascal van Leeuwen * but the engine still needs a result descriptor! 82919b347b3SPascal van Leeuwen * Create a dummy one just for catching the result token. 83019b347b3SPascal van Leeuwen */ 83119b347b3SPascal van Leeuwen rdesc = safexcel_add_rdesc(priv, ring, true, true, 0, 0); 83219b347b3SPascal van Leeuwen if (IS_ERR(rdesc)) { 83319b347b3SPascal van Leeuwen /* No space left in the result descriptor ring */ 83419b347b3SPascal van Leeuwen ret = PTR_ERR(rdesc); 83519b347b3SPascal van Leeuwen goto rdesc_rollback; 83619b347b3SPascal van Leeuwen } 83719b347b3SPascal van Leeuwen first_rdesc = rdesc; 83819b347b3SPascal van Leeuwen n_rdesc = 1; 83919b347b3SPascal van Leeuwen } 84019b347b3SPascal van Leeuwen 8419744fec9SOfer Heifetz safexcel_rdr_req_set(priv, ring, first_rdesc, base); 84297858434SAntoine Ténart 8431b44c5a6SAntoine Ténart *commands = n_cdesc; 844152bdf4cSOfer Heifetz *results = n_rdesc; 8451b44c5a6SAntoine Ténart return 0; 8461b44c5a6SAntoine Ténart 8471b44c5a6SAntoine Ténart rdesc_rollback: 8481b44c5a6SAntoine Ténart for (i = 0; i < n_rdesc; i++) 8491b44c5a6SAntoine Ténart safexcel_ring_rollback_wptr(priv, &priv->ring[ring].rdr); 8501b44c5a6SAntoine Ténart cdesc_rollback: 8511b44c5a6SAntoine Ténart for (i = 0; i < n_cdesc; i++) 8521b44c5a6SAntoine Ténart safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr); 8531b44c5a6SAntoine Ténart 8548ac1283eSAntoine Tenart if (src == dst) { 85519b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL); 8561b44c5a6SAntoine Ténart } else { 85719b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 85819b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE); 8591b44c5a6SAntoine Ténart } 8601b44c5a6SAntoine Ténart 8611b44c5a6SAntoine Ténart return ret; 8621b44c5a6SAntoine Ténart } 8631b44c5a6SAntoine Ténart 8641b44c5a6SAntoine Ténart static int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv, 8651b44c5a6SAntoine Ténart int ring, 8668ac1283eSAntoine Tenart struct crypto_async_request *base, 86789332590SAntoine Tenart struct safexcel_cipher_req *sreq, 8681b44c5a6SAntoine Ténart bool *should_complete, int *ret) 8691b44c5a6SAntoine Ténart { 8708ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 8711b44c5a6SAntoine Ténart struct safexcel_result_desc *rdesc; 8721b44c5a6SAntoine Ténart int ndesc = 0, enq_ret; 8731b44c5a6SAntoine Ténart 8741b44c5a6SAntoine Ténart *ret = 0; 8751b44c5a6SAntoine Ténart 87689332590SAntoine Tenart if (unlikely(!sreq->rdescs)) 87789332590SAntoine Tenart return 0; 87889332590SAntoine Tenart 87989332590SAntoine Tenart while (sreq->rdescs--) { 8801b44c5a6SAntoine Ténart rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr); 8811b44c5a6SAntoine Ténart if (IS_ERR(rdesc)) { 8821b44c5a6SAntoine Ténart dev_err(priv->dev, 8831b44c5a6SAntoine Ténart "cipher: invalidate: could not retrieve the result descriptor\n"); 8841b44c5a6SAntoine Ténart *ret = PTR_ERR(rdesc); 8851b44c5a6SAntoine Ténart break; 8861b44c5a6SAntoine Ténart } 8871b44c5a6SAntoine Ténart 888cda3e73aSAntoine Tenart if (likely(!*ret)) 889cda3e73aSAntoine Tenart *ret = safexcel_rdesc_check_errors(priv, rdesc); 8901b44c5a6SAntoine Ténart 8911b44c5a6SAntoine Ténart ndesc++; 89289332590SAntoine Tenart } 8931b44c5a6SAntoine Ténart 8941b44c5a6SAntoine Ténart safexcel_complete(priv, ring); 8951b44c5a6SAntoine Ténart 8961b44c5a6SAntoine Ténart if (ctx->base.exit_inv) { 8971b44c5a6SAntoine Ténart dma_pool_free(priv->context_pool, ctx->base.ctxr, 8981b44c5a6SAntoine Ténart ctx->base.ctxr_dma); 8991b44c5a6SAntoine Ténart 9001b44c5a6SAntoine Ténart *should_complete = true; 9011b44c5a6SAntoine Ténart 9021b44c5a6SAntoine Ténart return ndesc; 9031b44c5a6SAntoine Ténart } 9041b44c5a6SAntoine Ténart 90586671abbSAntoine Ténart ring = safexcel_select_ring(priv); 90686671abbSAntoine Ténart ctx->base.ring = ring; 9071b44c5a6SAntoine Ténart 90886671abbSAntoine Ténart spin_lock_bh(&priv->ring[ring].queue_lock); 9098ac1283eSAntoine Tenart enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, base); 91086671abbSAntoine Ténart spin_unlock_bh(&priv->ring[ring].queue_lock); 9111b44c5a6SAntoine Ténart 9121b44c5a6SAntoine Ténart if (enq_ret != -EINPROGRESS) 9131b44c5a6SAntoine Ténart *ret = enq_ret; 9141b44c5a6SAntoine Ténart 9158472e778SAntoine Ténart queue_work(priv->ring[ring].workqueue, 9168472e778SAntoine Ténart &priv->ring[ring].work_data.work); 91786671abbSAntoine Ténart 9181b44c5a6SAntoine Ténart *should_complete = false; 9191b44c5a6SAntoine Ténart 9201b44c5a6SAntoine Ténart return ndesc; 9211b44c5a6SAntoine Ténart } 9221b44c5a6SAntoine Ténart 9238ac1283eSAntoine Tenart static int safexcel_skcipher_handle_result(struct safexcel_crypto_priv *priv, 9248ac1283eSAntoine Tenart int ring, 9251eb7b403SOfer Heifetz struct crypto_async_request *async, 9261eb7b403SOfer Heifetz bool *should_complete, int *ret) 9271eb7b403SOfer Heifetz { 9281eb7b403SOfer Heifetz struct skcipher_request *req = skcipher_request_cast(async); 9291eb7b403SOfer Heifetz struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 9301eb7b403SOfer Heifetz int err; 9311eb7b403SOfer Heifetz 9321eb7b403SOfer Heifetz if (sreq->needs_inv) { 9331eb7b403SOfer Heifetz sreq->needs_inv = false; 93489332590SAntoine Tenart err = safexcel_handle_inv_result(priv, ring, async, sreq, 9351eb7b403SOfer Heifetz should_complete, ret); 9361eb7b403SOfer Heifetz } else { 9378ac1283eSAntoine Tenart err = safexcel_handle_req_result(priv, ring, async, req->src, 9388ac1283eSAntoine Tenart req->dst, req->cryptlen, sreq, 9391eb7b403SOfer Heifetz should_complete, ret); 9401eb7b403SOfer Heifetz } 9411eb7b403SOfer Heifetz 9421eb7b403SOfer Heifetz return err; 9431eb7b403SOfer Heifetz } 9441eb7b403SOfer Heifetz 945f6beaea3SAntoine Tenart static int safexcel_aead_handle_result(struct safexcel_crypto_priv *priv, 946f6beaea3SAntoine Tenart int ring, 947f6beaea3SAntoine Tenart struct crypto_async_request *async, 948f6beaea3SAntoine Tenart bool *should_complete, int *ret) 949f6beaea3SAntoine Tenart { 950f6beaea3SAntoine Tenart struct aead_request *req = aead_request_cast(async); 951f6beaea3SAntoine Tenart struct crypto_aead *tfm = crypto_aead_reqtfm(req); 952f6beaea3SAntoine Tenart struct safexcel_cipher_req *sreq = aead_request_ctx(req); 953f6beaea3SAntoine Tenart int err; 954f6beaea3SAntoine Tenart 955f6beaea3SAntoine Tenart if (sreq->needs_inv) { 956f6beaea3SAntoine Tenart sreq->needs_inv = false; 95789332590SAntoine Tenart err = safexcel_handle_inv_result(priv, ring, async, sreq, 958f6beaea3SAntoine Tenart should_complete, ret); 959f6beaea3SAntoine Tenart } else { 960f6beaea3SAntoine Tenart err = safexcel_handle_req_result(priv, ring, async, req->src, 961f6beaea3SAntoine Tenart req->dst, 962f6beaea3SAntoine Tenart req->cryptlen + crypto_aead_authsize(tfm), 963f6beaea3SAntoine Tenart sreq, should_complete, ret); 964f6beaea3SAntoine Tenart } 965f6beaea3SAntoine Tenart 966f6beaea3SAntoine Tenart return err; 967f6beaea3SAntoine Tenart } 968f6beaea3SAntoine Tenart 9698ac1283eSAntoine Tenart static int safexcel_cipher_send_inv(struct crypto_async_request *base, 9709744fec9SOfer Heifetz int ring, int *commands, int *results) 9711b44c5a6SAntoine Ténart { 9728ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 9731b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 9741b44c5a6SAntoine Ténart int ret; 9751b44c5a6SAntoine Ténart 9769744fec9SOfer Heifetz ret = safexcel_invalidate_cache(base, priv, ctx->base.ctxr_dma, ring); 9771b44c5a6SAntoine Ténart if (unlikely(ret)) 9781b44c5a6SAntoine Ténart return ret; 9791b44c5a6SAntoine Ténart 9801b44c5a6SAntoine Ténart *commands = 1; 9811b44c5a6SAntoine Ténart *results = 1; 9821b44c5a6SAntoine Ténart 9831b44c5a6SAntoine Ténart return 0; 9841b44c5a6SAntoine Ténart } 9851b44c5a6SAntoine Ténart 9868ac1283eSAntoine Tenart static int safexcel_skcipher_send(struct crypto_async_request *async, int ring, 9871eb7b403SOfer Heifetz int *commands, int *results) 9881eb7b403SOfer Heifetz { 9891eb7b403SOfer Heifetz struct skcipher_request *req = skcipher_request_cast(async); 990871df319SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 9911eb7b403SOfer Heifetz struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 992871df319SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 9931eb7b403SOfer Heifetz int ret; 9941eb7b403SOfer Heifetz 99553c83e91SAntoine Tenart BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv); 996871df319SAntoine Ténart 9975bdb6e6aSPascal van Leeuwen if (sreq->needs_inv) { 9989744fec9SOfer Heifetz ret = safexcel_cipher_send_inv(async, ring, commands, results); 9995bdb6e6aSPascal van Leeuwen } else { 10005bdb6e6aSPascal van Leeuwen struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 10015bdb6e6aSPascal van Leeuwen u8 input_iv[AES_BLOCK_SIZE]; 10025bdb6e6aSPascal van Leeuwen 10035bdb6e6aSPascal van Leeuwen /* 10045bdb6e6aSPascal van Leeuwen * Save input IV in case of CBC decrypt mode 10055bdb6e6aSPascal van Leeuwen * Will be overwritten with output IV prior to use! 10065bdb6e6aSPascal van Leeuwen */ 10075bdb6e6aSPascal van Leeuwen memcpy(input_iv, req->iv, crypto_skcipher_ivsize(skcipher)); 10085bdb6e6aSPascal van Leeuwen 10099744fec9SOfer Heifetz ret = safexcel_send_req(async, ring, sreq, req->src, 10105bdb6e6aSPascal van Leeuwen req->dst, req->cryptlen, 0, 0, input_iv, 1011f6beaea3SAntoine Tenart commands, results); 10125bdb6e6aSPascal van Leeuwen } 101389332590SAntoine Tenart 101489332590SAntoine Tenart sreq->rdescs = *results; 1015f6beaea3SAntoine Tenart return ret; 1016f6beaea3SAntoine Tenart } 1017f6beaea3SAntoine Tenart 1018f6beaea3SAntoine Tenart static int safexcel_aead_send(struct crypto_async_request *async, int ring, 10199744fec9SOfer Heifetz int *commands, int *results) 1020f6beaea3SAntoine Tenart { 1021f6beaea3SAntoine Tenart struct aead_request *req = aead_request_cast(async); 1022f6beaea3SAntoine Tenart struct crypto_aead *tfm = crypto_aead_reqtfm(req); 1023f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 1024f6beaea3SAntoine Tenart struct safexcel_cipher_req *sreq = aead_request_ctx(req); 1025f6beaea3SAntoine Tenart struct safexcel_crypto_priv *priv = ctx->priv; 1026f6beaea3SAntoine Tenart int ret; 1027f6beaea3SAntoine Tenart 102853c83e91SAntoine Tenart BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv); 1029f6beaea3SAntoine Tenart 1030f6beaea3SAntoine Tenart if (sreq->needs_inv) 10319744fec9SOfer Heifetz ret = safexcel_cipher_send_inv(async, ring, commands, results); 1032f6beaea3SAntoine Tenart else 10339744fec9SOfer Heifetz ret = safexcel_send_req(async, ring, sreq, req->src, req->dst, 10349744fec9SOfer Heifetz req->cryptlen, req->assoclen, 1035f6beaea3SAntoine Tenart crypto_aead_authsize(tfm), req->iv, 10361eb7b403SOfer Heifetz commands, results); 103789332590SAntoine Tenart sreq->rdescs = *results; 10381eb7b403SOfer Heifetz return ret; 10391eb7b403SOfer Heifetz } 10401eb7b403SOfer Heifetz 10418ac1283eSAntoine Tenart static int safexcel_cipher_exit_inv(struct crypto_tfm *tfm, 10428ac1283eSAntoine Tenart struct crypto_async_request *base, 10438ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 10448ac1283eSAntoine Tenart struct safexcel_inv_result *result) 10451b44c5a6SAntoine Ténart { 10461b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 10471b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 104886671abbSAntoine Ténart int ring = ctx->base.ring; 10491b44c5a6SAntoine Ténart 10508ac1283eSAntoine Tenart init_completion(&result->completion); 10511b44c5a6SAntoine Ténart 10528ac1283eSAntoine Tenart ctx = crypto_tfm_ctx(base->tfm); 10531b44c5a6SAntoine Ténart ctx->base.exit_inv = true; 10541eb7b403SOfer Heifetz sreq->needs_inv = true; 10551b44c5a6SAntoine Ténart 105686671abbSAntoine Ténart spin_lock_bh(&priv->ring[ring].queue_lock); 10578ac1283eSAntoine Tenart crypto_enqueue_request(&priv->ring[ring].queue, base); 105886671abbSAntoine Ténart spin_unlock_bh(&priv->ring[ring].queue_lock); 10591b44c5a6SAntoine Ténart 10608472e778SAntoine Ténart queue_work(priv->ring[ring].workqueue, 10618472e778SAntoine Ténart &priv->ring[ring].work_data.work); 10621b44c5a6SAntoine Ténart 10638ac1283eSAntoine Tenart wait_for_completion(&result->completion); 10641b44c5a6SAntoine Ténart 10658ac1283eSAntoine Tenart if (result->error) { 10661b44c5a6SAntoine Ténart dev_warn(priv->dev, 10671b44c5a6SAntoine Ténart "cipher: sync: invalidate: completion error %d\n", 10688ac1283eSAntoine Tenart result->error); 10698ac1283eSAntoine Tenart return result->error; 10701b44c5a6SAntoine Ténart } 10711b44c5a6SAntoine Ténart 10721b44c5a6SAntoine Ténart return 0; 10731b44c5a6SAntoine Ténart } 10741b44c5a6SAntoine Ténart 10758ac1283eSAntoine Tenart static int safexcel_skcipher_exit_inv(struct crypto_tfm *tfm) 10768ac1283eSAntoine Tenart { 10778ac1283eSAntoine Tenart EIP197_REQUEST_ON_STACK(req, skcipher, EIP197_SKCIPHER_REQ_SIZE); 10788ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 10798ac1283eSAntoine Tenart struct safexcel_inv_result result = {}; 10808ac1283eSAntoine Tenart 10818ac1283eSAntoine Tenart memset(req, 0, sizeof(struct skcipher_request)); 10828ac1283eSAntoine Tenart 10838ac1283eSAntoine Tenart skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 10848ac1283eSAntoine Tenart safexcel_inv_complete, &result); 10858ac1283eSAntoine Tenart skcipher_request_set_tfm(req, __crypto_skcipher_cast(tfm)); 10868ac1283eSAntoine Tenart 10878ac1283eSAntoine Tenart return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result); 10888ac1283eSAntoine Tenart } 10898ac1283eSAntoine Tenart 1090f6beaea3SAntoine Tenart static int safexcel_aead_exit_inv(struct crypto_tfm *tfm) 1091f6beaea3SAntoine Tenart { 1092f6beaea3SAntoine Tenart EIP197_REQUEST_ON_STACK(req, aead, EIP197_AEAD_REQ_SIZE); 1093f6beaea3SAntoine Tenart struct safexcel_cipher_req *sreq = aead_request_ctx(req); 1094f6beaea3SAntoine Tenart struct safexcel_inv_result result = {}; 1095f6beaea3SAntoine Tenart 1096f6beaea3SAntoine Tenart memset(req, 0, sizeof(struct aead_request)); 1097f6beaea3SAntoine Tenart 1098f6beaea3SAntoine Tenart aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 1099f6beaea3SAntoine Tenart safexcel_inv_complete, &result); 1100f6beaea3SAntoine Tenart aead_request_set_tfm(req, __crypto_aead_cast(tfm)); 1101f6beaea3SAntoine Tenart 1102f6beaea3SAntoine Tenart return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result); 1103f6beaea3SAntoine Tenart } 1104f6beaea3SAntoine Tenart 1105a7dea8c0SOfer Heifetz static int safexcel_queue_req(struct crypto_async_request *base, 11068ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 110793369b5dSPascal van Leeuwen enum safexcel_cipher_direction dir) 11081b44c5a6SAntoine Ténart { 11098ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 11101b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 111186671abbSAntoine Ténart int ret, ring; 11121b44c5a6SAntoine Ténart 11131eb7b403SOfer Heifetz sreq->needs_inv = false; 1114847ccfc5SOfer Heifetz sreq->direction = dir; 11151b44c5a6SAntoine Ténart 11161b44c5a6SAntoine Ténart if (ctx->base.ctxr) { 111753c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE && ctx->base.needs_inv) { 11181eb7b403SOfer Heifetz sreq->needs_inv = true; 11191eb7b403SOfer Heifetz ctx->base.needs_inv = false; 11201eb7b403SOfer Heifetz } 11211b44c5a6SAntoine Ténart } else { 11221b44c5a6SAntoine Ténart ctx->base.ring = safexcel_select_ring(priv); 11231b44c5a6SAntoine Ténart ctx->base.ctxr = dma_pool_zalloc(priv->context_pool, 11248ac1283eSAntoine Tenart EIP197_GFP_FLAGS(*base), 11251b44c5a6SAntoine Ténart &ctx->base.ctxr_dma); 11261b44c5a6SAntoine Ténart if (!ctx->base.ctxr) 11271b44c5a6SAntoine Ténart return -ENOMEM; 11281b44c5a6SAntoine Ténart } 11291b44c5a6SAntoine Ténart 113086671abbSAntoine Ténart ring = ctx->base.ring; 11311b44c5a6SAntoine Ténart 113286671abbSAntoine Ténart spin_lock_bh(&priv->ring[ring].queue_lock); 11338ac1283eSAntoine Tenart ret = crypto_enqueue_request(&priv->ring[ring].queue, base); 113486671abbSAntoine Ténart spin_unlock_bh(&priv->ring[ring].queue_lock); 113586671abbSAntoine Ténart 11368472e778SAntoine Ténart queue_work(priv->ring[ring].workqueue, 11378472e778SAntoine Ténart &priv->ring[ring].work_data.work); 11381b44c5a6SAntoine Ténart 11391b44c5a6SAntoine Ténart return ret; 11401b44c5a6SAntoine Ténart } 11411b44c5a6SAntoine Ténart 114293369b5dSPascal van Leeuwen static int safexcel_encrypt(struct skcipher_request *req) 11431b44c5a6SAntoine Ténart { 1144a7dea8c0SOfer Heifetz return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 114593369b5dSPascal van Leeuwen SAFEXCEL_ENCRYPT); 11461b44c5a6SAntoine Ténart } 11471b44c5a6SAntoine Ténart 114893369b5dSPascal van Leeuwen static int safexcel_decrypt(struct skcipher_request *req) 11491b44c5a6SAntoine Ténart { 1150a7dea8c0SOfer Heifetz return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 115193369b5dSPascal van Leeuwen SAFEXCEL_DECRYPT); 11521b44c5a6SAntoine Ténart } 11531b44c5a6SAntoine Ténart 11541b44c5a6SAntoine Ténart static int safexcel_skcipher_cra_init(struct crypto_tfm *tfm) 11551b44c5a6SAntoine Ténart { 11561b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 11571b44c5a6SAntoine Ténart struct safexcel_alg_template *tmpl = 11581b44c5a6SAntoine Ténart container_of(tfm->__crt_alg, struct safexcel_alg_template, 11591b44c5a6SAntoine Ténart alg.skcipher.base); 11601b44c5a6SAntoine Ténart 11611eb7b403SOfer Heifetz crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), 11621eb7b403SOfer Heifetz sizeof(struct safexcel_cipher_req)); 11631b44c5a6SAntoine Ténart 11648ac1283eSAntoine Tenart ctx->priv = tmpl->priv; 11658ac1283eSAntoine Tenart 11668ac1283eSAntoine Tenart ctx->base.send = safexcel_skcipher_send; 11678ac1283eSAntoine Tenart ctx->base.handle_result = safexcel_skcipher_handle_result; 11688ac1283eSAntoine Tenart return 0; 11698ac1283eSAntoine Tenart } 11708ac1283eSAntoine Tenart 11718ac1283eSAntoine Tenart static int safexcel_cipher_cra_exit(struct crypto_tfm *tfm) 11728ac1283eSAntoine Tenart { 11738ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 11748ac1283eSAntoine Tenart 1175ce679559SAntoine Tenart memzero_explicit(ctx->key, sizeof(ctx->key)); 11768ac1283eSAntoine Tenart 11778ac1283eSAntoine Tenart /* context not allocated, skip invalidation */ 11788ac1283eSAntoine Tenart if (!ctx->base.ctxr) 11798ac1283eSAntoine Tenart return -ENOMEM; 11808ac1283eSAntoine Tenart 1181ce679559SAntoine Tenart memzero_explicit(ctx->base.ctxr->data, sizeof(ctx->base.ctxr->data)); 11821b44c5a6SAntoine Ténart return 0; 11831b44c5a6SAntoine Ténart } 11841b44c5a6SAntoine Ténart 11851b44c5a6SAntoine Ténart static void safexcel_skcipher_cra_exit(struct crypto_tfm *tfm) 11861b44c5a6SAntoine Ténart { 11871b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 11881b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 11891b44c5a6SAntoine Ténart int ret; 11901b44c5a6SAntoine Ténart 11918ac1283eSAntoine Tenart if (safexcel_cipher_cra_exit(tfm)) 11921b44c5a6SAntoine Ténart return; 11931b44c5a6SAntoine Ténart 119453c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE) { 11958ac1283eSAntoine Tenart ret = safexcel_skcipher_exit_inv(tfm); 11961b44c5a6SAntoine Ténart if (ret) 11978ac1283eSAntoine Tenart dev_warn(priv->dev, "skcipher: invalidation error %d\n", 11988ac1283eSAntoine Tenart ret); 1199871df319SAntoine Ténart } else { 1200871df319SAntoine Ténart dma_pool_free(priv->context_pool, ctx->base.ctxr, 1201871df319SAntoine Ténart ctx->base.ctxr_dma); 1202871df319SAntoine Ténart } 12031b44c5a6SAntoine Ténart } 12041b44c5a6SAntoine Ténart 1205f6beaea3SAntoine Tenart static void safexcel_aead_cra_exit(struct crypto_tfm *tfm) 1206f6beaea3SAntoine Tenart { 1207f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1208f6beaea3SAntoine Tenart struct safexcel_crypto_priv *priv = ctx->priv; 1209f6beaea3SAntoine Tenart int ret; 1210f6beaea3SAntoine Tenart 1211f6beaea3SAntoine Tenart if (safexcel_cipher_cra_exit(tfm)) 1212f6beaea3SAntoine Tenart return; 1213f6beaea3SAntoine Tenart 121453c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE) { 1215f6beaea3SAntoine Tenart ret = safexcel_aead_exit_inv(tfm); 1216f6beaea3SAntoine Tenart if (ret) 1217f6beaea3SAntoine Tenart dev_warn(priv->dev, "aead: invalidation error %d\n", 1218f6beaea3SAntoine Tenart ret); 1219f6beaea3SAntoine Tenart } else { 1220f6beaea3SAntoine Tenart dma_pool_free(priv->context_pool, ctx->base.ctxr, 1221f6beaea3SAntoine Tenart ctx->base.ctxr_dma); 1222f6beaea3SAntoine Tenart } 1223f6beaea3SAntoine Tenart } 1224f6beaea3SAntoine Tenart 122593369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_ecb_cra_init(struct crypto_tfm *tfm) 122693369b5dSPascal van Leeuwen { 122793369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 122893369b5dSPascal van Leeuwen 122993369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 123093369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 123193369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 123293369b5dSPascal van Leeuwen return 0; 123393369b5dSPascal van Leeuwen } 123493369b5dSPascal van Leeuwen 12351b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_ecb_aes = { 12361b44c5a6SAntoine Ténart .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1237062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES, 12381b44c5a6SAntoine Ténart .alg.skcipher = { 12398ac1283eSAntoine Tenart .setkey = safexcel_skcipher_aes_setkey, 124093369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 124193369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 12421b44c5a6SAntoine Ténart .min_keysize = AES_MIN_KEY_SIZE, 12431b44c5a6SAntoine Ténart .max_keysize = AES_MAX_KEY_SIZE, 12441b44c5a6SAntoine Ténart .base = { 12451b44c5a6SAntoine Ténart .cra_name = "ecb(aes)", 12461b44c5a6SAntoine Ténart .cra_driver_name = "safexcel-ecb-aes", 1247aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 12482c95e6d9SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 12491b44c5a6SAntoine Ténart CRYPTO_ALG_KERN_DRIVER_ONLY, 12501b44c5a6SAntoine Ténart .cra_blocksize = AES_BLOCK_SIZE, 12511b44c5a6SAntoine Ténart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 12521b44c5a6SAntoine Ténart .cra_alignmask = 0, 125393369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_ecb_cra_init, 12541b44c5a6SAntoine Ténart .cra_exit = safexcel_skcipher_cra_exit, 12551b44c5a6SAntoine Ténart .cra_module = THIS_MODULE, 12561b44c5a6SAntoine Ténart }, 12571b44c5a6SAntoine Ténart }, 12581b44c5a6SAntoine Ténart }; 12591b44c5a6SAntoine Ténart 126093369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_cbc_cra_init(struct crypto_tfm *tfm) 12611b44c5a6SAntoine Ténart { 126293369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 12631b44c5a6SAntoine Ténart 126493369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 126593369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 126693369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 126793369b5dSPascal van Leeuwen return 0; 12681b44c5a6SAntoine Ténart } 12691b44c5a6SAntoine Ténart 12701b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_cbc_aes = { 12711b44c5a6SAntoine Ténart .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1272062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES, 12731b44c5a6SAntoine Ténart .alg.skcipher = { 12748ac1283eSAntoine Tenart .setkey = safexcel_skcipher_aes_setkey, 127593369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 127693369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 12771b44c5a6SAntoine Ténart .min_keysize = AES_MIN_KEY_SIZE, 12781b44c5a6SAntoine Ténart .max_keysize = AES_MAX_KEY_SIZE, 12791b44c5a6SAntoine Ténart .ivsize = AES_BLOCK_SIZE, 12801b44c5a6SAntoine Ténart .base = { 12811b44c5a6SAntoine Ténart .cra_name = "cbc(aes)", 12821b44c5a6SAntoine Ténart .cra_driver_name = "safexcel-cbc-aes", 1283aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 12842c95e6d9SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 12851b44c5a6SAntoine Ténart CRYPTO_ALG_KERN_DRIVER_ONLY, 12861b44c5a6SAntoine Ténart .cra_blocksize = AES_BLOCK_SIZE, 12871b44c5a6SAntoine Ténart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 12881b44c5a6SAntoine Ténart .cra_alignmask = 0, 128993369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_cbc_cra_init, 12901b44c5a6SAntoine Ténart .cra_exit = safexcel_skcipher_cra_exit, 12911b44c5a6SAntoine Ténart .cra_module = THIS_MODULE, 12921b44c5a6SAntoine Ténart }, 12931b44c5a6SAntoine Ténart }, 12941b44c5a6SAntoine Ténart }; 1295f6beaea3SAntoine Tenart 129648e97afaSPascal van Leeuwen static int safexcel_skcipher_aes_cfb_cra_init(struct crypto_tfm *tfm) 129748e97afaSPascal van Leeuwen { 129848e97afaSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 129948e97afaSPascal van Leeuwen 130048e97afaSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 130148e97afaSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 130248e97afaSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; 130348e97afaSPascal van Leeuwen return 0; 130448e97afaSPascal van Leeuwen } 130548e97afaSPascal van Leeuwen 130648e97afaSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cfb_aes = { 130748e97afaSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 130848e97afaSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB, 130948e97afaSPascal van Leeuwen .alg.skcipher = { 131048e97afaSPascal van Leeuwen .setkey = safexcel_skcipher_aes_setkey, 131148e97afaSPascal van Leeuwen .encrypt = safexcel_encrypt, 131248e97afaSPascal van Leeuwen .decrypt = safexcel_decrypt, 131348e97afaSPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE, 131448e97afaSPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE, 131548e97afaSPascal van Leeuwen .ivsize = AES_BLOCK_SIZE, 131648e97afaSPascal van Leeuwen .base = { 131748e97afaSPascal van Leeuwen .cra_name = "cfb(aes)", 131848e97afaSPascal van Leeuwen .cra_driver_name = "safexcel-cfb-aes", 131948e97afaSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 132048e97afaSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 132148e97afaSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 132248e97afaSPascal van Leeuwen .cra_blocksize = 1, 132348e97afaSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 132448e97afaSPascal van Leeuwen .cra_alignmask = 0, 132548e97afaSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_cfb_cra_init, 132648e97afaSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 132748e97afaSPascal van Leeuwen .cra_module = THIS_MODULE, 132848e97afaSPascal van Leeuwen }, 132948e97afaSPascal van Leeuwen }, 133048e97afaSPascal van Leeuwen }; 133148e97afaSPascal van Leeuwen 133250485dfbSPascal van Leeuwen static int safexcel_skcipher_aes_ofb_cra_init(struct crypto_tfm *tfm) 133350485dfbSPascal van Leeuwen { 133450485dfbSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 133550485dfbSPascal van Leeuwen 133650485dfbSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 133750485dfbSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 133850485dfbSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; 133950485dfbSPascal van Leeuwen return 0; 134050485dfbSPascal van Leeuwen } 134150485dfbSPascal van Leeuwen 134250485dfbSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ofb_aes = { 134350485dfbSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 134450485dfbSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB, 134550485dfbSPascal van Leeuwen .alg.skcipher = { 134650485dfbSPascal van Leeuwen .setkey = safexcel_skcipher_aes_setkey, 134750485dfbSPascal van Leeuwen .encrypt = safexcel_encrypt, 134850485dfbSPascal van Leeuwen .decrypt = safexcel_decrypt, 134950485dfbSPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE, 135050485dfbSPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE, 135150485dfbSPascal van Leeuwen .ivsize = AES_BLOCK_SIZE, 135250485dfbSPascal van Leeuwen .base = { 135350485dfbSPascal van Leeuwen .cra_name = "ofb(aes)", 135450485dfbSPascal van Leeuwen .cra_driver_name = "safexcel-ofb-aes", 135550485dfbSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 135650485dfbSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 135750485dfbSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 135850485dfbSPascal van Leeuwen .cra_blocksize = 1, 135950485dfbSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 136050485dfbSPascal van Leeuwen .cra_alignmask = 0, 136150485dfbSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_ofb_cra_init, 136250485dfbSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 136350485dfbSPascal van Leeuwen .cra_module = THIS_MODULE, 136450485dfbSPascal van Leeuwen }, 136550485dfbSPascal van Leeuwen }, 136650485dfbSPascal van Leeuwen }; 136750485dfbSPascal van Leeuwen 136854f9e8faSPascal van Leeuwen static int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm, 136954f9e8faSPascal van Leeuwen const u8 *key, unsigned int len) 137054f9e8faSPascal van Leeuwen { 137154f9e8faSPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 137254f9e8faSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 137354f9e8faSPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 137454f9e8faSPascal van Leeuwen struct crypto_aes_ctx aes; 137554f9e8faSPascal van Leeuwen int ret, i; 137654f9e8faSPascal van Leeuwen unsigned int keylen; 137754f9e8faSPascal van Leeuwen 137854f9e8faSPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 1379f26882a3SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 138054f9e8faSPascal van Leeuwen /* exclude the nonce here */ 1381f26882a3SPascal van Leeuwen keylen = len - CTR_RFC3686_NONCE_SIZE; 138254f9e8faSPascal van Leeuwen ret = aes_expandkey(&aes, key, keylen); 138354f9e8faSPascal van Leeuwen if (ret) { 138454f9e8faSPascal van Leeuwen crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 138554f9e8faSPascal van Leeuwen return ret; 138654f9e8faSPascal van Leeuwen } 138754f9e8faSPascal van Leeuwen 138854f9e8faSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 138954f9e8faSPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) { 139013a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 139154f9e8faSPascal van Leeuwen ctx->base.needs_inv = true; 139254f9e8faSPascal van Leeuwen break; 139354f9e8faSPascal van Leeuwen } 139454f9e8faSPascal van Leeuwen } 139554f9e8faSPascal van Leeuwen } 139654f9e8faSPascal van Leeuwen 139754f9e8faSPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) 139854f9e8faSPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 139954f9e8faSPascal van Leeuwen 140054f9e8faSPascal van Leeuwen ctx->key_len = keylen; 140154f9e8faSPascal van Leeuwen 140254f9e8faSPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 140354f9e8faSPascal van Leeuwen return 0; 140454f9e8faSPascal van Leeuwen } 140554f9e8faSPascal van Leeuwen 140693369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_ctr_cra_init(struct crypto_tfm *tfm) 140793369b5dSPascal van Leeuwen { 140893369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 140993369b5dSPascal van Leeuwen 141093369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 141193369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 141293369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 141393369b5dSPascal van Leeuwen return 0; 141493369b5dSPascal van Leeuwen } 141593369b5dSPascal van Leeuwen 141654f9e8faSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ctr_aes = { 141754f9e8faSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1418062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES, 141954f9e8faSPascal van Leeuwen .alg.skcipher = { 142054f9e8faSPascal van Leeuwen .setkey = safexcel_skcipher_aesctr_setkey, 142193369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 142293369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 1423f26882a3SPascal van Leeuwen /* Add nonce size */ 1424f26882a3SPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 1425f26882a3SPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 1426f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 142754f9e8faSPascal van Leeuwen .base = { 142854f9e8faSPascal van Leeuwen .cra_name = "rfc3686(ctr(aes))", 142954f9e8faSPascal van Leeuwen .cra_driver_name = "safexcel-ctr-aes", 1430aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 143154f9e8faSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 143254f9e8faSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 143354f9e8faSPascal van Leeuwen .cra_blocksize = 1, 143454f9e8faSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 143554f9e8faSPascal van Leeuwen .cra_alignmask = 0, 143693369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_ctr_cra_init, 143754f9e8faSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 143854f9e8faSPascal van Leeuwen .cra_module = THIS_MODULE, 143954f9e8faSPascal van Leeuwen }, 144054f9e8faSPascal van Leeuwen }, 144154f9e8faSPascal van Leeuwen }; 144254f9e8faSPascal van Leeuwen 1443a7dea8c0SOfer Heifetz static int safexcel_des_setkey(struct crypto_skcipher *ctfm, const u8 *key, 1444a7dea8c0SOfer Heifetz unsigned int len) 1445a7dea8c0SOfer Heifetz { 144621f5a15eSArd Biesheuvel struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 1447a7dea8c0SOfer Heifetz int ret; 1448a7dea8c0SOfer Heifetz 144921f5a15eSArd Biesheuvel ret = verify_skcipher_des_key(ctfm, key); 145021f5a15eSArd Biesheuvel if (ret) 145121f5a15eSArd Biesheuvel return ret; 1452a7dea8c0SOfer Heifetz 1453a7dea8c0SOfer Heifetz /* if context exits and key changed, need to invalidate it */ 1454a7dea8c0SOfer Heifetz if (ctx->base.ctxr_dma) 1455a7dea8c0SOfer Heifetz if (memcmp(ctx->key, key, len)) 1456a7dea8c0SOfer Heifetz ctx->base.needs_inv = true; 1457a7dea8c0SOfer Heifetz 1458a7dea8c0SOfer Heifetz memcpy(ctx->key, key, len); 1459a7dea8c0SOfer Heifetz ctx->key_len = len; 1460a7dea8c0SOfer Heifetz 1461a7dea8c0SOfer Heifetz return 0; 1462a7dea8c0SOfer Heifetz } 1463a7dea8c0SOfer Heifetz 146493369b5dSPascal van Leeuwen static int safexcel_skcipher_des_cbc_cra_init(struct crypto_tfm *tfm) 146593369b5dSPascal van Leeuwen { 146693369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 146793369b5dSPascal van Leeuwen 146893369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 146993369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; 147093369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 147193369b5dSPascal van Leeuwen return 0; 147293369b5dSPascal van Leeuwen } 147393369b5dSPascal van Leeuwen 1474a7dea8c0SOfer Heifetz struct safexcel_alg_template safexcel_alg_cbc_des = { 1475a7dea8c0SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1476062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 1477a7dea8c0SOfer Heifetz .alg.skcipher = { 1478a7dea8c0SOfer Heifetz .setkey = safexcel_des_setkey, 147993369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 148093369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 1481a7dea8c0SOfer Heifetz .min_keysize = DES_KEY_SIZE, 1482a7dea8c0SOfer Heifetz .max_keysize = DES_KEY_SIZE, 1483a7dea8c0SOfer Heifetz .ivsize = DES_BLOCK_SIZE, 1484a7dea8c0SOfer Heifetz .base = { 1485a7dea8c0SOfer Heifetz .cra_name = "cbc(des)", 1486a7dea8c0SOfer Heifetz .cra_driver_name = "safexcel-cbc-des", 1487aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 14882b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1489a7dea8c0SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 1490a7dea8c0SOfer Heifetz .cra_blocksize = DES_BLOCK_SIZE, 1491a7dea8c0SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1492a7dea8c0SOfer Heifetz .cra_alignmask = 0, 149393369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des_cbc_cra_init, 1494a7dea8c0SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 1495a7dea8c0SOfer Heifetz .cra_module = THIS_MODULE, 1496a7dea8c0SOfer Heifetz }, 1497a7dea8c0SOfer Heifetz }, 1498a7dea8c0SOfer Heifetz }; 1499a7dea8c0SOfer Heifetz 150093369b5dSPascal van Leeuwen static int safexcel_skcipher_des_ecb_cra_init(struct crypto_tfm *tfm) 1501a7dea8c0SOfer Heifetz { 150293369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1503a7dea8c0SOfer Heifetz 150493369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 150593369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; 150693369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 150793369b5dSPascal van Leeuwen return 0; 1508a7dea8c0SOfer Heifetz } 1509a7dea8c0SOfer Heifetz 1510a7dea8c0SOfer Heifetz struct safexcel_alg_template safexcel_alg_ecb_des = { 1511a7dea8c0SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1512062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 1513a7dea8c0SOfer Heifetz .alg.skcipher = { 1514a7dea8c0SOfer Heifetz .setkey = safexcel_des_setkey, 151593369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 151693369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 1517a7dea8c0SOfer Heifetz .min_keysize = DES_KEY_SIZE, 1518a7dea8c0SOfer Heifetz .max_keysize = DES_KEY_SIZE, 1519a7dea8c0SOfer Heifetz .base = { 1520a7dea8c0SOfer Heifetz .cra_name = "ecb(des)", 1521a7dea8c0SOfer Heifetz .cra_driver_name = "safexcel-ecb-des", 1522aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 15232b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1524a7dea8c0SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 1525a7dea8c0SOfer Heifetz .cra_blocksize = DES_BLOCK_SIZE, 1526a7dea8c0SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1527a7dea8c0SOfer Heifetz .cra_alignmask = 0, 152893369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des_ecb_cra_init, 1529a7dea8c0SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 1530a7dea8c0SOfer Heifetz .cra_module = THIS_MODULE, 1531a7dea8c0SOfer Heifetz }, 1532a7dea8c0SOfer Heifetz }, 1533a7dea8c0SOfer Heifetz }; 153462469879SOfer Heifetz 153562469879SOfer Heifetz static int safexcel_des3_ede_setkey(struct crypto_skcipher *ctfm, 153662469879SOfer Heifetz const u8 *key, unsigned int len) 153762469879SOfer Heifetz { 153867ac62bfSHerbert Xu struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 153967ac62bfSHerbert Xu int err; 154062469879SOfer Heifetz 154121f5a15eSArd Biesheuvel err = verify_skcipher_des3_key(ctfm, key); 154221f5a15eSArd Biesheuvel if (err) 154367ac62bfSHerbert Xu return err; 154462469879SOfer Heifetz 154562469879SOfer Heifetz /* if context exits and key changed, need to invalidate it */ 154613a1bb93SPascal van Leeuwen if (ctx->base.ctxr_dma) 154762469879SOfer Heifetz if (memcmp(ctx->key, key, len)) 154862469879SOfer Heifetz ctx->base.needs_inv = true; 154962469879SOfer Heifetz 155062469879SOfer Heifetz memcpy(ctx->key, key, len); 155162469879SOfer Heifetz ctx->key_len = len; 155262469879SOfer Heifetz 155362469879SOfer Heifetz return 0; 155462469879SOfer Heifetz } 155562469879SOfer Heifetz 155693369b5dSPascal van Leeuwen static int safexcel_skcipher_des3_cbc_cra_init(struct crypto_tfm *tfm) 155793369b5dSPascal van Leeuwen { 155893369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 155993369b5dSPascal van Leeuwen 156093369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 156193369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; 156293369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 156393369b5dSPascal van Leeuwen return 0; 156493369b5dSPascal van Leeuwen } 156593369b5dSPascal van Leeuwen 156662469879SOfer Heifetz struct safexcel_alg_template safexcel_alg_cbc_des3_ede = { 156762469879SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1568062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 156962469879SOfer Heifetz .alg.skcipher = { 157062469879SOfer Heifetz .setkey = safexcel_des3_ede_setkey, 157193369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 157293369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 157362469879SOfer Heifetz .min_keysize = DES3_EDE_KEY_SIZE, 157462469879SOfer Heifetz .max_keysize = DES3_EDE_KEY_SIZE, 157562469879SOfer Heifetz .ivsize = DES3_EDE_BLOCK_SIZE, 157662469879SOfer Heifetz .base = { 157762469879SOfer Heifetz .cra_name = "cbc(des3_ede)", 157862469879SOfer Heifetz .cra_driver_name = "safexcel-cbc-des3_ede", 1579aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 15802b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 158162469879SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 158262469879SOfer Heifetz .cra_blocksize = DES3_EDE_BLOCK_SIZE, 158362469879SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 158462469879SOfer Heifetz .cra_alignmask = 0, 158593369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des3_cbc_cra_init, 158662469879SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 158762469879SOfer Heifetz .cra_module = THIS_MODULE, 158862469879SOfer Heifetz }, 158962469879SOfer Heifetz }, 159062469879SOfer Heifetz }; 159162469879SOfer Heifetz 159293369b5dSPascal van Leeuwen static int safexcel_skcipher_des3_ecb_cra_init(struct crypto_tfm *tfm) 159362469879SOfer Heifetz { 159493369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 159562469879SOfer Heifetz 159693369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 159793369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; 159893369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 159993369b5dSPascal van Leeuwen return 0; 160062469879SOfer Heifetz } 160162469879SOfer Heifetz 160262469879SOfer Heifetz struct safexcel_alg_template safexcel_alg_ecb_des3_ede = { 160362469879SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1604062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 160562469879SOfer Heifetz .alg.skcipher = { 160662469879SOfer Heifetz .setkey = safexcel_des3_ede_setkey, 160793369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 160893369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 160962469879SOfer Heifetz .min_keysize = DES3_EDE_KEY_SIZE, 161062469879SOfer Heifetz .max_keysize = DES3_EDE_KEY_SIZE, 161162469879SOfer Heifetz .base = { 161262469879SOfer Heifetz .cra_name = "ecb(des3_ede)", 161362469879SOfer Heifetz .cra_driver_name = "safexcel-ecb-des3_ede", 1614aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 16152b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 161662469879SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 161762469879SOfer Heifetz .cra_blocksize = DES3_EDE_BLOCK_SIZE, 161862469879SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 161962469879SOfer Heifetz .cra_alignmask = 0, 162093369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des3_ecb_cra_init, 162162469879SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 162262469879SOfer Heifetz .cra_module = THIS_MODULE, 162362469879SOfer Heifetz }, 162462469879SOfer Heifetz }, 162562469879SOfer Heifetz }; 162662469879SOfer Heifetz 162793369b5dSPascal van Leeuwen static int safexcel_aead_encrypt(struct aead_request *req) 1628f6beaea3SAntoine Tenart { 1629f6beaea3SAntoine Tenart struct safexcel_cipher_req *creq = aead_request_ctx(req); 1630f6beaea3SAntoine Tenart 163193369b5dSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 1632f6beaea3SAntoine Tenart } 1633f6beaea3SAntoine Tenart 163493369b5dSPascal van Leeuwen static int safexcel_aead_decrypt(struct aead_request *req) 1635f6beaea3SAntoine Tenart { 1636f6beaea3SAntoine Tenart struct safexcel_cipher_req *creq = aead_request_ctx(req); 1637f6beaea3SAntoine Tenart 163893369b5dSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 1639f6beaea3SAntoine Tenart } 1640f6beaea3SAntoine Tenart 1641f6beaea3SAntoine Tenart static int safexcel_aead_cra_init(struct crypto_tfm *tfm) 1642f6beaea3SAntoine Tenart { 1643f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1644f6beaea3SAntoine Tenart struct safexcel_alg_template *tmpl = 1645f6beaea3SAntoine Tenart container_of(tfm->__crt_alg, struct safexcel_alg_template, 1646f6beaea3SAntoine Tenart alg.aead.base); 1647f6beaea3SAntoine Tenart 1648f6beaea3SAntoine Tenart crypto_aead_set_reqsize(__crypto_aead_cast(tfm), 1649f6beaea3SAntoine Tenart sizeof(struct safexcel_cipher_req)); 1650f6beaea3SAntoine Tenart 1651f6beaea3SAntoine Tenart ctx->priv = tmpl->priv; 1652f6beaea3SAntoine Tenart 16530e17e362SPascal van Leeuwen ctx->alg = SAFEXCEL_AES; /* default */ 165493369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; /* default */ 1655f6beaea3SAntoine Tenart ctx->aead = true; 1656f6beaea3SAntoine Tenart ctx->base.send = safexcel_aead_send; 1657f6beaea3SAntoine Tenart ctx->base.handle_result = safexcel_aead_handle_result; 1658f6beaea3SAntoine Tenart return 0; 1659f6beaea3SAntoine Tenart } 1660f6beaea3SAntoine Tenart 166101ba061dSAntoine Tenart static int safexcel_aead_sha1_cra_init(struct crypto_tfm *tfm) 166201ba061dSAntoine Tenart { 166301ba061dSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 166401ba061dSAntoine Tenart 166501ba061dSAntoine Tenart safexcel_aead_cra_init(tfm); 1666a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; 166701ba061dSAntoine Tenart ctx->state_sz = SHA1_DIGEST_SIZE; 166801ba061dSAntoine Tenart return 0; 166901ba061dSAntoine Tenart } 167001ba061dSAntoine Tenart 167101ba061dSAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_aes = { 167201ba061dSAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1673062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1, 167401ba061dSAntoine Tenart .alg.aead = { 167577cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 167693369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 167793369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 167801ba061dSAntoine Tenart .ivsize = AES_BLOCK_SIZE, 167901ba061dSAntoine Tenart .maxauthsize = SHA1_DIGEST_SIZE, 168001ba061dSAntoine Tenart .base = { 168101ba061dSAntoine Tenart .cra_name = "authenc(hmac(sha1),cbc(aes))", 168201ba061dSAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-aes", 1683aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 16843f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 168501ba061dSAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 168601ba061dSAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 168701ba061dSAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 168801ba061dSAntoine Tenart .cra_alignmask = 0, 168901ba061dSAntoine Tenart .cra_init = safexcel_aead_sha1_cra_init, 169001ba061dSAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 169101ba061dSAntoine Tenart .cra_module = THIS_MODULE, 169201ba061dSAntoine Tenart }, 169301ba061dSAntoine Tenart }, 169401ba061dSAntoine Tenart }; 169501ba061dSAntoine Tenart 1696f6beaea3SAntoine Tenart static int safexcel_aead_sha256_cra_init(struct crypto_tfm *tfm) 1697f6beaea3SAntoine Tenart { 1698f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1699f6beaea3SAntoine Tenart 1700f6beaea3SAntoine Tenart safexcel_aead_cra_init(tfm); 1701a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256; 1702f6beaea3SAntoine Tenart ctx->state_sz = SHA256_DIGEST_SIZE; 1703f6beaea3SAntoine Tenart return 0; 1704f6beaea3SAntoine Tenart } 1705f6beaea3SAntoine Tenart 1706f6beaea3SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_aes = { 1707f6beaea3SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1708062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 1709f6beaea3SAntoine Tenart .alg.aead = { 171077cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 171193369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 171293369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1713f6beaea3SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 1714f6beaea3SAntoine Tenart .maxauthsize = SHA256_DIGEST_SIZE, 1715f6beaea3SAntoine Tenart .base = { 1716f6beaea3SAntoine Tenart .cra_name = "authenc(hmac(sha256),cbc(aes))", 1717f6beaea3SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-aes", 1718aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 17193f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1720f6beaea3SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 1721f6beaea3SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 1722f6beaea3SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1723f6beaea3SAntoine Tenart .cra_alignmask = 0, 1724f6beaea3SAntoine Tenart .cra_init = safexcel_aead_sha256_cra_init, 1725f6beaea3SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 1726f6beaea3SAntoine Tenart .cra_module = THIS_MODULE, 1727f6beaea3SAntoine Tenart }, 1728f6beaea3SAntoine Tenart }, 1729f6beaea3SAntoine Tenart }; 1730678b2878SAntoine Tenart 1731678b2878SAntoine Tenart static int safexcel_aead_sha224_cra_init(struct crypto_tfm *tfm) 1732678b2878SAntoine Tenart { 1733678b2878SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1734678b2878SAntoine Tenart 1735678b2878SAntoine Tenart safexcel_aead_cra_init(tfm); 1736a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224; 1737678b2878SAntoine Tenart ctx->state_sz = SHA256_DIGEST_SIZE; 1738678b2878SAntoine Tenart return 0; 1739678b2878SAntoine Tenart } 1740678b2878SAntoine Tenart 1741678b2878SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_aes = { 1742678b2878SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1743062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 1744678b2878SAntoine Tenart .alg.aead = { 174577cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 174693369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 174793369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1748678b2878SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 1749678b2878SAntoine Tenart .maxauthsize = SHA224_DIGEST_SIZE, 1750678b2878SAntoine Tenart .base = { 1751678b2878SAntoine Tenart .cra_name = "authenc(hmac(sha224),cbc(aes))", 1752678b2878SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-aes", 1753aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 17543f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1755678b2878SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 1756678b2878SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 1757678b2878SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1758678b2878SAntoine Tenart .cra_alignmask = 0, 1759678b2878SAntoine Tenart .cra_init = safexcel_aead_sha224_cra_init, 1760678b2878SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 1761678b2878SAntoine Tenart .cra_module = THIS_MODULE, 1762678b2878SAntoine Tenart }, 1763678b2878SAntoine Tenart }, 1764678b2878SAntoine Tenart }; 176587eee125SAntoine Tenart 176687eee125SAntoine Tenart static int safexcel_aead_sha512_cra_init(struct crypto_tfm *tfm) 176787eee125SAntoine Tenart { 176887eee125SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 176987eee125SAntoine Tenart 177087eee125SAntoine Tenart safexcel_aead_cra_init(tfm); 1771a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512; 177287eee125SAntoine Tenart ctx->state_sz = SHA512_DIGEST_SIZE; 177387eee125SAntoine Tenart return 0; 177487eee125SAntoine Tenart } 177587eee125SAntoine Tenart 177687eee125SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_aes = { 177787eee125SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1778062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 177987eee125SAntoine Tenart .alg.aead = { 178077cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 178193369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 178293369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 178387eee125SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 178487eee125SAntoine Tenart .maxauthsize = SHA512_DIGEST_SIZE, 178587eee125SAntoine Tenart .base = { 178687eee125SAntoine Tenart .cra_name = "authenc(hmac(sha512),cbc(aes))", 178787eee125SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-aes", 1788aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 17893f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 179087eee125SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 179187eee125SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 179287eee125SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 179387eee125SAntoine Tenart .cra_alignmask = 0, 179487eee125SAntoine Tenart .cra_init = safexcel_aead_sha512_cra_init, 179587eee125SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 179687eee125SAntoine Tenart .cra_module = THIS_MODULE, 179787eee125SAntoine Tenart }, 179887eee125SAntoine Tenart }, 179987eee125SAntoine Tenart }; 1800ea23cb53SAntoine Tenart 1801ea23cb53SAntoine Tenart static int safexcel_aead_sha384_cra_init(struct crypto_tfm *tfm) 1802ea23cb53SAntoine Tenart { 1803ea23cb53SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1804ea23cb53SAntoine Tenart 1805ea23cb53SAntoine Tenart safexcel_aead_cra_init(tfm); 1806a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384; 1807ea23cb53SAntoine Tenart ctx->state_sz = SHA512_DIGEST_SIZE; 1808ea23cb53SAntoine Tenart return 0; 1809ea23cb53SAntoine Tenart } 1810ea23cb53SAntoine Tenart 1811ea23cb53SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_aes = { 1812ea23cb53SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1813062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 1814ea23cb53SAntoine Tenart .alg.aead = { 181577cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 181693369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 181793369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1818ea23cb53SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 1819ea23cb53SAntoine Tenart .maxauthsize = SHA384_DIGEST_SIZE, 1820ea23cb53SAntoine Tenart .base = { 1821ea23cb53SAntoine Tenart .cra_name = "authenc(hmac(sha384),cbc(aes))", 1822ea23cb53SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-aes", 1823aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 18243f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1825ea23cb53SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 1826ea23cb53SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 1827ea23cb53SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1828ea23cb53SAntoine Tenart .cra_alignmask = 0, 1829ea23cb53SAntoine Tenart .cra_init = safexcel_aead_sha384_cra_init, 1830ea23cb53SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 1831ea23cb53SAntoine Tenart .cra_module = THIS_MODULE, 1832ea23cb53SAntoine Tenart }, 1833ea23cb53SAntoine Tenart }, 1834ea23cb53SAntoine Tenart }; 183577cdd4efSPascal van Leeuwen 18360e17e362SPascal van Leeuwen static int safexcel_aead_sha1_des3_cra_init(struct crypto_tfm *tfm) 18370e17e362SPascal van Leeuwen { 18380e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 18390e17e362SPascal van Leeuwen 18400e17e362SPascal van Leeuwen safexcel_aead_sha1_cra_init(tfm); 18410e17e362SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 18420e17e362SPascal van Leeuwen return 0; 18430e17e362SPascal van Leeuwen } 18440e17e362SPascal van Leeuwen 184577cdd4efSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des3_ede = { 184677cdd4efSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1847062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, 184877cdd4efSPascal van Leeuwen .alg.aead = { 184977cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 185093369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 185193369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 185277cdd4efSPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 185377cdd4efSPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 185477cdd4efSPascal van Leeuwen .base = { 185577cdd4efSPascal van Leeuwen .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", 185677cdd4efSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des3_ede", 1857aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 185877cdd4efSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 185977cdd4efSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 186077cdd4efSPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 186177cdd4efSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 186277cdd4efSPascal van Leeuwen .cra_alignmask = 0, 18630e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha1_des3_cra_init, 18640e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 18650e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 18660e17e362SPascal van Leeuwen }, 18670e17e362SPascal van Leeuwen }, 18680e17e362SPascal van Leeuwen }; 18690e17e362SPascal van Leeuwen 1870f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha256_des3_cra_init(struct crypto_tfm *tfm) 1871f0a8bdf0SPascal van Leeuwen { 1872f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1873f0a8bdf0SPascal van Leeuwen 1874f0a8bdf0SPascal van Leeuwen safexcel_aead_sha256_cra_init(tfm); 1875f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1876f0a8bdf0SPascal van Leeuwen return 0; 1877f0a8bdf0SPascal van Leeuwen } 1878f0a8bdf0SPascal van Leeuwen 1879f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede = { 1880f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1881f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 1882f0a8bdf0SPascal van Leeuwen .alg.aead = { 1883f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 1884f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 1885f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1886f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 1887f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA256_DIGEST_SIZE, 1888f0a8bdf0SPascal van Leeuwen .base = { 1889f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", 1890f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des3_ede", 1891f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 1892f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1893f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 1894f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 1895f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1896f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 1897f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha256_des3_cra_init, 1898f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 1899f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 1900f0a8bdf0SPascal van Leeuwen }, 1901f0a8bdf0SPascal van Leeuwen }, 1902f0a8bdf0SPascal van Leeuwen }; 1903f0a8bdf0SPascal van Leeuwen 1904f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha224_des3_cra_init(struct crypto_tfm *tfm) 1905f0a8bdf0SPascal van Leeuwen { 1906f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1907f0a8bdf0SPascal van Leeuwen 1908f0a8bdf0SPascal van Leeuwen safexcel_aead_sha224_cra_init(tfm); 1909f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1910f0a8bdf0SPascal van Leeuwen return 0; 1911f0a8bdf0SPascal van Leeuwen } 1912f0a8bdf0SPascal van Leeuwen 1913f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede = { 1914f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1915f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 1916f0a8bdf0SPascal van Leeuwen .alg.aead = { 1917f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 1918f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 1919f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1920f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 1921f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA224_DIGEST_SIZE, 1922f0a8bdf0SPascal van Leeuwen .base = { 1923f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha224),cbc(des3_ede))", 1924f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des3_ede", 1925f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 1926f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1927f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 1928f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 1929f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1930f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 1931f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha224_des3_cra_init, 1932f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 1933f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 1934f0a8bdf0SPascal van Leeuwen }, 1935f0a8bdf0SPascal van Leeuwen }, 1936f0a8bdf0SPascal van Leeuwen }; 1937f0a8bdf0SPascal van Leeuwen 1938f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha512_des3_cra_init(struct crypto_tfm *tfm) 1939f0a8bdf0SPascal van Leeuwen { 1940f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1941f0a8bdf0SPascal van Leeuwen 1942f0a8bdf0SPascal van Leeuwen safexcel_aead_sha512_cra_init(tfm); 1943f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1944f0a8bdf0SPascal van Leeuwen return 0; 1945f0a8bdf0SPascal van Leeuwen } 1946f0a8bdf0SPascal van Leeuwen 1947f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede = { 1948f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1949f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 1950f0a8bdf0SPascal van Leeuwen .alg.aead = { 1951f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 1952f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 1953f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1954f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 1955f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA512_DIGEST_SIZE, 1956f0a8bdf0SPascal van Leeuwen .base = { 1957f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha512),cbc(des3_ede))", 1958f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des3_ede", 1959f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 1960f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1961f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 1962f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 1963f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1964f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 1965f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha512_des3_cra_init, 1966f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 1967f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 1968f0a8bdf0SPascal van Leeuwen }, 1969f0a8bdf0SPascal van Leeuwen }, 1970f0a8bdf0SPascal van Leeuwen }; 1971f0a8bdf0SPascal van Leeuwen 1972f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha384_des3_cra_init(struct crypto_tfm *tfm) 1973f0a8bdf0SPascal van Leeuwen { 1974f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1975f0a8bdf0SPascal van Leeuwen 1976f0a8bdf0SPascal van Leeuwen safexcel_aead_sha384_cra_init(tfm); 1977f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1978f0a8bdf0SPascal van Leeuwen return 0; 1979f0a8bdf0SPascal van Leeuwen } 1980f0a8bdf0SPascal van Leeuwen 1981f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede = { 1982f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1983f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 1984f0a8bdf0SPascal van Leeuwen .alg.aead = { 1985f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 1986f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 1987f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1988f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 1989f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA384_DIGEST_SIZE, 1990f0a8bdf0SPascal van Leeuwen .base = { 1991f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha384),cbc(des3_ede))", 1992f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des3_ede", 1993f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 1994f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1995f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 1996f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 1997f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1998f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 1999f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha384_des3_cra_init, 2000f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2001f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 2002f0a8bdf0SPascal van Leeuwen }, 2003f0a8bdf0SPascal van Leeuwen }, 2004f0a8bdf0SPascal van Leeuwen }; 2005f0a8bdf0SPascal van Leeuwen 2006bb7679b8SPascal van Leeuwen static int safexcel_aead_sha1_des_cra_init(struct crypto_tfm *tfm) 2007bb7679b8SPascal van Leeuwen { 2008bb7679b8SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2009bb7679b8SPascal van Leeuwen 2010bb7679b8SPascal van Leeuwen safexcel_aead_sha1_cra_init(tfm); 2011bb7679b8SPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2012bb7679b8SPascal van Leeuwen return 0; 2013bb7679b8SPascal van Leeuwen } 2014bb7679b8SPascal van Leeuwen 2015bb7679b8SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des = { 2016bb7679b8SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2017bb7679b8SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, 2018bb7679b8SPascal van Leeuwen .alg.aead = { 2019bb7679b8SPascal van Leeuwen .setkey = safexcel_aead_setkey, 2020bb7679b8SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2021bb7679b8SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2022bb7679b8SPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2023bb7679b8SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 2024bb7679b8SPascal van Leeuwen .base = { 2025bb7679b8SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),cbc(des))", 2026bb7679b8SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des", 2027bb7679b8SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2028bb7679b8SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2029bb7679b8SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2030bb7679b8SPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2031bb7679b8SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2032bb7679b8SPascal van Leeuwen .cra_alignmask = 0, 2033bb7679b8SPascal van Leeuwen .cra_init = safexcel_aead_sha1_des_cra_init, 2034bb7679b8SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2035bb7679b8SPascal van Leeuwen .cra_module = THIS_MODULE, 2036bb7679b8SPascal van Leeuwen }, 2037bb7679b8SPascal van Leeuwen }, 2038bb7679b8SPascal van Leeuwen }; 2039bb7679b8SPascal van Leeuwen 2040457a6fdfSPascal van Leeuwen static int safexcel_aead_sha256_des_cra_init(struct crypto_tfm *tfm) 2041457a6fdfSPascal van Leeuwen { 2042457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2043457a6fdfSPascal van Leeuwen 2044457a6fdfSPascal van Leeuwen safexcel_aead_sha256_cra_init(tfm); 2045457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2046457a6fdfSPascal van Leeuwen return 0; 2047457a6fdfSPascal van Leeuwen } 2048457a6fdfSPascal van Leeuwen 2049457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des = { 2050457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2051457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 2052457a6fdfSPascal van Leeuwen .alg.aead = { 2053457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2054457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2055457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2056457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2057457a6fdfSPascal van Leeuwen .maxauthsize = SHA256_DIGEST_SIZE, 2058457a6fdfSPascal van Leeuwen .base = { 2059457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha256),cbc(des))", 2060457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des", 2061457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2062457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2063457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2064457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2065457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2066457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2067457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha256_des_cra_init, 2068457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2069457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2070457a6fdfSPascal van Leeuwen }, 2071457a6fdfSPascal van Leeuwen }, 2072457a6fdfSPascal van Leeuwen }; 2073457a6fdfSPascal van Leeuwen 2074457a6fdfSPascal van Leeuwen static int safexcel_aead_sha224_des_cra_init(struct crypto_tfm *tfm) 2075457a6fdfSPascal van Leeuwen { 2076457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2077457a6fdfSPascal van Leeuwen 2078457a6fdfSPascal van Leeuwen safexcel_aead_sha224_cra_init(tfm); 2079457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2080457a6fdfSPascal van Leeuwen return 0; 2081457a6fdfSPascal van Leeuwen } 2082457a6fdfSPascal van Leeuwen 2083457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des = { 2084457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2085457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 2086457a6fdfSPascal van Leeuwen .alg.aead = { 2087457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2088457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2089457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2090457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2091457a6fdfSPascal van Leeuwen .maxauthsize = SHA224_DIGEST_SIZE, 2092457a6fdfSPascal van Leeuwen .base = { 2093457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha224),cbc(des))", 2094457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des", 2095457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2096457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2097457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2098457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2099457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2100457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2101457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha224_des_cra_init, 2102457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2103457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2104457a6fdfSPascal van Leeuwen }, 2105457a6fdfSPascal van Leeuwen }, 2106457a6fdfSPascal van Leeuwen }; 2107457a6fdfSPascal van Leeuwen 2108457a6fdfSPascal van Leeuwen static int safexcel_aead_sha512_des_cra_init(struct crypto_tfm *tfm) 2109457a6fdfSPascal van Leeuwen { 2110457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2111457a6fdfSPascal van Leeuwen 2112457a6fdfSPascal van Leeuwen safexcel_aead_sha512_cra_init(tfm); 2113457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2114457a6fdfSPascal van Leeuwen return 0; 2115457a6fdfSPascal van Leeuwen } 2116457a6fdfSPascal van Leeuwen 2117457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des = { 2118457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2119457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2120457a6fdfSPascal van Leeuwen .alg.aead = { 2121457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2122457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2123457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2124457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2125457a6fdfSPascal van Leeuwen .maxauthsize = SHA512_DIGEST_SIZE, 2126457a6fdfSPascal van Leeuwen .base = { 2127457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha512),cbc(des))", 2128457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des", 2129457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2130457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2131457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2132457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2133457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2134457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2135457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha512_des_cra_init, 2136457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2137457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2138457a6fdfSPascal van Leeuwen }, 2139457a6fdfSPascal van Leeuwen }, 2140457a6fdfSPascal van Leeuwen }; 2141457a6fdfSPascal van Leeuwen 2142457a6fdfSPascal van Leeuwen static int safexcel_aead_sha384_des_cra_init(struct crypto_tfm *tfm) 2143457a6fdfSPascal van Leeuwen { 2144457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2145457a6fdfSPascal van Leeuwen 2146457a6fdfSPascal van Leeuwen safexcel_aead_sha384_cra_init(tfm); 2147457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2148457a6fdfSPascal van Leeuwen return 0; 2149457a6fdfSPascal van Leeuwen } 2150457a6fdfSPascal van Leeuwen 2151457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des = { 2152457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2153457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2154457a6fdfSPascal van Leeuwen .alg.aead = { 2155457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2156457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2157457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2158457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2159457a6fdfSPascal van Leeuwen .maxauthsize = SHA384_DIGEST_SIZE, 2160457a6fdfSPascal van Leeuwen .base = { 2161457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha384),cbc(des))", 2162457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des", 2163457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2164457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2165457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2166457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2167457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2168457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2169457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha384_des_cra_init, 2170457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2171457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2172457a6fdfSPascal van Leeuwen }, 2173457a6fdfSPascal van Leeuwen }, 2174457a6fdfSPascal van Leeuwen }; 2175457a6fdfSPascal van Leeuwen 21760e17e362SPascal van Leeuwen static int safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm *tfm) 21770e17e362SPascal van Leeuwen { 21780e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 21790e17e362SPascal van Leeuwen 21800e17e362SPascal van Leeuwen safexcel_aead_sha1_cra_init(tfm); 21810e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 21820e17e362SPascal van Leeuwen return 0; 21830e17e362SPascal van Leeuwen } 21840e17e362SPascal van Leeuwen 21850e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_aes = { 21860e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2187062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1, 21880e17e362SPascal van Leeuwen .alg.aead = { 21890e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 219093369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 219193369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2192f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 21930e17e362SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 21940e17e362SPascal van Leeuwen .base = { 21950e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))", 21960e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-aes", 2197aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 21980e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 21990e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 22000e17e362SPascal van Leeuwen .cra_blocksize = 1, 22010e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 22020e17e362SPascal van Leeuwen .cra_alignmask = 0, 22030e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha1_ctr_cra_init, 22040e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 22050e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 22060e17e362SPascal van Leeuwen }, 22070e17e362SPascal van Leeuwen }, 22080e17e362SPascal van Leeuwen }; 22090e17e362SPascal van Leeuwen 22100e17e362SPascal van Leeuwen static int safexcel_aead_sha256_ctr_cra_init(struct crypto_tfm *tfm) 22110e17e362SPascal van Leeuwen { 22120e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 22130e17e362SPascal van Leeuwen 22140e17e362SPascal van Leeuwen safexcel_aead_sha256_cra_init(tfm); 22150e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 22160e17e362SPascal van Leeuwen return 0; 22170e17e362SPascal van Leeuwen } 22180e17e362SPascal van Leeuwen 22190e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes = { 22200e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2221062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 22220e17e362SPascal van Leeuwen .alg.aead = { 22230e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 222493369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 222593369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2226f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 22270e17e362SPascal van Leeuwen .maxauthsize = SHA256_DIGEST_SIZE, 22280e17e362SPascal van Leeuwen .base = { 22290e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))", 22300e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha256-ctr-aes", 2231aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 22320e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 22330e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 22340e17e362SPascal van Leeuwen .cra_blocksize = 1, 22350e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 22360e17e362SPascal van Leeuwen .cra_alignmask = 0, 22370e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha256_ctr_cra_init, 22380e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 22390e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 22400e17e362SPascal van Leeuwen }, 22410e17e362SPascal van Leeuwen }, 22420e17e362SPascal van Leeuwen }; 22430e17e362SPascal van Leeuwen 22440e17e362SPascal van Leeuwen static int safexcel_aead_sha224_ctr_cra_init(struct crypto_tfm *tfm) 22450e17e362SPascal van Leeuwen { 22460e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 22470e17e362SPascal van Leeuwen 22480e17e362SPascal van Leeuwen safexcel_aead_sha224_cra_init(tfm); 22490e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 22500e17e362SPascal van Leeuwen return 0; 22510e17e362SPascal van Leeuwen } 22520e17e362SPascal van Leeuwen 22530e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_ctr_aes = { 22540e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2255062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 22560e17e362SPascal van Leeuwen .alg.aead = { 22570e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 225893369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 225993369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2260f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 22610e17e362SPascal van Leeuwen .maxauthsize = SHA224_DIGEST_SIZE, 22620e17e362SPascal van Leeuwen .base = { 22630e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))", 22640e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha224-ctr-aes", 2265aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 22660e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 22670e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 22680e17e362SPascal van Leeuwen .cra_blocksize = 1, 22690e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 22700e17e362SPascal van Leeuwen .cra_alignmask = 0, 22710e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha224_ctr_cra_init, 22720e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 22730e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 22740e17e362SPascal van Leeuwen }, 22750e17e362SPascal van Leeuwen }, 22760e17e362SPascal van Leeuwen }; 22770e17e362SPascal van Leeuwen 22780e17e362SPascal van Leeuwen static int safexcel_aead_sha512_ctr_cra_init(struct crypto_tfm *tfm) 22790e17e362SPascal van Leeuwen { 22800e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 22810e17e362SPascal van Leeuwen 22820e17e362SPascal van Leeuwen safexcel_aead_sha512_cra_init(tfm); 22830e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 22840e17e362SPascal van Leeuwen return 0; 22850e17e362SPascal van Leeuwen } 22860e17e362SPascal van Leeuwen 22870e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes = { 22880e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2289062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 22900e17e362SPascal van Leeuwen .alg.aead = { 22910e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 229293369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 229393369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2294f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 22950e17e362SPascal van Leeuwen .maxauthsize = SHA512_DIGEST_SIZE, 22960e17e362SPascal van Leeuwen .base = { 22970e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha512),rfc3686(ctr(aes)))", 22980e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha512-ctr-aes", 2299aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 23000e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 23010e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 23020e17e362SPascal van Leeuwen .cra_blocksize = 1, 23030e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 23040e17e362SPascal van Leeuwen .cra_alignmask = 0, 23050e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha512_ctr_cra_init, 23060e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 23070e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 23080e17e362SPascal van Leeuwen }, 23090e17e362SPascal van Leeuwen }, 23100e17e362SPascal van Leeuwen }; 23110e17e362SPascal van Leeuwen 23120e17e362SPascal van Leeuwen static int safexcel_aead_sha384_ctr_cra_init(struct crypto_tfm *tfm) 23130e17e362SPascal van Leeuwen { 23140e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 23150e17e362SPascal van Leeuwen 23160e17e362SPascal van Leeuwen safexcel_aead_sha384_cra_init(tfm); 23170e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 23180e17e362SPascal van Leeuwen return 0; 23190e17e362SPascal van Leeuwen } 23200e17e362SPascal van Leeuwen 23210e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes = { 23220e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2323062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 23240e17e362SPascal van Leeuwen .alg.aead = { 23250e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 232693369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 232793369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2328f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 23290e17e362SPascal van Leeuwen .maxauthsize = SHA384_DIGEST_SIZE, 23300e17e362SPascal van Leeuwen .base = { 23310e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha384),rfc3686(ctr(aes)))", 23320e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha384-ctr-aes", 2333aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 23340e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 23350e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 23360e17e362SPascal van Leeuwen .cra_blocksize = 1, 23370e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 23380e17e362SPascal van Leeuwen .cra_alignmask = 0, 23390e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha384_ctr_cra_init, 234077cdd4efSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 234177cdd4efSPascal van Leeuwen .cra_module = THIS_MODULE, 234277cdd4efSPascal van Leeuwen }, 234377cdd4efSPascal van Leeuwen }, 234477cdd4efSPascal van Leeuwen }; 2345c7da38a7SPascal van Leeuwen 2346c7da38a7SPascal van Leeuwen static int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm, 2347c7da38a7SPascal van Leeuwen const u8 *key, unsigned int len) 2348c7da38a7SPascal van Leeuwen { 2349c7da38a7SPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 2350c7da38a7SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2351c7da38a7SPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 2352c7da38a7SPascal van Leeuwen struct crypto_aes_ctx aes; 2353c7da38a7SPascal van Leeuwen int ret, i; 2354c7da38a7SPascal van Leeuwen unsigned int keylen; 2355c7da38a7SPascal van Leeuwen 2356c7da38a7SPascal van Leeuwen /* Check for illegal XTS keys */ 2357c7da38a7SPascal van Leeuwen ret = xts_verify_key(ctfm, key, len); 2358c7da38a7SPascal van Leeuwen if (ret) 2359c7da38a7SPascal van Leeuwen return ret; 2360c7da38a7SPascal van Leeuwen 2361c7da38a7SPascal van Leeuwen /* Only half of the key data is cipher key */ 2362c7da38a7SPascal van Leeuwen keylen = (len >> 1); 2363c7da38a7SPascal van Leeuwen ret = aes_expandkey(&aes, key, keylen); 2364c7da38a7SPascal van Leeuwen if (ret) { 2365c7da38a7SPascal van Leeuwen crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 2366c7da38a7SPascal van Leeuwen return ret; 2367c7da38a7SPascal van Leeuwen } 2368c7da38a7SPascal van Leeuwen 2369c7da38a7SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 2370c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) { 237113a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 2372c7da38a7SPascal van Leeuwen ctx->base.needs_inv = true; 2373c7da38a7SPascal van Leeuwen break; 2374c7da38a7SPascal van Leeuwen } 2375c7da38a7SPascal van Leeuwen } 2376c7da38a7SPascal van Leeuwen } 2377c7da38a7SPascal van Leeuwen 2378c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) 2379c7da38a7SPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 2380c7da38a7SPascal van Leeuwen 2381c7da38a7SPascal van Leeuwen /* The other half is the tweak key */ 2382c7da38a7SPascal van Leeuwen ret = aes_expandkey(&aes, (u8 *)(key + keylen), keylen); 2383c7da38a7SPascal van Leeuwen if (ret) { 2384c7da38a7SPascal van Leeuwen crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 2385c7da38a7SPascal van Leeuwen return ret; 2386c7da38a7SPascal van Leeuwen } 2387c7da38a7SPascal van Leeuwen 2388c7da38a7SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 2389c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) { 239013a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i + keylen / sizeof(u32)]) != 239113a1bb93SPascal van Leeuwen aes.key_enc[i]) { 2392c7da38a7SPascal van Leeuwen ctx->base.needs_inv = true; 2393c7da38a7SPascal van Leeuwen break; 2394c7da38a7SPascal van Leeuwen } 2395c7da38a7SPascal van Leeuwen } 2396c7da38a7SPascal van Leeuwen } 2397c7da38a7SPascal van Leeuwen 2398c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) 2399c7da38a7SPascal van Leeuwen ctx->key[i + keylen / sizeof(u32)] = 2400c7da38a7SPascal van Leeuwen cpu_to_le32(aes.key_enc[i]); 2401c7da38a7SPascal van Leeuwen 2402c7da38a7SPascal van Leeuwen ctx->key_len = keylen << 1; 2403c7da38a7SPascal van Leeuwen 2404c7da38a7SPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 2405c7da38a7SPascal van Leeuwen return 0; 2406c7da38a7SPascal van Leeuwen } 2407c7da38a7SPascal van Leeuwen 2408c7da38a7SPascal van Leeuwen static int safexcel_skcipher_aes_xts_cra_init(struct crypto_tfm *tfm) 2409c7da38a7SPascal van Leeuwen { 2410c7da38a7SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2411c7da38a7SPascal van Leeuwen 2412c7da38a7SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 2413c7da38a7SPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 2414c7da38a7SPascal van Leeuwen ctx->xts = 1; 2415c7da38a7SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS; 2416c7da38a7SPascal van Leeuwen return 0; 2417c7da38a7SPascal van Leeuwen } 2418c7da38a7SPascal van Leeuwen 2419c7da38a7SPascal van Leeuwen static int safexcel_encrypt_xts(struct skcipher_request *req) 2420c7da38a7SPascal van Leeuwen { 2421c7da38a7SPascal van Leeuwen if (req->cryptlen < XTS_BLOCK_SIZE) 2422c7da38a7SPascal van Leeuwen return -EINVAL; 2423c7da38a7SPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 2424c7da38a7SPascal van Leeuwen SAFEXCEL_ENCRYPT); 2425c7da38a7SPascal van Leeuwen } 2426c7da38a7SPascal van Leeuwen 2427c7da38a7SPascal van Leeuwen static int safexcel_decrypt_xts(struct skcipher_request *req) 2428c7da38a7SPascal van Leeuwen { 2429c7da38a7SPascal van Leeuwen if (req->cryptlen < XTS_BLOCK_SIZE) 2430c7da38a7SPascal van Leeuwen return -EINVAL; 2431c7da38a7SPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 2432c7da38a7SPascal van Leeuwen SAFEXCEL_DECRYPT); 2433c7da38a7SPascal van Leeuwen } 2434c7da38a7SPascal van Leeuwen 2435c7da38a7SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_xts_aes = { 2436c7da38a7SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 2437062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XTS, 2438c7da38a7SPascal van Leeuwen .alg.skcipher = { 2439c7da38a7SPascal van Leeuwen .setkey = safexcel_skcipher_aesxts_setkey, 2440c7da38a7SPascal van Leeuwen .encrypt = safexcel_encrypt_xts, 2441c7da38a7SPascal van Leeuwen .decrypt = safexcel_decrypt_xts, 2442c7da38a7SPascal van Leeuwen /* XTS actually uses 2 AES keys glued together */ 2443c7da38a7SPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE * 2, 2444c7da38a7SPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE * 2, 2445c7da38a7SPascal van Leeuwen .ivsize = XTS_BLOCK_SIZE, 2446c7da38a7SPascal van Leeuwen .base = { 2447c7da38a7SPascal van Leeuwen .cra_name = "xts(aes)", 2448c7da38a7SPascal van Leeuwen .cra_driver_name = "safexcel-xts-aes", 2449aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2450c7da38a7SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2451c7da38a7SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2452c7da38a7SPascal van Leeuwen .cra_blocksize = XTS_BLOCK_SIZE, 2453c7da38a7SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2454c7da38a7SPascal van Leeuwen .cra_alignmask = 0, 2455c7da38a7SPascal van Leeuwen .cra_init = safexcel_skcipher_aes_xts_cra_init, 2456c7da38a7SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 2457c7da38a7SPascal van Leeuwen .cra_module = THIS_MODULE, 2458c7da38a7SPascal van Leeuwen }, 2459c7da38a7SPascal van Leeuwen }, 2460c7da38a7SPascal van Leeuwen }; 24613e450886SPascal van Leeuwen 24623e450886SPascal van Leeuwen static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, 24633e450886SPascal van Leeuwen unsigned int len) 24643e450886SPascal van Leeuwen { 24653e450886SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 24663e450886SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 24673e450886SPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 24683e450886SPascal van Leeuwen struct crypto_aes_ctx aes; 24693e450886SPascal van Leeuwen u32 hashkey[AES_BLOCK_SIZE >> 2]; 24703e450886SPascal van Leeuwen int ret, i; 24713e450886SPascal van Leeuwen 24723e450886SPascal van Leeuwen ret = aes_expandkey(&aes, key, len); 24733e450886SPascal van Leeuwen if (ret) { 24743e450886SPascal van Leeuwen crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 24753e450886SPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 24763e450886SPascal van Leeuwen return ret; 24773e450886SPascal van Leeuwen } 24783e450886SPascal van Leeuwen 24793e450886SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 24803e450886SPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) { 248113a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 24823e450886SPascal van Leeuwen ctx->base.needs_inv = true; 24833e450886SPascal van Leeuwen break; 24843e450886SPascal van Leeuwen } 24853e450886SPascal van Leeuwen } 24863e450886SPascal van Leeuwen } 24873e450886SPascal van Leeuwen 24883e450886SPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) 24893e450886SPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 24903e450886SPascal van Leeuwen 24913e450886SPascal van Leeuwen ctx->key_len = len; 24923e450886SPascal van Leeuwen 24933e450886SPascal van Leeuwen /* Compute hash key by encrypting zeroes with cipher key */ 24943e450886SPascal van Leeuwen crypto_cipher_clear_flags(ctx->hkaes, CRYPTO_TFM_REQ_MASK); 24953e450886SPascal van Leeuwen crypto_cipher_set_flags(ctx->hkaes, crypto_aead_get_flags(ctfm) & 24963e450886SPascal van Leeuwen CRYPTO_TFM_REQ_MASK); 24973e450886SPascal van Leeuwen ret = crypto_cipher_setkey(ctx->hkaes, key, len); 24983e450886SPascal van Leeuwen crypto_aead_set_flags(ctfm, crypto_cipher_get_flags(ctx->hkaes) & 24993e450886SPascal van Leeuwen CRYPTO_TFM_RES_MASK); 25003e450886SPascal van Leeuwen if (ret) 25013e450886SPascal van Leeuwen return ret; 25023e450886SPascal van Leeuwen 25033e450886SPascal van Leeuwen memset(hashkey, 0, AES_BLOCK_SIZE); 25043e450886SPascal van Leeuwen crypto_cipher_encrypt_one(ctx->hkaes, (u8 *)hashkey, (u8 *)hashkey); 25053e450886SPascal van Leeuwen 25063e450886SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 25073e450886SPascal van Leeuwen for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) { 250813a1bb93SPascal van Leeuwen if (be32_to_cpu(ctx->ipad[i]) != hashkey[i]) { 25093e450886SPascal van Leeuwen ctx->base.needs_inv = true; 25103e450886SPascal van Leeuwen break; 25113e450886SPascal van Leeuwen } 25123e450886SPascal van Leeuwen } 25133e450886SPascal van Leeuwen } 25143e450886SPascal van Leeuwen 25153e450886SPascal van Leeuwen for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) 25163e450886SPascal van Leeuwen ctx->ipad[i] = cpu_to_be32(hashkey[i]); 25173e450886SPascal van Leeuwen 25183e450886SPascal van Leeuwen memzero_explicit(hashkey, AES_BLOCK_SIZE); 25193e450886SPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 25203e450886SPascal van Leeuwen return 0; 25213e450886SPascal van Leeuwen } 25223e450886SPascal van Leeuwen 25233e450886SPascal van Leeuwen static int safexcel_aead_gcm_cra_init(struct crypto_tfm *tfm) 25243e450886SPascal van Leeuwen { 25253e450886SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 25263e450886SPascal van Leeuwen 25273e450886SPascal van Leeuwen safexcel_aead_cra_init(tfm); 25283e450886SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_GHASH; 25293e450886SPascal van Leeuwen ctx->state_sz = GHASH_BLOCK_SIZE; 25304eb76fafSPascal van Leeuwen ctx->xcm = EIP197_XCM_MODE_GCM; 25313e450886SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ 25323e450886SPascal van Leeuwen 25333e450886SPascal van Leeuwen ctx->hkaes = crypto_alloc_cipher("aes", 0, 0); 25343e450886SPascal van Leeuwen if (IS_ERR(ctx->hkaes)) 25353e450886SPascal van Leeuwen return PTR_ERR(ctx->hkaes); 25363e450886SPascal van Leeuwen 25373e450886SPascal van Leeuwen return 0; 25383e450886SPascal van Leeuwen } 25393e450886SPascal van Leeuwen 25403e450886SPascal van Leeuwen static void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm) 25413e450886SPascal van Leeuwen { 25423e450886SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 25433e450886SPascal van Leeuwen 25443e450886SPascal van Leeuwen crypto_free_cipher(ctx->hkaes); 25453e450886SPascal van Leeuwen safexcel_aead_cra_exit(tfm); 25463e450886SPascal van Leeuwen } 25473e450886SPascal van Leeuwen 25483e450886SPascal van Leeuwen static int safexcel_aead_gcm_setauthsize(struct crypto_aead *tfm, 25493e450886SPascal van Leeuwen unsigned int authsize) 25503e450886SPascal van Leeuwen { 25513e450886SPascal van Leeuwen return crypto_gcm_check_authsize(authsize); 25523e450886SPascal van Leeuwen } 25533e450886SPascal van Leeuwen 25543e450886SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_gcm = { 25553e450886SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 25563e450886SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 25573e450886SPascal van Leeuwen .alg.aead = { 25583e450886SPascal van Leeuwen .setkey = safexcel_aead_gcm_setkey, 25593e450886SPascal van Leeuwen .setauthsize = safexcel_aead_gcm_setauthsize, 25603e450886SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 25613e450886SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 25623e450886SPascal van Leeuwen .ivsize = GCM_AES_IV_SIZE, 25633e450886SPascal van Leeuwen .maxauthsize = GHASH_DIGEST_SIZE, 25643e450886SPascal van Leeuwen .base = { 25653e450886SPascal van Leeuwen .cra_name = "gcm(aes)", 25663e450886SPascal van Leeuwen .cra_driver_name = "safexcel-gcm-aes", 25673e450886SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 25683e450886SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 25693e450886SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 25703e450886SPascal van Leeuwen .cra_blocksize = 1, 25713e450886SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 25723e450886SPascal van Leeuwen .cra_alignmask = 0, 25733e450886SPascal van Leeuwen .cra_init = safexcel_aead_gcm_cra_init, 25743e450886SPascal van Leeuwen .cra_exit = safexcel_aead_gcm_cra_exit, 25753e450886SPascal van Leeuwen .cra_module = THIS_MODULE, 25763e450886SPascal van Leeuwen }, 25773e450886SPascal van Leeuwen }, 25783e450886SPascal van Leeuwen }; 25794eb76fafSPascal van Leeuwen 25804eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, 25814eb76fafSPascal van Leeuwen unsigned int len) 25824eb76fafSPascal van Leeuwen { 25834eb76fafSPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 25844eb76fafSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 25854eb76fafSPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 25864eb76fafSPascal van Leeuwen struct crypto_aes_ctx aes; 25874eb76fafSPascal van Leeuwen int ret, i; 25884eb76fafSPascal van Leeuwen 25894eb76fafSPascal van Leeuwen ret = aes_expandkey(&aes, key, len); 25904eb76fafSPascal van Leeuwen if (ret) { 25914eb76fafSPascal van Leeuwen crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 25924eb76fafSPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 25934eb76fafSPascal van Leeuwen return ret; 25944eb76fafSPascal van Leeuwen } 25954eb76fafSPascal van Leeuwen 25964eb76fafSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 25974eb76fafSPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) { 259813a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 25994eb76fafSPascal van Leeuwen ctx->base.needs_inv = true; 26004eb76fafSPascal van Leeuwen break; 26014eb76fafSPascal van Leeuwen } 26024eb76fafSPascal van Leeuwen } 26034eb76fafSPascal van Leeuwen } 26044eb76fafSPascal van Leeuwen 26054eb76fafSPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) { 26064eb76fafSPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 26074eb76fafSPascal van Leeuwen ctx->ipad[i + 2 * AES_BLOCK_SIZE / sizeof(u32)] = 26084eb76fafSPascal van Leeuwen cpu_to_be32(aes.key_enc[i]); 26094eb76fafSPascal van Leeuwen } 26104eb76fafSPascal van Leeuwen 26114eb76fafSPascal van Leeuwen ctx->key_len = len; 26124eb76fafSPascal van Leeuwen ctx->state_sz = 2 * AES_BLOCK_SIZE + len; 26134eb76fafSPascal van Leeuwen 26144eb76fafSPascal van Leeuwen if (len == AES_KEYSIZE_192) 26154eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192; 26164eb76fafSPascal van Leeuwen else if (len == AES_KEYSIZE_256) 26174eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256; 26184eb76fafSPascal van Leeuwen else 26194eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; 26204eb76fafSPascal van Leeuwen 26214eb76fafSPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 26224eb76fafSPascal van Leeuwen return 0; 26234eb76fafSPascal van Leeuwen } 26244eb76fafSPascal van Leeuwen 26254eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_cra_init(struct crypto_tfm *tfm) 26264eb76fafSPascal van Leeuwen { 26274eb76fafSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 26284eb76fafSPascal van Leeuwen 26294eb76fafSPascal van Leeuwen safexcel_aead_cra_init(tfm); 26304eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; 26314eb76fafSPascal van Leeuwen ctx->state_sz = 3 * AES_BLOCK_SIZE; 26324eb76fafSPascal van Leeuwen ctx->xcm = EIP197_XCM_MODE_CCM; 26334eb76fafSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ 26344eb76fafSPascal van Leeuwen return 0; 26354eb76fafSPascal van Leeuwen } 26364eb76fafSPascal van Leeuwen 26374eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_setauthsize(struct crypto_aead *tfm, 26384eb76fafSPascal van Leeuwen unsigned int authsize) 26394eb76fafSPascal van Leeuwen { 26404eb76fafSPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 26414eb76fafSPascal van Leeuwen switch (authsize) { 26424eb76fafSPascal van Leeuwen case 4: 26434eb76fafSPascal van Leeuwen case 6: 26444eb76fafSPascal van Leeuwen case 8: 26454eb76fafSPascal van Leeuwen case 10: 26464eb76fafSPascal van Leeuwen case 12: 26474eb76fafSPascal van Leeuwen case 14: 26484eb76fafSPascal van Leeuwen case 16: 26494eb76fafSPascal van Leeuwen break; 26504eb76fafSPascal van Leeuwen default: 26514eb76fafSPascal van Leeuwen return -EINVAL; 26524eb76fafSPascal van Leeuwen } 26534eb76fafSPascal van Leeuwen 26544eb76fafSPascal van Leeuwen return 0; 26554eb76fafSPascal van Leeuwen } 26564eb76fafSPascal van Leeuwen 26574eb76fafSPascal van Leeuwen static int safexcel_ccm_encrypt(struct aead_request *req) 26584eb76fafSPascal van Leeuwen { 26594eb76fafSPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 26604eb76fafSPascal van Leeuwen 26614eb76fafSPascal van Leeuwen if (req->iv[0] < 1 || req->iv[0] > 7) 26624eb76fafSPascal van Leeuwen return -EINVAL; 26634eb76fafSPascal van Leeuwen 26644eb76fafSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 26654eb76fafSPascal van Leeuwen } 26664eb76fafSPascal van Leeuwen 26674eb76fafSPascal van Leeuwen static int safexcel_ccm_decrypt(struct aead_request *req) 26684eb76fafSPascal van Leeuwen { 26694eb76fafSPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 26704eb76fafSPascal van Leeuwen 26714eb76fafSPascal van Leeuwen if (req->iv[0] < 1 || req->iv[0] > 7) 26724eb76fafSPascal van Leeuwen return -EINVAL; 26734eb76fafSPascal van Leeuwen 26744eb76fafSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 26754eb76fafSPascal van Leeuwen } 26764eb76fafSPascal van Leeuwen 26774eb76fafSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ccm = { 26784eb76fafSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 26794eb76fafSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, 26804eb76fafSPascal van Leeuwen .alg.aead = { 26814eb76fafSPascal van Leeuwen .setkey = safexcel_aead_ccm_setkey, 26824eb76fafSPascal van Leeuwen .setauthsize = safexcel_aead_ccm_setauthsize, 26834eb76fafSPascal van Leeuwen .encrypt = safexcel_ccm_encrypt, 26844eb76fafSPascal van Leeuwen .decrypt = safexcel_ccm_decrypt, 26854eb76fafSPascal van Leeuwen .ivsize = AES_BLOCK_SIZE, 26864eb76fafSPascal van Leeuwen .maxauthsize = AES_BLOCK_SIZE, 26874eb76fafSPascal van Leeuwen .base = { 26884eb76fafSPascal van Leeuwen .cra_name = "ccm(aes)", 26894eb76fafSPascal van Leeuwen .cra_driver_name = "safexcel-ccm-aes", 26904eb76fafSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 26914eb76fafSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 26924eb76fafSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 26934eb76fafSPascal van Leeuwen .cra_blocksize = 1, 26944eb76fafSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 26954eb76fafSPascal van Leeuwen .cra_alignmask = 0, 26964eb76fafSPascal van Leeuwen .cra_init = safexcel_aead_ccm_cra_init, 26974eb76fafSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 26984eb76fafSPascal van Leeuwen .cra_module = THIS_MODULE, 26994eb76fafSPascal van Leeuwen }, 27004eb76fafSPascal van Leeuwen }, 27014eb76fafSPascal van Leeuwen }; 27024a593fb3SPascal van Leeuwen 2703a6061921SPascal van Leeuwen static void safexcel_chacha20_setkey(struct safexcel_cipher_ctx *ctx, 2704a6061921SPascal van Leeuwen const u8 *key) 27054a593fb3SPascal van Leeuwen { 27064a593fb3SPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 27074a593fb3SPascal van Leeuwen 270813a1bb93SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 270913a1bb93SPascal van Leeuwen if (memcmp(ctx->key, key, CHACHA_KEY_SIZE)) 27104a593fb3SPascal van Leeuwen ctx->base.needs_inv = true; 27114a593fb3SPascal van Leeuwen 271213a1bb93SPascal van Leeuwen memcpy(ctx->key, key, CHACHA_KEY_SIZE); 27134a593fb3SPascal van Leeuwen ctx->key_len = CHACHA_KEY_SIZE; 2714a6061921SPascal van Leeuwen } 2715a6061921SPascal van Leeuwen 2716a6061921SPascal van Leeuwen static int safexcel_skcipher_chacha20_setkey(struct crypto_skcipher *ctfm, 2717a6061921SPascal van Leeuwen const u8 *key, unsigned int len) 2718a6061921SPascal van Leeuwen { 2719a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 2720a6061921SPascal van Leeuwen 2721a6061921SPascal van Leeuwen if (len != CHACHA_KEY_SIZE) { 2722a6061921SPascal van Leeuwen crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 2723a6061921SPascal van Leeuwen return -EINVAL; 2724a6061921SPascal van Leeuwen } 2725a6061921SPascal van Leeuwen safexcel_chacha20_setkey(ctx, key); 27264a593fb3SPascal van Leeuwen 27274a593fb3SPascal van Leeuwen return 0; 27284a593fb3SPascal van Leeuwen } 27294a593fb3SPascal van Leeuwen 27304a593fb3SPascal van Leeuwen static int safexcel_skcipher_chacha20_cra_init(struct crypto_tfm *tfm) 27314a593fb3SPascal van Leeuwen { 27324a593fb3SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 27334a593fb3SPascal van Leeuwen 27344a593fb3SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 27354a593fb3SPascal van Leeuwen ctx->alg = SAFEXCEL_CHACHA20; 27364a593fb3SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32; 27374a593fb3SPascal van Leeuwen return 0; 27384a593fb3SPascal van Leeuwen } 27394a593fb3SPascal van Leeuwen 27404a593fb3SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chacha20 = { 27414a593fb3SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 27424a593fb3SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_CHACHA20, 27434a593fb3SPascal van Leeuwen .alg.skcipher = { 27444a593fb3SPascal van Leeuwen .setkey = safexcel_skcipher_chacha20_setkey, 27454a593fb3SPascal van Leeuwen .encrypt = safexcel_encrypt, 27464a593fb3SPascal van Leeuwen .decrypt = safexcel_decrypt, 27474a593fb3SPascal van Leeuwen .min_keysize = CHACHA_KEY_SIZE, 27484a593fb3SPascal van Leeuwen .max_keysize = CHACHA_KEY_SIZE, 27494a593fb3SPascal van Leeuwen .ivsize = CHACHA_IV_SIZE, 27504a593fb3SPascal van Leeuwen .base = { 27514a593fb3SPascal van Leeuwen .cra_name = "chacha20", 27524a593fb3SPascal van Leeuwen .cra_driver_name = "safexcel-chacha20", 27534a593fb3SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 27544a593fb3SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 27554a593fb3SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 27564a593fb3SPascal van Leeuwen .cra_blocksize = 1, 27574a593fb3SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 27584a593fb3SPascal van Leeuwen .cra_alignmask = 0, 27594a593fb3SPascal van Leeuwen .cra_init = safexcel_skcipher_chacha20_cra_init, 27604a593fb3SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 27614a593fb3SPascal van Leeuwen .cra_module = THIS_MODULE, 27624a593fb3SPascal van Leeuwen }, 27634a593fb3SPascal van Leeuwen }, 27644a593fb3SPascal van Leeuwen }; 2765a6061921SPascal van Leeuwen 2766a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_setkey(struct crypto_aead *ctfm, 2767a6061921SPascal van Leeuwen const u8 *key, unsigned int len) 2768a6061921SPascal van Leeuwen { 2769a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_aead_ctx(ctfm); 2770a6061921SPascal van Leeuwen 2771a6061921SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP && 2772a6061921SPascal van Leeuwen len > EIP197_AEAD_IPSEC_NONCE_SIZE) { 2773a6061921SPascal van Leeuwen /* ESP variant has nonce appended to key */ 2774a6061921SPascal van Leeuwen len -= EIP197_AEAD_IPSEC_NONCE_SIZE; 2775a6061921SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len); 2776a6061921SPascal van Leeuwen } 2777a6061921SPascal van Leeuwen if (len != CHACHA_KEY_SIZE) { 2778a6061921SPascal van Leeuwen crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 2779a6061921SPascal van Leeuwen return -EINVAL; 2780a6061921SPascal van Leeuwen } 2781a6061921SPascal van Leeuwen safexcel_chacha20_setkey(ctx, key); 2782a6061921SPascal van Leeuwen 2783a6061921SPascal van Leeuwen return 0; 2784a6061921SPascal van Leeuwen } 2785a6061921SPascal van Leeuwen 2786a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_setauthsize(struct crypto_aead *tfm, 2787a6061921SPascal van Leeuwen unsigned int authsize) 2788a6061921SPascal van Leeuwen { 2789a6061921SPascal van Leeuwen if (authsize != POLY1305_DIGEST_SIZE) 2790a6061921SPascal van Leeuwen return -EINVAL; 2791a6061921SPascal van Leeuwen return 0; 2792a6061921SPascal van Leeuwen } 2793a6061921SPascal van Leeuwen 2794a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_crypt(struct aead_request *req, 2795a6061921SPascal van Leeuwen enum safexcel_cipher_direction dir) 2796a6061921SPascal van Leeuwen { 2797a6061921SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 2798a6061921SPascal van Leeuwen struct crypto_aead *aead = crypto_aead_reqtfm(req); 2799a6061921SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(aead); 2800a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2801a6061921SPascal van Leeuwen struct aead_request *subreq = aead_request_ctx(req); 2802a6061921SPascal van Leeuwen u32 key[CHACHA_KEY_SIZE / sizeof(u32) + 1]; 280313a1bb93SPascal van Leeuwen int ret = 0; 2804a6061921SPascal van Leeuwen 2805a6061921SPascal van Leeuwen /* 2806a6061921SPascal van Leeuwen * Instead of wasting time detecting umpteen silly corner cases, 2807a6061921SPascal van Leeuwen * just dump all "small" requests to the fallback implementation. 2808a6061921SPascal van Leeuwen * HW would not be faster on such small requests anyway. 2809a6061921SPascal van Leeuwen */ 2810a6061921SPascal van Leeuwen if (likely((ctx->aead != EIP197_AEAD_TYPE_IPSEC_ESP || 2811a6061921SPascal van Leeuwen req->assoclen >= EIP197_AEAD_IPSEC_IV_SIZE) && 2812a6061921SPascal van Leeuwen req->cryptlen > POLY1305_DIGEST_SIZE)) { 2813a6061921SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, dir); 2814a6061921SPascal van Leeuwen } 2815a6061921SPascal van Leeuwen 2816a6061921SPascal van Leeuwen /* HW cannot do full (AAD+payload) zero length, use fallback */ 281713a1bb93SPascal van Leeuwen memcpy(key, ctx->key, CHACHA_KEY_SIZE); 2818a6061921SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 2819a6061921SPascal van Leeuwen /* ESP variant has nonce appended to the key */ 2820a6061921SPascal van Leeuwen key[CHACHA_KEY_SIZE / sizeof(u32)] = ctx->nonce; 2821a6061921SPascal van Leeuwen ret = crypto_aead_setkey(ctx->fback, (u8 *)key, 2822a6061921SPascal van Leeuwen CHACHA_KEY_SIZE + 2823a6061921SPascal van Leeuwen EIP197_AEAD_IPSEC_NONCE_SIZE); 2824a6061921SPascal van Leeuwen } else { 2825a6061921SPascal van Leeuwen ret = crypto_aead_setkey(ctx->fback, (u8 *)key, 2826a6061921SPascal van Leeuwen CHACHA_KEY_SIZE); 2827a6061921SPascal van Leeuwen } 2828a6061921SPascal van Leeuwen if (ret) { 2829a6061921SPascal van Leeuwen crypto_aead_clear_flags(aead, CRYPTO_TFM_REQ_MASK); 2830a6061921SPascal van Leeuwen crypto_aead_set_flags(aead, crypto_aead_get_flags(ctx->fback) & 2831a6061921SPascal van Leeuwen CRYPTO_TFM_REQ_MASK); 2832a6061921SPascal van Leeuwen return ret; 2833a6061921SPascal van Leeuwen } 2834a6061921SPascal van Leeuwen 2835a6061921SPascal van Leeuwen aead_request_set_tfm(subreq, ctx->fback); 2836a6061921SPascal van Leeuwen aead_request_set_callback(subreq, req->base.flags, req->base.complete, 2837a6061921SPascal van Leeuwen req->base.data); 2838a6061921SPascal van Leeuwen aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 2839a6061921SPascal van Leeuwen req->iv); 2840a6061921SPascal van Leeuwen aead_request_set_ad(subreq, req->assoclen); 2841a6061921SPascal van Leeuwen 2842a6061921SPascal van Leeuwen return (dir == SAFEXCEL_ENCRYPT) ? 2843a6061921SPascal van Leeuwen crypto_aead_encrypt(subreq) : 2844a6061921SPascal van Leeuwen crypto_aead_decrypt(subreq); 2845a6061921SPascal van Leeuwen } 2846a6061921SPascal van Leeuwen 2847a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_encrypt(struct aead_request *req) 2848a6061921SPascal van Leeuwen { 2849a6061921SPascal van Leeuwen return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_ENCRYPT); 2850a6061921SPascal van Leeuwen } 2851a6061921SPascal van Leeuwen 2852a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_decrypt(struct aead_request *req) 2853a6061921SPascal van Leeuwen { 2854a6061921SPascal van Leeuwen return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_DECRYPT); 2855a6061921SPascal van Leeuwen } 2856a6061921SPascal van Leeuwen 28571769f704SPascal van Leeuwen static int safexcel_aead_fallback_cra_init(struct crypto_tfm *tfm) 2858a6061921SPascal van Leeuwen { 2859a6061921SPascal van Leeuwen struct crypto_aead *aead = __crypto_aead_cast(tfm); 2860a6061921SPascal van Leeuwen struct aead_alg *alg = crypto_aead_alg(aead); 2861a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2862a6061921SPascal van Leeuwen 2863a6061921SPascal van Leeuwen safexcel_aead_cra_init(tfm); 2864a6061921SPascal van Leeuwen 2865a6061921SPascal van Leeuwen /* Allocate fallback implementation */ 2866a6061921SPascal van Leeuwen ctx->fback = crypto_alloc_aead(alg->base.cra_name, 0, 2867a6061921SPascal van Leeuwen CRYPTO_ALG_ASYNC | 2868a6061921SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK); 2869a6061921SPascal van Leeuwen if (IS_ERR(ctx->fback)) 2870a6061921SPascal van Leeuwen return PTR_ERR(ctx->fback); 2871a6061921SPascal van Leeuwen 2872a6061921SPascal van Leeuwen crypto_aead_set_reqsize(aead, max(sizeof(struct safexcel_cipher_req), 2873a6061921SPascal van Leeuwen sizeof(struct aead_request) + 2874a6061921SPascal van Leeuwen crypto_aead_reqsize(ctx->fback))); 2875a6061921SPascal van Leeuwen 2876a6061921SPascal van Leeuwen return 0; 2877a6061921SPascal van Leeuwen } 2878a6061921SPascal van Leeuwen 28791769f704SPascal van Leeuwen static int safexcel_aead_chachapoly_cra_init(struct crypto_tfm *tfm) 28801769f704SPascal van Leeuwen { 28811769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 28821769f704SPascal van Leeuwen 28831769f704SPascal van Leeuwen safexcel_aead_fallback_cra_init(tfm); 28841769f704SPascal van Leeuwen ctx->alg = SAFEXCEL_CHACHA20; 28851769f704SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32 | 28861769f704SPascal van Leeuwen CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK; 28871769f704SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_POLY1305; 28881769f704SPascal van Leeuwen ctx->state_sz = 0; /* Precomputed by HW */ 28891769f704SPascal van Leeuwen return 0; 28901769f704SPascal van Leeuwen } 28911769f704SPascal van Leeuwen 28921769f704SPascal van Leeuwen static void safexcel_aead_fallback_cra_exit(struct crypto_tfm *tfm) 2893a6061921SPascal van Leeuwen { 2894a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2895a6061921SPascal van Leeuwen 2896a6061921SPascal van Leeuwen crypto_free_aead(ctx->fback); 2897a6061921SPascal van Leeuwen safexcel_aead_cra_exit(tfm); 2898a6061921SPascal van Leeuwen } 2899a6061921SPascal van Leeuwen 2900a6061921SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chachapoly = { 2901a6061921SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2902a6061921SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, 2903a6061921SPascal van Leeuwen .alg.aead = { 2904a6061921SPascal van Leeuwen .setkey = safexcel_aead_chachapoly_setkey, 2905a6061921SPascal van Leeuwen .setauthsize = safexcel_aead_chachapoly_setauthsize, 2906a6061921SPascal van Leeuwen .encrypt = safexcel_aead_chachapoly_encrypt, 2907a6061921SPascal van Leeuwen .decrypt = safexcel_aead_chachapoly_decrypt, 2908a6061921SPascal van Leeuwen .ivsize = CHACHAPOLY_IV_SIZE, 2909a6061921SPascal van Leeuwen .maxauthsize = POLY1305_DIGEST_SIZE, 2910a6061921SPascal van Leeuwen .base = { 2911a6061921SPascal van Leeuwen .cra_name = "rfc7539(chacha20,poly1305)", 2912a6061921SPascal van Leeuwen .cra_driver_name = "safexcel-chacha20-poly1305", 2913a6061921SPascal van Leeuwen /* +1 to put it above HW chacha + SW poly */ 2914a6061921SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, 2915a6061921SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2916a6061921SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY | 2917a6061921SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK, 2918a6061921SPascal van Leeuwen .cra_blocksize = 1, 2919a6061921SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2920a6061921SPascal van Leeuwen .cra_alignmask = 0, 2921a6061921SPascal van Leeuwen .cra_init = safexcel_aead_chachapoly_cra_init, 29221769f704SPascal van Leeuwen .cra_exit = safexcel_aead_fallback_cra_exit, 2923a6061921SPascal van Leeuwen .cra_module = THIS_MODULE, 2924a6061921SPascal van Leeuwen }, 2925a6061921SPascal van Leeuwen }, 2926a6061921SPascal van Leeuwen }; 2927a6061921SPascal van Leeuwen 2928a6061921SPascal van Leeuwen static int safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm *tfm) 2929a6061921SPascal van Leeuwen { 2930a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2931a6061921SPascal van Leeuwen int ret; 2932a6061921SPascal van Leeuwen 2933a6061921SPascal van Leeuwen ret = safexcel_aead_chachapoly_cra_init(tfm); 2934a6061921SPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 2935a6061921SPascal van Leeuwen return ret; 2936a6061921SPascal van Leeuwen } 2937a6061921SPascal van Leeuwen 2938a6061921SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chachapoly_esp = { 2939a6061921SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2940a6061921SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, 2941a6061921SPascal van Leeuwen .alg.aead = { 2942a6061921SPascal van Leeuwen .setkey = safexcel_aead_chachapoly_setkey, 2943a6061921SPascal van Leeuwen .setauthsize = safexcel_aead_chachapoly_setauthsize, 2944a6061921SPascal van Leeuwen .encrypt = safexcel_aead_chachapoly_encrypt, 2945a6061921SPascal van Leeuwen .decrypt = safexcel_aead_chachapoly_decrypt, 2946a6061921SPascal van Leeuwen .ivsize = CHACHAPOLY_IV_SIZE - EIP197_AEAD_IPSEC_NONCE_SIZE, 2947a6061921SPascal van Leeuwen .maxauthsize = POLY1305_DIGEST_SIZE, 2948a6061921SPascal van Leeuwen .base = { 2949a6061921SPascal van Leeuwen .cra_name = "rfc7539esp(chacha20,poly1305)", 2950a6061921SPascal van Leeuwen .cra_driver_name = "safexcel-chacha20-poly1305-esp", 2951a6061921SPascal van Leeuwen /* +1 to put it above HW chacha + SW poly */ 2952a6061921SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, 2953a6061921SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2954a6061921SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY | 2955a6061921SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK, 2956a6061921SPascal van Leeuwen .cra_blocksize = 1, 2957a6061921SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2958a6061921SPascal van Leeuwen .cra_alignmask = 0, 2959a6061921SPascal van Leeuwen .cra_init = safexcel_aead_chachapolyesp_cra_init, 29601769f704SPascal van Leeuwen .cra_exit = safexcel_aead_fallback_cra_exit, 2961a6061921SPascal van Leeuwen .cra_module = THIS_MODULE, 2962a6061921SPascal van Leeuwen }, 2963a6061921SPascal van Leeuwen }, 2964a6061921SPascal van Leeuwen }; 2965fcca797dSPascal van Leeuwen 2966fcca797dSPascal van Leeuwen static int safexcel_skcipher_sm4_setkey(struct crypto_skcipher *ctfm, 2967fcca797dSPascal van Leeuwen const u8 *key, unsigned int len) 2968fcca797dSPascal van Leeuwen { 2969fcca797dSPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 2970fcca797dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2971fcca797dSPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 2972fcca797dSPascal van Leeuwen 2973fcca797dSPascal van Leeuwen if (len != SM4_KEY_SIZE) { 2974fcca797dSPascal van Leeuwen crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 2975fcca797dSPascal van Leeuwen return -EINVAL; 2976fcca797dSPascal van Leeuwen } 2977fcca797dSPascal van Leeuwen 297813a1bb93SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 297913a1bb93SPascal van Leeuwen if (memcmp(ctx->key, key, SM4_KEY_SIZE)) 2980fcca797dSPascal van Leeuwen ctx->base.needs_inv = true; 2981fcca797dSPascal van Leeuwen 298213a1bb93SPascal van Leeuwen memcpy(ctx->key, key, SM4_KEY_SIZE); 2983fcca797dSPascal van Leeuwen ctx->key_len = SM4_KEY_SIZE; 2984fcca797dSPascal van Leeuwen 2985fcca797dSPascal van Leeuwen return 0; 2986fcca797dSPascal van Leeuwen } 2987fcca797dSPascal van Leeuwen 2988fcca797dSPascal van Leeuwen static int safexcel_sm4_blk_encrypt(struct skcipher_request *req) 2989fcca797dSPascal van Leeuwen { 2990fcca797dSPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 2991fcca797dSPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 2992fcca797dSPascal van Leeuwen return -EINVAL; 2993fcca797dSPascal van Leeuwen else 2994fcca797dSPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 2995fcca797dSPascal van Leeuwen SAFEXCEL_ENCRYPT); 2996fcca797dSPascal van Leeuwen } 2997fcca797dSPascal van Leeuwen 2998fcca797dSPascal van Leeuwen static int safexcel_sm4_blk_decrypt(struct skcipher_request *req) 2999fcca797dSPascal van Leeuwen { 3000fcca797dSPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 3001fcca797dSPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 3002fcca797dSPascal van Leeuwen return -EINVAL; 3003fcca797dSPascal van Leeuwen else 3004fcca797dSPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 3005fcca797dSPascal van Leeuwen SAFEXCEL_DECRYPT); 3006fcca797dSPascal van Leeuwen } 3007fcca797dSPascal van Leeuwen 3008fcca797dSPascal van Leeuwen static int safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm *tfm) 3009fcca797dSPascal van Leeuwen { 3010fcca797dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3011fcca797dSPascal van Leeuwen 3012fcca797dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 3013fcca797dSPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3014fcca797dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 3015fcca797dSPascal van Leeuwen return 0; 3016fcca797dSPascal van Leeuwen } 3017fcca797dSPascal van Leeuwen 3018fcca797dSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ecb_sm4 = { 3019fcca797dSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 3020fcca797dSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4, 3021fcca797dSPascal van Leeuwen .alg.skcipher = { 3022fcca797dSPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 3023fcca797dSPascal van Leeuwen .encrypt = safexcel_sm4_blk_encrypt, 3024fcca797dSPascal van Leeuwen .decrypt = safexcel_sm4_blk_decrypt, 3025fcca797dSPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 3026fcca797dSPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 3027fcca797dSPascal van Leeuwen .base = { 3028fcca797dSPascal van Leeuwen .cra_name = "ecb(sm4)", 3029fcca797dSPascal van Leeuwen .cra_driver_name = "safexcel-ecb-sm4", 3030fcca797dSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3031fcca797dSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3032fcca797dSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3033fcca797dSPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 3034fcca797dSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3035fcca797dSPascal van Leeuwen .cra_alignmask = 0, 3036fcca797dSPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_ecb_cra_init, 3037fcca797dSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 3038fcca797dSPascal van Leeuwen .cra_module = THIS_MODULE, 3039fcca797dSPascal van Leeuwen }, 3040fcca797dSPascal van Leeuwen }, 3041fcca797dSPascal van Leeuwen }; 30426f2d1428SPascal van Leeuwen 30436f2d1428SPascal van Leeuwen static int safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm *tfm) 30446f2d1428SPascal van Leeuwen { 30456f2d1428SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 30466f2d1428SPascal van Leeuwen 30476f2d1428SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 30486f2d1428SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 30496f2d1428SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 30506f2d1428SPascal van Leeuwen return 0; 30516f2d1428SPascal van Leeuwen } 30526f2d1428SPascal van Leeuwen 30536f2d1428SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cbc_sm4 = { 30546f2d1428SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 30556f2d1428SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4, 30566f2d1428SPascal van Leeuwen .alg.skcipher = { 30576f2d1428SPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 30586f2d1428SPascal van Leeuwen .encrypt = safexcel_sm4_blk_encrypt, 30596f2d1428SPascal van Leeuwen .decrypt = safexcel_sm4_blk_decrypt, 30606f2d1428SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 30616f2d1428SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 30626f2d1428SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 30636f2d1428SPascal van Leeuwen .base = { 30646f2d1428SPascal van Leeuwen .cra_name = "cbc(sm4)", 30656f2d1428SPascal van Leeuwen .cra_driver_name = "safexcel-cbc-sm4", 30666f2d1428SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 30676f2d1428SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 30686f2d1428SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 30696f2d1428SPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 30706f2d1428SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 30716f2d1428SPascal van Leeuwen .cra_alignmask = 0, 30726f2d1428SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_cbc_cra_init, 30736f2d1428SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 30746f2d1428SPascal van Leeuwen .cra_module = THIS_MODULE, 30756f2d1428SPascal van Leeuwen }, 30766f2d1428SPascal van Leeuwen }, 30776f2d1428SPascal van Leeuwen }; 307803a6cfb9SPascal van Leeuwen 307903a6cfb9SPascal van Leeuwen static int safexcel_skcipher_sm4_ofb_cra_init(struct crypto_tfm *tfm) 308003a6cfb9SPascal van Leeuwen { 308103a6cfb9SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 308203a6cfb9SPascal van Leeuwen 308303a6cfb9SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 308403a6cfb9SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 308503a6cfb9SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; 308603a6cfb9SPascal van Leeuwen return 0; 308703a6cfb9SPascal van Leeuwen } 308803a6cfb9SPascal van Leeuwen 308903a6cfb9SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ofb_sm4 = { 309003a6cfb9SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 309103a6cfb9SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, 309203a6cfb9SPascal van Leeuwen .alg.skcipher = { 309303a6cfb9SPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 309403a6cfb9SPascal van Leeuwen .encrypt = safexcel_encrypt, 309503a6cfb9SPascal van Leeuwen .decrypt = safexcel_decrypt, 309603a6cfb9SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 309703a6cfb9SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 309803a6cfb9SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 309903a6cfb9SPascal van Leeuwen .base = { 310003a6cfb9SPascal van Leeuwen .cra_name = "ofb(sm4)", 310103a6cfb9SPascal van Leeuwen .cra_driver_name = "safexcel-ofb-sm4", 310203a6cfb9SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 310303a6cfb9SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 310403a6cfb9SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 310503a6cfb9SPascal van Leeuwen .cra_blocksize = 1, 310603a6cfb9SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 310703a6cfb9SPascal van Leeuwen .cra_alignmask = 0, 310803a6cfb9SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_ofb_cra_init, 310903a6cfb9SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 311003a6cfb9SPascal van Leeuwen .cra_module = THIS_MODULE, 311103a6cfb9SPascal van Leeuwen }, 311203a6cfb9SPascal van Leeuwen }, 311303a6cfb9SPascal van Leeuwen }; 31147468ab22SPascal van Leeuwen 31157468ab22SPascal van Leeuwen static int safexcel_skcipher_sm4_cfb_cra_init(struct crypto_tfm *tfm) 31167468ab22SPascal van Leeuwen { 31177468ab22SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 31187468ab22SPascal van Leeuwen 31197468ab22SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 31207468ab22SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 31217468ab22SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; 31227468ab22SPascal van Leeuwen return 0; 31237468ab22SPascal van Leeuwen } 31247468ab22SPascal van Leeuwen 31257468ab22SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cfb_sm4 = { 31267468ab22SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 31277468ab22SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, 31287468ab22SPascal van Leeuwen .alg.skcipher = { 31297468ab22SPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 31307468ab22SPascal van Leeuwen .encrypt = safexcel_encrypt, 31317468ab22SPascal van Leeuwen .decrypt = safexcel_decrypt, 31327468ab22SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 31337468ab22SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 31347468ab22SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 31357468ab22SPascal van Leeuwen .base = { 31367468ab22SPascal van Leeuwen .cra_name = "cfb(sm4)", 31377468ab22SPascal van Leeuwen .cra_driver_name = "safexcel-cfb-sm4", 31387468ab22SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 31397468ab22SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 31407468ab22SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 31417468ab22SPascal van Leeuwen .cra_blocksize = 1, 31427468ab22SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 31437468ab22SPascal van Leeuwen .cra_alignmask = 0, 31447468ab22SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_cfb_cra_init, 31457468ab22SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 31467468ab22SPascal van Leeuwen .cra_module = THIS_MODULE, 31477468ab22SPascal van Leeuwen }, 31487468ab22SPascal van Leeuwen }, 31497468ab22SPascal van Leeuwen }; 3150f77e5dc0SPascal van Leeuwen 3151f77e5dc0SPascal van Leeuwen static int safexcel_skcipher_sm4ctr_setkey(struct crypto_skcipher *ctfm, 3152f77e5dc0SPascal van Leeuwen const u8 *key, unsigned int len) 3153f77e5dc0SPascal van Leeuwen { 3154f77e5dc0SPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 3155f77e5dc0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3156f77e5dc0SPascal van Leeuwen 3157f77e5dc0SPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 3158f77e5dc0SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 3159f77e5dc0SPascal van Leeuwen /* exclude the nonce here */ 3160f77e5dc0SPascal van Leeuwen len -= CTR_RFC3686_NONCE_SIZE; 3161f77e5dc0SPascal van Leeuwen 3162f77e5dc0SPascal van Leeuwen return safexcel_skcipher_sm4_setkey(ctfm, key, len); 3163f77e5dc0SPascal van Leeuwen } 3164f77e5dc0SPascal van Leeuwen 3165f77e5dc0SPascal van Leeuwen static int safexcel_skcipher_sm4_ctr_cra_init(struct crypto_tfm *tfm) 3166f77e5dc0SPascal van Leeuwen { 3167f77e5dc0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3168f77e5dc0SPascal van Leeuwen 3169f77e5dc0SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 3170f77e5dc0SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3171f77e5dc0SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 3172f77e5dc0SPascal van Leeuwen return 0; 3173f77e5dc0SPascal van Leeuwen } 3174f77e5dc0SPascal van Leeuwen 3175f77e5dc0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ctr_sm4 = { 3176f77e5dc0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 3177f77e5dc0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4, 3178f77e5dc0SPascal van Leeuwen .alg.skcipher = { 3179f77e5dc0SPascal van Leeuwen .setkey = safexcel_skcipher_sm4ctr_setkey, 3180f77e5dc0SPascal van Leeuwen .encrypt = safexcel_encrypt, 3181f77e5dc0SPascal van Leeuwen .decrypt = safexcel_decrypt, 3182f77e5dc0SPascal van Leeuwen /* Add nonce size */ 3183f77e5dc0SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 3184f77e5dc0SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 3185f77e5dc0SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 3186f77e5dc0SPascal van Leeuwen .base = { 3187f77e5dc0SPascal van Leeuwen .cra_name = "rfc3686(ctr(sm4))", 3188f77e5dc0SPascal van Leeuwen .cra_driver_name = "safexcel-ctr-sm4", 3189f77e5dc0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3190f77e5dc0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3191f77e5dc0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3192f77e5dc0SPascal van Leeuwen .cra_blocksize = 1, 3193f77e5dc0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3194f77e5dc0SPascal van Leeuwen .cra_alignmask = 0, 3195f77e5dc0SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_ctr_cra_init, 3196f77e5dc0SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 3197f77e5dc0SPascal van Leeuwen .cra_module = THIS_MODULE, 3198f77e5dc0SPascal van Leeuwen }, 3199f77e5dc0SPascal van Leeuwen }, 3200f77e5dc0SPascal van Leeuwen }; 32011769f704SPascal van Leeuwen 32021769f704SPascal van Leeuwen static int safexcel_aead_sm4_blk_encrypt(struct aead_request *req) 32031769f704SPascal van Leeuwen { 32041769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 32051769f704SPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 32061769f704SPascal van Leeuwen return -EINVAL; 32071769f704SPascal van Leeuwen 32081769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, aead_request_ctx(req), 32091769f704SPascal van Leeuwen SAFEXCEL_ENCRYPT); 32101769f704SPascal van Leeuwen } 32111769f704SPascal van Leeuwen 32121769f704SPascal van Leeuwen static int safexcel_aead_sm4_blk_decrypt(struct aead_request *req) 32131769f704SPascal van Leeuwen { 32141769f704SPascal van Leeuwen struct crypto_aead *tfm = crypto_aead_reqtfm(req); 32151769f704SPascal van Leeuwen 32161769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 32171769f704SPascal van Leeuwen if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) 32181769f704SPascal van Leeuwen return -EINVAL; 32191769f704SPascal van Leeuwen 32201769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, aead_request_ctx(req), 32211769f704SPascal van Leeuwen SAFEXCEL_DECRYPT); 32221769f704SPascal van Leeuwen } 32231769f704SPascal van Leeuwen 32241769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sha1_cra_init(struct crypto_tfm *tfm) 32251769f704SPascal van Leeuwen { 32261769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 32271769f704SPascal van Leeuwen 32281769f704SPascal van Leeuwen safexcel_aead_cra_init(tfm); 32291769f704SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 32301769f704SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; 32311769f704SPascal van Leeuwen ctx->state_sz = SHA1_DIGEST_SIZE; 32321769f704SPascal van Leeuwen return 0; 32331769f704SPascal van Leeuwen } 32341769f704SPascal van Leeuwen 32351769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4 = { 32361769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 32371769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, 32381769f704SPascal van Leeuwen .alg.aead = { 32391769f704SPascal van Leeuwen .setkey = safexcel_aead_setkey, 32401769f704SPascal van Leeuwen .encrypt = safexcel_aead_sm4_blk_encrypt, 32411769f704SPascal van Leeuwen .decrypt = safexcel_aead_sm4_blk_decrypt, 32421769f704SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 32431769f704SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 32441769f704SPascal van Leeuwen .base = { 32451769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),cbc(sm4))", 32461769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-sm4", 32471769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 32481769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 32491769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 32501769f704SPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 32511769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 32521769f704SPascal van Leeuwen .cra_alignmask = 0, 32531769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4cbc_sha1_cra_init, 32541769f704SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 32551769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 32561769f704SPascal van Leeuwen }, 32571769f704SPascal van Leeuwen }, 32581769f704SPascal van Leeuwen }; 32591769f704SPascal van Leeuwen 32601769f704SPascal van Leeuwen static int safexcel_aead_fallback_setkey(struct crypto_aead *ctfm, 32611769f704SPascal van Leeuwen const u8 *key, unsigned int len) 32621769f704SPascal van Leeuwen { 32631769f704SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 32641769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 32651769f704SPascal van Leeuwen 32661769f704SPascal van Leeuwen /* Keep fallback cipher synchronized */ 32671769f704SPascal van Leeuwen return crypto_aead_setkey(ctx->fback, (u8 *)key, len) ?: 32681769f704SPascal van Leeuwen safexcel_aead_setkey(ctfm, key, len); 32691769f704SPascal van Leeuwen } 32701769f704SPascal van Leeuwen 32711769f704SPascal van Leeuwen static int safexcel_aead_fallback_setauthsize(struct crypto_aead *ctfm, 32721769f704SPascal van Leeuwen unsigned int authsize) 32731769f704SPascal van Leeuwen { 32741769f704SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 32751769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 32761769f704SPascal van Leeuwen 32771769f704SPascal van Leeuwen /* Keep fallback cipher synchronized */ 32781769f704SPascal van Leeuwen return crypto_aead_setauthsize(ctx->fback, authsize); 32791769f704SPascal van Leeuwen } 32801769f704SPascal van Leeuwen 32811769f704SPascal van Leeuwen static int safexcel_aead_fallback_crypt(struct aead_request *req, 32821769f704SPascal van Leeuwen enum safexcel_cipher_direction dir) 32831769f704SPascal van Leeuwen { 32841769f704SPascal van Leeuwen struct crypto_aead *aead = crypto_aead_reqtfm(req); 32851769f704SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(aead); 32861769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 32871769f704SPascal van Leeuwen struct aead_request *subreq = aead_request_ctx(req); 32881769f704SPascal van Leeuwen 32891769f704SPascal van Leeuwen aead_request_set_tfm(subreq, ctx->fback); 32901769f704SPascal van Leeuwen aead_request_set_callback(subreq, req->base.flags, req->base.complete, 32911769f704SPascal van Leeuwen req->base.data); 32921769f704SPascal van Leeuwen aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 32931769f704SPascal van Leeuwen req->iv); 32941769f704SPascal van Leeuwen aead_request_set_ad(subreq, req->assoclen); 32951769f704SPascal van Leeuwen 32961769f704SPascal van Leeuwen return (dir == SAFEXCEL_ENCRYPT) ? 32971769f704SPascal van Leeuwen crypto_aead_encrypt(subreq) : 32981769f704SPascal van Leeuwen crypto_aead_decrypt(subreq); 32991769f704SPascal van Leeuwen } 33001769f704SPascal van Leeuwen 33011769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request *req) 33021769f704SPascal van Leeuwen { 33031769f704SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 33041769f704SPascal van Leeuwen 33051769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 33061769f704SPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 33071769f704SPascal van Leeuwen return -EINVAL; 33081769f704SPascal van Leeuwen else if (req->cryptlen || req->assoclen) /* If input length > 0 only */ 33091769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 33101769f704SPascal van Leeuwen 33111769f704SPascal van Leeuwen /* HW cannot do full (AAD+payload) zero length, use fallback */ 33121769f704SPascal van Leeuwen return safexcel_aead_fallback_crypt(req, SAFEXCEL_ENCRYPT); 33131769f704SPascal van Leeuwen } 33141769f704SPascal van Leeuwen 33151769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request *req) 33161769f704SPascal van Leeuwen { 33171769f704SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 33181769f704SPascal van Leeuwen struct crypto_aead *tfm = crypto_aead_reqtfm(req); 33191769f704SPascal van Leeuwen 33201769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 33211769f704SPascal van Leeuwen if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) 33221769f704SPascal van Leeuwen return -EINVAL; 33231769f704SPascal van Leeuwen else if (req->cryptlen > crypto_aead_authsize(tfm) || req->assoclen) 33241769f704SPascal van Leeuwen /* If input length > 0 only */ 33251769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 33261769f704SPascal van Leeuwen 33271769f704SPascal van Leeuwen /* HW cannot do full (AAD+payload) zero length, use fallback */ 33281769f704SPascal van Leeuwen return safexcel_aead_fallback_crypt(req, SAFEXCEL_DECRYPT); 33291769f704SPascal van Leeuwen } 33301769f704SPascal van Leeuwen 33311769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm *tfm) 33321769f704SPascal van Leeuwen { 33331769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33341769f704SPascal van Leeuwen 33351769f704SPascal van Leeuwen safexcel_aead_fallback_cra_init(tfm); 33361769f704SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 33371769f704SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3; 33381769f704SPascal van Leeuwen ctx->state_sz = SM3_DIGEST_SIZE; 33391769f704SPascal van Leeuwen return 0; 33401769f704SPascal van Leeuwen } 33411769f704SPascal van Leeuwen 33421769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4 = { 33431769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 33441769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, 33451769f704SPascal van Leeuwen .alg.aead = { 33461769f704SPascal van Leeuwen .setkey = safexcel_aead_fallback_setkey, 33471769f704SPascal van Leeuwen .setauthsize = safexcel_aead_fallback_setauthsize, 33481769f704SPascal van Leeuwen .encrypt = safexcel_aead_sm4cbc_sm3_encrypt, 33491769f704SPascal van Leeuwen .decrypt = safexcel_aead_sm4cbc_sm3_decrypt, 33501769f704SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 33511769f704SPascal van Leeuwen .maxauthsize = SM3_DIGEST_SIZE, 33521769f704SPascal van Leeuwen .base = { 33531769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sm3),cbc(sm4))", 33541769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sm3-cbc-sm4", 33551769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 33561769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 33571769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY | 33581769f704SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK, 33591769f704SPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 33601769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 33611769f704SPascal van Leeuwen .cra_alignmask = 0, 33621769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4cbc_sm3_cra_init, 33631769f704SPascal van Leeuwen .cra_exit = safexcel_aead_fallback_cra_exit, 33641769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 33651769f704SPascal van Leeuwen }, 33661769f704SPascal van Leeuwen }, 33671769f704SPascal van Leeuwen }; 33681769f704SPascal van Leeuwen 33691769f704SPascal van Leeuwen static int safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm *tfm) 33701769f704SPascal van Leeuwen { 33711769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33721769f704SPascal van Leeuwen 33731769f704SPascal van Leeuwen safexcel_aead_sm4cbc_sha1_cra_init(tfm); 33741769f704SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 33751769f704SPascal van Leeuwen return 0; 33761769f704SPascal van Leeuwen } 33771769f704SPascal van Leeuwen 33781769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4 = { 33791769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 33801769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, 33811769f704SPascal van Leeuwen .alg.aead = { 33821769f704SPascal van Leeuwen .setkey = safexcel_aead_setkey, 33831769f704SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 33841769f704SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 33851769f704SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 33861769f704SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 33871769f704SPascal van Leeuwen .base = { 33881769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),rfc3686(ctr(sm4)))", 33891769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-sm4", 33901769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 33911769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 33921769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 33931769f704SPascal van Leeuwen .cra_blocksize = 1, 33941769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 33951769f704SPascal van Leeuwen .cra_alignmask = 0, 33961769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4ctr_sha1_cra_init, 33971769f704SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 33981769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 33991769f704SPascal van Leeuwen }, 34001769f704SPascal van Leeuwen }, 34011769f704SPascal van Leeuwen }; 34021769f704SPascal van Leeuwen 34031769f704SPascal van Leeuwen static int safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm *tfm) 34041769f704SPascal van Leeuwen { 34051769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 34061769f704SPascal van Leeuwen 34071769f704SPascal van Leeuwen safexcel_aead_sm4cbc_sm3_cra_init(tfm); 34081769f704SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 34091769f704SPascal van Leeuwen return 0; 34101769f704SPascal van Leeuwen } 34111769f704SPascal van Leeuwen 34121769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4 = { 34131769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 34141769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, 34151769f704SPascal van Leeuwen .alg.aead = { 34161769f704SPascal van Leeuwen .setkey = safexcel_aead_setkey, 34171769f704SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 34181769f704SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 34191769f704SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 34201769f704SPascal van Leeuwen .maxauthsize = SM3_DIGEST_SIZE, 34211769f704SPascal van Leeuwen .base = { 34221769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sm3),rfc3686(ctr(sm4)))", 34231769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sm3-ctr-sm4", 34241769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 34251769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 34261769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 34271769f704SPascal van Leeuwen .cra_blocksize = 1, 34281769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 34291769f704SPascal van Leeuwen .cra_alignmask = 0, 34301769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4ctr_sm3_cra_init, 34311769f704SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 34321769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 34331769f704SPascal van Leeuwen }, 34341769f704SPascal van Leeuwen }, 34351769f704SPascal van Leeuwen }; 3436a19052d4SPascal van Leeuwen 3437a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, 3438a19052d4SPascal van Leeuwen unsigned int len) 3439a19052d4SPascal van Leeuwen { 3440a19052d4SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 3441a19052d4SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3442a19052d4SPascal van Leeuwen 3443a19052d4SPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 3444a19052d4SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 3445a19052d4SPascal van Leeuwen 3446a19052d4SPascal van Leeuwen len -= CTR_RFC3686_NONCE_SIZE; 3447a19052d4SPascal van Leeuwen return safexcel_aead_gcm_setkey(ctfm, key, len); 3448a19052d4SPascal van Leeuwen } 3449a19052d4SPascal van Leeuwen 3450a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_setauthsize(struct crypto_aead *tfm, 3451a19052d4SPascal van Leeuwen unsigned int authsize) 3452a19052d4SPascal van Leeuwen { 3453a19052d4SPascal van Leeuwen return crypto_rfc4106_check_authsize(authsize); 3454a19052d4SPascal van Leeuwen } 3455a19052d4SPascal van Leeuwen 3456a19052d4SPascal van Leeuwen static int safexcel_rfc4106_encrypt(struct aead_request *req) 3457a19052d4SPascal van Leeuwen { 3458a19052d4SPascal van Leeuwen return crypto_ipsec_check_assoclen(req->assoclen) ?: 3459a19052d4SPascal van Leeuwen safexcel_aead_encrypt(req); 3460a19052d4SPascal van Leeuwen } 3461a19052d4SPascal van Leeuwen 3462a19052d4SPascal van Leeuwen static int safexcel_rfc4106_decrypt(struct aead_request *req) 3463a19052d4SPascal van Leeuwen { 3464a19052d4SPascal van Leeuwen return crypto_ipsec_check_assoclen(req->assoclen) ?: 3465a19052d4SPascal van Leeuwen safexcel_aead_decrypt(req); 3466a19052d4SPascal van Leeuwen } 3467a19052d4SPascal van Leeuwen 3468a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_cra_init(struct crypto_tfm *tfm) 3469a19052d4SPascal van Leeuwen { 3470a19052d4SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3471a19052d4SPascal van Leeuwen int ret; 3472a19052d4SPascal van Leeuwen 3473a19052d4SPascal van Leeuwen ret = safexcel_aead_gcm_cra_init(tfm); 3474a19052d4SPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 3475a19052d4SPascal van Leeuwen return ret; 3476a19052d4SPascal van Leeuwen } 3477a19052d4SPascal van Leeuwen 3478a19052d4SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4106_gcm = { 3479a19052d4SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3480a19052d4SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 3481a19052d4SPascal van Leeuwen .alg.aead = { 3482a19052d4SPascal van Leeuwen .setkey = safexcel_rfc4106_gcm_setkey, 3483a19052d4SPascal van Leeuwen .setauthsize = safexcel_rfc4106_gcm_setauthsize, 3484a19052d4SPascal van Leeuwen .encrypt = safexcel_rfc4106_encrypt, 3485a19052d4SPascal van Leeuwen .decrypt = safexcel_rfc4106_decrypt, 3486a19052d4SPascal van Leeuwen .ivsize = GCM_RFC4106_IV_SIZE, 3487a19052d4SPascal van Leeuwen .maxauthsize = GHASH_DIGEST_SIZE, 3488a19052d4SPascal van Leeuwen .base = { 3489a19052d4SPascal van Leeuwen .cra_name = "rfc4106(gcm(aes))", 3490a19052d4SPascal van Leeuwen .cra_driver_name = "safexcel-rfc4106-gcm-aes", 3491a19052d4SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3492a19052d4SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3493a19052d4SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3494a19052d4SPascal van Leeuwen .cra_blocksize = 1, 3495a19052d4SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3496a19052d4SPascal van Leeuwen .cra_alignmask = 0, 3497a19052d4SPascal van Leeuwen .cra_init = safexcel_rfc4106_gcm_cra_init, 3498a19052d4SPascal van Leeuwen .cra_exit = safexcel_aead_gcm_cra_exit, 3499a19052d4SPascal van Leeuwen }, 3500a19052d4SPascal van Leeuwen }, 3501a19052d4SPascal van Leeuwen }; 350292c60cefSPascal van Leeuwen 350392c60cefSPascal van Leeuwen static int safexcel_rfc4543_gcm_setauthsize(struct crypto_aead *tfm, 350492c60cefSPascal van Leeuwen unsigned int authsize) 350592c60cefSPascal van Leeuwen { 350692c60cefSPascal van Leeuwen if (authsize != GHASH_DIGEST_SIZE) 350792c60cefSPascal van Leeuwen return -EINVAL; 350892c60cefSPascal van Leeuwen 350992c60cefSPascal van Leeuwen return 0; 351092c60cefSPascal van Leeuwen } 351192c60cefSPascal van Leeuwen 351292c60cefSPascal van Leeuwen static int safexcel_rfc4543_gcm_cra_init(struct crypto_tfm *tfm) 351392c60cefSPascal van Leeuwen { 351492c60cefSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 351592c60cefSPascal van Leeuwen int ret; 351692c60cefSPascal van Leeuwen 351792c60cefSPascal van Leeuwen ret = safexcel_aead_gcm_cra_init(tfm); 351892c60cefSPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP_GMAC; 351992c60cefSPascal van Leeuwen return ret; 352092c60cefSPascal van Leeuwen } 352192c60cefSPascal van Leeuwen 352292c60cefSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4543_gcm = { 352392c60cefSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 352492c60cefSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 352592c60cefSPascal van Leeuwen .alg.aead = { 352692c60cefSPascal van Leeuwen .setkey = safexcel_rfc4106_gcm_setkey, 352792c60cefSPascal van Leeuwen .setauthsize = safexcel_rfc4543_gcm_setauthsize, 352892c60cefSPascal van Leeuwen .encrypt = safexcel_rfc4106_encrypt, 352992c60cefSPascal van Leeuwen .decrypt = safexcel_rfc4106_decrypt, 353092c60cefSPascal van Leeuwen .ivsize = GCM_RFC4543_IV_SIZE, 353192c60cefSPascal van Leeuwen .maxauthsize = GHASH_DIGEST_SIZE, 353292c60cefSPascal van Leeuwen .base = { 353392c60cefSPascal van Leeuwen .cra_name = "rfc4543(gcm(aes))", 353492c60cefSPascal van Leeuwen .cra_driver_name = "safexcel-rfc4543-gcm-aes", 353592c60cefSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 353692c60cefSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 353792c60cefSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 353892c60cefSPascal van Leeuwen .cra_blocksize = 1, 353992c60cefSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 354092c60cefSPascal van Leeuwen .cra_alignmask = 0, 354192c60cefSPascal van Leeuwen .cra_init = safexcel_rfc4543_gcm_cra_init, 354292c60cefSPascal van Leeuwen .cra_exit = safexcel_aead_gcm_cra_exit, 354392c60cefSPascal van Leeuwen }, 354492c60cefSPascal van Leeuwen }, 354592c60cefSPascal van Leeuwen }; 3546a9a89624SPascal van Leeuwen 3547a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, 3548a9a89624SPascal van Leeuwen unsigned int len) 3549a9a89624SPascal van Leeuwen { 3550a9a89624SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 3551a9a89624SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3552a9a89624SPascal van Leeuwen 3553a9a89624SPascal van Leeuwen /* First byte of the nonce = L = always 3 for RFC4309 (4 byte ctr) */ 3554a9a89624SPascal van Leeuwen *(u8 *)&ctx->nonce = EIP197_AEAD_IPSEC_COUNTER_SIZE - 1; 3555a9a89624SPascal van Leeuwen /* last 3 bytes of key are the nonce! */ 3556a9a89624SPascal van Leeuwen memcpy((u8 *)&ctx->nonce + 1, key + len - 3557a9a89624SPascal van Leeuwen EIP197_AEAD_IPSEC_CCM_NONCE_SIZE, 3558a9a89624SPascal van Leeuwen EIP197_AEAD_IPSEC_CCM_NONCE_SIZE); 3559a9a89624SPascal van Leeuwen 3560a9a89624SPascal van Leeuwen len -= EIP197_AEAD_IPSEC_CCM_NONCE_SIZE; 3561a9a89624SPascal van Leeuwen return safexcel_aead_ccm_setkey(ctfm, key, len); 3562a9a89624SPascal van Leeuwen } 3563a9a89624SPascal van Leeuwen 3564a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_setauthsize(struct crypto_aead *tfm, 3565a9a89624SPascal van Leeuwen unsigned int authsize) 3566a9a89624SPascal van Leeuwen { 3567a9a89624SPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 3568a9a89624SPascal van Leeuwen switch (authsize) { 3569a9a89624SPascal van Leeuwen case 8: 3570a9a89624SPascal van Leeuwen case 12: 3571a9a89624SPascal van Leeuwen case 16: 3572a9a89624SPascal van Leeuwen break; 3573a9a89624SPascal van Leeuwen default: 3574a9a89624SPascal van Leeuwen return -EINVAL; 3575a9a89624SPascal van Leeuwen } 3576a9a89624SPascal van Leeuwen 3577a9a89624SPascal van Leeuwen return 0; 3578a9a89624SPascal van Leeuwen } 3579a9a89624SPascal van Leeuwen 3580a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_encrypt(struct aead_request *req) 3581a9a89624SPascal van Leeuwen { 3582a9a89624SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 3583a9a89624SPascal van Leeuwen 3584a9a89624SPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 3585a9a89624SPascal van Leeuwen if (req->assoclen != 16 && req->assoclen != 20) 3586a9a89624SPascal van Leeuwen return -EINVAL; 3587a9a89624SPascal van Leeuwen 3588a9a89624SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 3589a9a89624SPascal van Leeuwen } 3590a9a89624SPascal van Leeuwen 3591a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_decrypt(struct aead_request *req) 3592a9a89624SPascal van Leeuwen { 3593a9a89624SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 3594a9a89624SPascal van Leeuwen 3595a9a89624SPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 3596a9a89624SPascal van Leeuwen if (req->assoclen != 16 && req->assoclen != 20) 3597a9a89624SPascal van Leeuwen return -EINVAL; 3598a9a89624SPascal van Leeuwen 3599a9a89624SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 3600a9a89624SPascal van Leeuwen } 3601a9a89624SPascal van Leeuwen 3602a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_cra_init(struct crypto_tfm *tfm) 3603a9a89624SPascal van Leeuwen { 3604a9a89624SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3605a9a89624SPascal van Leeuwen int ret; 3606a9a89624SPascal van Leeuwen 3607a9a89624SPascal van Leeuwen ret = safexcel_aead_ccm_cra_init(tfm); 3608a9a89624SPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 3609a9a89624SPascal van Leeuwen return ret; 3610a9a89624SPascal van Leeuwen } 3611a9a89624SPascal van Leeuwen 3612a9a89624SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4309_ccm = { 3613a9a89624SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3614a9a89624SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, 3615a9a89624SPascal van Leeuwen .alg.aead = { 3616a9a89624SPascal van Leeuwen .setkey = safexcel_rfc4309_ccm_setkey, 3617a9a89624SPascal van Leeuwen .setauthsize = safexcel_rfc4309_ccm_setauthsize, 3618a9a89624SPascal van Leeuwen .encrypt = safexcel_rfc4309_ccm_encrypt, 3619a9a89624SPascal van Leeuwen .decrypt = safexcel_rfc4309_ccm_decrypt, 3620a9a89624SPascal van Leeuwen .ivsize = EIP197_AEAD_IPSEC_IV_SIZE, 3621a9a89624SPascal van Leeuwen .maxauthsize = AES_BLOCK_SIZE, 3622a9a89624SPascal van Leeuwen .base = { 3623a9a89624SPascal van Leeuwen .cra_name = "rfc4309(ccm(aes))", 3624a9a89624SPascal van Leeuwen .cra_driver_name = "safexcel-rfc4309-ccm-aes", 3625a9a89624SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3626a9a89624SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3627a9a89624SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3628a9a89624SPascal van Leeuwen .cra_blocksize = 1, 3629a9a89624SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3630a9a89624SPascal van Leeuwen .cra_alignmask = 0, 3631a9a89624SPascal van Leeuwen .cra_init = safexcel_rfc4309_ccm_cra_init, 3632a9a89624SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 3633a9a89624SPascal van Leeuwen .cra_module = THIS_MODULE, 3634a9a89624SPascal van Leeuwen }, 3635a9a89624SPascal van Leeuwen }, 3636a9a89624SPascal van Leeuwen }; 3637