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; 50098e51e5SPascal van Leeuwen u8 aead; /* !=0=AEAD, 2=IPSec ESP AEAD, 3=IPsec ESP GMAC */ 51098e51e5SPascal van Leeuwen u8 xcm; /* 0=authenc, 1=GCM, 2 reserved for CCM */ 52098e51e5SPascal van Leeuwen u8 aadskip; 53098e51e5SPascal van Leeuwen u8 blocksz; 54098e51e5SPascal van Leeuwen u32 ivmask; 55098e51e5SPascal van Leeuwen u32 ctrinit; 561b44c5a6SAntoine Ténart 57c7da38a7SPascal van Leeuwen __le32 key[16]; 5854f9e8faSPascal van Leeuwen u32 nonce; 59c7da38a7SPascal van Leeuwen unsigned int key_len, xts; 60f6beaea3SAntoine Tenart 61f6beaea3SAntoine Tenart /* All the below is AEAD specific */ 62a7dea8c0SOfer Heifetz u32 hash_alg; 63f6beaea3SAntoine Tenart u32 state_sz; 643e450886SPascal van Leeuwen 653e450886SPascal van Leeuwen struct crypto_cipher *hkaes; 66a6061921SPascal van Leeuwen struct crypto_aead *fback; 671b44c5a6SAntoine Ténart }; 681b44c5a6SAntoine Ténart 691eb7b403SOfer Heifetz struct safexcel_cipher_req { 70847ccfc5SOfer Heifetz enum safexcel_cipher_direction direction; 7189332590SAntoine Tenart /* Number of result descriptors associated to the request */ 7289332590SAntoine Tenart unsigned int rdescs; 731eb7b403SOfer Heifetz bool needs_inv; 7419b347b3SPascal van Leeuwen int nr_src, nr_dst; 751eb7b403SOfer Heifetz }; 761eb7b403SOfer Heifetz 77098e51e5SPascal van Leeuwen static int safexcel_skcipher_iv(struct safexcel_cipher_ctx *ctx, u8 *iv, 780e17e362SPascal van Leeuwen struct safexcel_command_desc *cdesc) 791b44c5a6SAntoine Ténart { 80098e51e5SPascal van Leeuwen if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { 81493e289cSPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 82493e289cSPascal van Leeuwen /* 32 bit nonce */ 83493e289cSPascal van Leeuwen cdesc->control_data.token[0] = ctx->nonce; 84493e289cSPascal van Leeuwen /* 64 bit IV part */ 85493e289cSPascal van Leeuwen memcpy(&cdesc->control_data.token[1], iv, 8); 86098e51e5SPascal van Leeuwen /* 32 bit counter, start at 0 or 1 (big endian!) */ 8713a1bb93SPascal van Leeuwen cdesc->control_data.token[3] = 88098e51e5SPascal van Leeuwen (__force u32)cpu_to_be32(ctx->ctrinit); 89098e51e5SPascal van Leeuwen return 4; 90a19052d4SPascal van Leeuwen } 91a19052d4SPascal van Leeuwen if (ctx->alg == SAFEXCEL_CHACHA20) { 924a593fb3SPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 934a593fb3SPascal van Leeuwen /* 96 bit nonce part */ 944a593fb3SPascal van Leeuwen memcpy(&cdesc->control_data.token[0], &iv[4], 12); 954a593fb3SPascal van Leeuwen /* 32 bit counter */ 964a593fb3SPascal van Leeuwen cdesc->control_data.token[3] = *(u32 *)iv; 97098e51e5SPascal van Leeuwen return 4; 98493e289cSPascal van Leeuwen } 99493e289cSPascal van Leeuwen 100098e51e5SPascal van Leeuwen cdesc->control_data.options |= ctx->ivmask; 101098e51e5SPascal van Leeuwen memcpy(cdesc->control_data.token, iv, ctx->blocksz); 102098e51e5SPascal van Leeuwen return ctx->blocksz / sizeof(u32); 10354f9e8faSPascal van Leeuwen } 1040e17e362SPascal van Leeuwen 1050e17e362SPascal van Leeuwen static void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 1060e17e362SPascal van Leeuwen struct safexcel_command_desc *cdesc, 107098e51e5SPascal van Leeuwen struct safexcel_token *atoken, 1080e17e362SPascal van Leeuwen u32 length) 1090e17e362SPascal van Leeuwen { 1100e17e362SPascal van Leeuwen struct safexcel_token *token; 111098e51e5SPascal van Leeuwen int ivlen; 1120e17e362SPascal van Leeuwen 113098e51e5SPascal van Leeuwen ivlen = safexcel_skcipher_iv(ctx, iv, cdesc); 114098e51e5SPascal van Leeuwen if (ivlen == 4) { 115098e51e5SPascal van Leeuwen /* No space in cdesc, instruction moves to atoken */ 116098e51e5SPascal van Leeuwen cdesc->additional_cdata_size = 1; 117098e51e5SPascal van Leeuwen token = atoken; 118098e51e5SPascal van Leeuwen } else { 119098e51e5SPascal van Leeuwen /* Everything fits in cdesc */ 120098e51e5SPascal van Leeuwen token = (struct safexcel_token *)(cdesc->control_data.token + 2); 121098e51e5SPascal van Leeuwen /* Need to pad with NOP */ 122098e51e5SPascal van Leeuwen eip197_noop_token(&token[1]); 123098e51e5SPascal van Leeuwen } 1241b44c5a6SAntoine Ténart 125098e51e5SPascal van Leeuwen token->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 126098e51e5SPascal van Leeuwen token->packet_length = length; 127098e51e5SPascal van Leeuwen token->stat = EIP197_TOKEN_STAT_LAST_PACKET | 12815f64ee0SAntoine Tenart EIP197_TOKEN_STAT_LAST_HASH; 129098e51e5SPascal van Leeuwen token->instructions = EIP197_TOKEN_INS_LAST | 130a74d850fSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_CRYPTO | 1311b44c5a6SAntoine Ténart EIP197_TOKEN_INS_TYPE_OUTPUT; 1321b44c5a6SAntoine Ténart } 1331b44c5a6SAntoine Ténart 134098e51e5SPascal van Leeuwen static void safexcel_aead_iv(struct safexcel_cipher_ctx *ctx, u8 *iv, 135098e51e5SPascal van Leeuwen struct safexcel_command_desc *cdesc) 136098e51e5SPascal van Leeuwen { 137098e51e5SPascal van Leeuwen if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD || 138098e51e5SPascal van Leeuwen ctx->aead & EIP197_AEAD_TYPE_IPSEC_ESP) { /* _ESP and _ESP_GMAC */ 139098e51e5SPascal van Leeuwen /* 32 bit nonce */ 140098e51e5SPascal van Leeuwen cdesc->control_data.token[0] = ctx->nonce; 141098e51e5SPascal van Leeuwen /* 64 bit IV part */ 142098e51e5SPascal van Leeuwen memcpy(&cdesc->control_data.token[1], iv, 8); 143098e51e5SPascal van Leeuwen /* 32 bit counter, start at 0 or 1 (big endian!) */ 144098e51e5SPascal van Leeuwen cdesc->control_data.token[3] = 145098e51e5SPascal van Leeuwen (__force u32)cpu_to_be32(ctx->ctrinit); 146098e51e5SPascal van Leeuwen return; 147098e51e5SPascal van Leeuwen } 148098e51e5SPascal van Leeuwen if (ctx->xcm == EIP197_XCM_MODE_GCM || ctx->alg == SAFEXCEL_CHACHA20) { 149098e51e5SPascal van Leeuwen /* 96 bit IV part */ 150098e51e5SPascal van Leeuwen memcpy(&cdesc->control_data.token[0], iv, 12); 151098e51e5SPascal van Leeuwen /* 32 bit counter, start at 0 or 1 (big endian!) */ 152098e51e5SPascal van Leeuwen cdesc->control_data.token[3] = 153098e51e5SPascal van Leeuwen (__force u32)cpu_to_be32(ctx->ctrinit); 154098e51e5SPascal van Leeuwen return; 155098e51e5SPascal van Leeuwen } 156098e51e5SPascal van Leeuwen /* CBC */ 157098e51e5SPascal van Leeuwen memcpy(cdesc->control_data.token, iv, ctx->blocksz); 158098e51e5SPascal van Leeuwen } 159098e51e5SPascal van Leeuwen 160f6beaea3SAntoine Tenart static void safexcel_aead_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 161f6beaea3SAntoine Tenart struct safexcel_command_desc *cdesc, 162098e51e5SPascal van Leeuwen struct safexcel_token *atoken, 163f6beaea3SAntoine Tenart enum safexcel_cipher_direction direction, 164f6beaea3SAntoine Tenart u32 cryptlen, u32 assoclen, u32 digestsize) 165f6beaea3SAntoine Tenart { 166098e51e5SPascal van Leeuwen struct safexcel_token *aadref; 167098e51e5SPascal van Leeuwen int atoksize = 2; /* Start with minimum size */ 168098e51e5SPascal van Leeuwen int assocadj = assoclen - ctx->aadskip, aadalign; 169f6beaea3SAntoine Tenart 170098e51e5SPascal van Leeuwen /* Always 4 dwords of embedded IV for AEAD modes */ 171098e51e5SPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 172f6beaea3SAntoine Tenart 173098e51e5SPascal van Leeuwen if (direction == SAFEXCEL_DECRYPT) 174d2d9e6fdSPascal van Leeuwen cryptlen -= digestsize; 175d2d9e6fdSPascal van Leeuwen 176098e51e5SPascal van Leeuwen if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM)) { 177098e51e5SPascal van Leeuwen /* Construct IV block B0 for the CBC-MAC */ 178098e51e5SPascal van Leeuwen u8 *final_iv = (u8 *)cdesc->control_data.token; 179098e51e5SPascal van Leeuwen u8 *cbcmaciv = (u8 *)&atoken[1]; 180098e51e5SPascal van Leeuwen __le32 *aadlen = (__le32 *)&atoken[5]; 18154f9e8faSPascal van Leeuwen 182098e51e5SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 183098e51e5SPascal van Leeuwen /* Length + nonce */ 184098e51e5SPascal van Leeuwen cdesc->control_data.token[0] = ctx->nonce; 185098e51e5SPascal van Leeuwen /* Fixup flags byte */ 186098e51e5SPascal van Leeuwen *(__le32 *)cbcmaciv = 187098e51e5SPascal van Leeuwen cpu_to_le32(ctx->nonce | 188098e51e5SPascal van Leeuwen ((assocadj > 0) << 6) | 189098e51e5SPascal van Leeuwen ((digestsize - 2) << 2)); 190098e51e5SPascal van Leeuwen /* 64 bit IV part */ 191098e51e5SPascal van Leeuwen memcpy(&cdesc->control_data.token[1], iv, 8); 192098e51e5SPascal van Leeuwen memcpy(cbcmaciv + 4, iv, 8); 193098e51e5SPascal van Leeuwen /* Start counter at 0 */ 194098e51e5SPascal van Leeuwen cdesc->control_data.token[3] = 0; 195098e51e5SPascal van Leeuwen /* Message length */ 196098e51e5SPascal van Leeuwen *(__be32 *)(cbcmaciv + 12) = cpu_to_be32(cryptlen); 197098e51e5SPascal van Leeuwen } else { 198098e51e5SPascal van Leeuwen /* Variable length IV part */ 199098e51e5SPascal van Leeuwen memcpy(final_iv, iv, 15 - iv[0]); 200098e51e5SPascal van Leeuwen memcpy(cbcmaciv, iv, 15 - iv[0]); 201098e51e5SPascal van Leeuwen /* Start variable length counter at 0 */ 202098e51e5SPascal van Leeuwen memset(final_iv + 15 - iv[0], 0, iv[0] + 1); 203098e51e5SPascal van Leeuwen memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1); 204098e51e5SPascal van Leeuwen /* fixup flags byte */ 205098e51e5SPascal van Leeuwen cbcmaciv[0] |= ((assocadj > 0) << 6) | 206098e51e5SPascal van Leeuwen ((digestsize - 2) << 2); 207098e51e5SPascal van Leeuwen /* insert lower 2 bytes of message length */ 208098e51e5SPascal van Leeuwen cbcmaciv[14] = cryptlen >> 8; 209098e51e5SPascal van Leeuwen cbcmaciv[15] = cryptlen & 255; 210f6beaea3SAntoine Tenart } 21154f9e8faSPascal van Leeuwen 212098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 213098e51e5SPascal van Leeuwen atoken->packet_length = AES_BLOCK_SIZE + 214098e51e5SPascal van Leeuwen ((assocadj > 0) << 1); 215098e51e5SPascal van Leeuwen atoken->stat = 0; 216098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN | 217098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH; 218098e51e5SPascal van Leeuwen 219098e51e5SPascal van Leeuwen if (likely(assocadj)) { 220098e51e5SPascal van Leeuwen *aadlen = cpu_to_le32((assocadj >> 8) | 221098e51e5SPascal van Leeuwen (assocadj & 255) << 8); 222098e51e5SPascal van Leeuwen atoken += 6; 223098e51e5SPascal van Leeuwen atoksize += 7; 224098e51e5SPascal van Leeuwen } else { 225098e51e5SPascal van Leeuwen atoken += 5; 226098e51e5SPascal van Leeuwen atoksize += 6; 227098e51e5SPascal van Leeuwen } 228098e51e5SPascal van Leeuwen 229098e51e5SPascal van Leeuwen /* Process AAD data */ 230098e51e5SPascal van Leeuwen aadref = atoken; 231098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 232098e51e5SPascal van Leeuwen atoken->packet_length = assocadj; 233098e51e5SPascal van Leeuwen atoken->stat = 0; 234098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 235098e51e5SPascal van Leeuwen atoken++; 236098e51e5SPascal van Leeuwen 237098e51e5SPascal van Leeuwen /* For CCM only, align AAD data towards hash engine */ 238098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 239098e51e5SPascal van Leeuwen aadalign = (assocadj + 2) & 15; 240098e51e5SPascal van Leeuwen atoken->packet_length = assocadj && aadalign ? 241098e51e5SPascal van Leeuwen 16 - aadalign : 242098e51e5SPascal van Leeuwen 0; 243098e51e5SPascal van Leeuwen if (likely(cryptlen)) { 244098e51e5SPascal van Leeuwen atoken->stat = 0; 245098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 246098e51e5SPascal van Leeuwen } else { 247098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 248098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_LAST | 249098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH; 250098e51e5SPascal van Leeuwen } 251098e51e5SPascal van Leeuwen } else { 252098e51e5SPascal van Leeuwen safexcel_aead_iv(ctx, iv, cdesc); 253098e51e5SPascal van Leeuwen 254098e51e5SPascal van Leeuwen /* Process AAD data */ 255098e51e5SPascal van Leeuwen aadref = atoken; 256098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 257098e51e5SPascal van Leeuwen atoken->packet_length = assocadj; 258098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 259098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_LAST | 260098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH; 261098e51e5SPascal van Leeuwen } 262098e51e5SPascal van Leeuwen atoken++; 263098e51e5SPascal van Leeuwen 264a6061921SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 26592c60cefSPascal van Leeuwen /* For ESP mode (and not GMAC), skip over the IV */ 266098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 267098e51e5SPascal van Leeuwen atoken->packet_length = EIP197_AEAD_IPSEC_IV_SIZE; 268098e51e5SPascal van Leeuwen atoken->stat = 0; 269098e51e5SPascal van Leeuwen atoken->instructions = 0; 270098e51e5SPascal van Leeuwen atoken++; 271098e51e5SPascal van Leeuwen atoksize++; 272098e51e5SPascal van Leeuwen } else if (unlikely(ctx->alg == SAFEXCEL_CHACHA20 && 273098e51e5SPascal van Leeuwen direction == SAFEXCEL_DECRYPT)) { 274098e51e5SPascal van Leeuwen /* Poly-chacha decryption needs a dummy NOP here ... */ 275098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 276098e51e5SPascal van Leeuwen atoken->packet_length = 16; /* According to Op Manual */ 277098e51e5SPascal van Leeuwen atoken->stat = 0; 278098e51e5SPascal van Leeuwen atoken->instructions = 0; 279098e51e5SPascal van Leeuwen atoken++; 280098e51e5SPascal van Leeuwen atoksize++; 281a6061921SPascal van Leeuwen } 282a6061921SPascal van Leeuwen 283098e51e5SPascal van Leeuwen if (ctx->xcm) { 284098e51e5SPascal van Leeuwen /* For GCM and CCM, obtain enc(Y0) */ 285098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES; 286098e51e5SPascal van Leeuwen atoken->packet_length = 0; 287098e51e5SPascal van Leeuwen atoken->stat = 0; 288098e51e5SPascal van Leeuwen atoken->instructions = AES_BLOCK_SIZE; 289098e51e5SPascal van Leeuwen atoken++; 290098e51e5SPascal van Leeuwen 291098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 292098e51e5SPascal van Leeuwen atoken->packet_length = AES_BLOCK_SIZE; 293098e51e5SPascal van Leeuwen atoken->stat = 0; 294098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | 295098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_CRYPTO; 296098e51e5SPascal van Leeuwen atoken++; 297098e51e5SPascal van Leeuwen atoksize += 2; 298098e51e5SPascal van Leeuwen } 29954f9e8faSPascal van Leeuwen 300a6061921SPascal van Leeuwen if (likely(cryptlen || ctx->alg == SAFEXCEL_CHACHA20)) { 301098e51e5SPascal van Leeuwen /* Fixup stat field for AAD direction instruction */ 302098e51e5SPascal van Leeuwen aadref->stat = 0; 303098e51e5SPascal van Leeuwen 304098e51e5SPascal van Leeuwen /* Process crypto data */ 305098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 306098e51e5SPascal van Leeuwen atoken->packet_length = cryptlen; 307098e51e5SPascal van Leeuwen 30892c60cefSPascal van Leeuwen if (unlikely(ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) { 309098e51e5SPascal van Leeuwen /* Fixup instruction field for AAD dir instruction */ 310098e51e5SPascal van Leeuwen aadref->instructions = EIP197_TOKEN_INS_TYPE_HASH; 311098e51e5SPascal van Leeuwen 31292c60cefSPascal van Leeuwen /* Do not send to crypt engine in case of GMAC */ 313098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_LAST | 31492c60cefSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH | 31592c60cefSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_OUTPUT; 31692c60cefSPascal van Leeuwen } else { 317098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_LAST | 31854f9e8faSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_CRYPTO | 31954f9e8faSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH | 32054f9e8faSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_OUTPUT; 32192c60cefSPascal van Leeuwen } 3223e450886SPascal van Leeuwen 3234eb76fafSPascal van Leeuwen cryptlen &= 15; 324098e51e5SPascal van Leeuwen if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM && cryptlen)) { 325098e51e5SPascal van Leeuwen atoken->stat = 0; 326098e51e5SPascal van Leeuwen /* For CCM only, pad crypto data to the hash engine */ 327098e51e5SPascal van Leeuwen atoken++; 328098e51e5SPascal van Leeuwen atoksize++; 329098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 330098e51e5SPascal van Leeuwen atoken->packet_length = 16 - cryptlen; 331098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 332098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 3334eb76fafSPascal van Leeuwen } else { 334098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 3354eb76fafSPascal van Leeuwen } 336098e51e5SPascal van Leeuwen atoken++; 337098e51e5SPascal van Leeuwen atoksize++; 3383e450886SPascal van Leeuwen } 339098e51e5SPascal van Leeuwen 340098e51e5SPascal van Leeuwen if (direction == SAFEXCEL_ENCRYPT) { 341098e51e5SPascal van Leeuwen /* Append ICV */ 342098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 343098e51e5SPascal van Leeuwen atoken->packet_length = digestsize; 344098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 345098e51e5SPascal van Leeuwen EIP197_TOKEN_STAT_LAST_PACKET; 346098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | 347098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_INSERT_HASH_DIGEST; 348098e51e5SPascal van Leeuwen } else { 349098e51e5SPascal van Leeuwen /* Extract ICV */ 350098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_RETRIEVE; 351098e51e5SPascal van Leeuwen atoken->packet_length = digestsize; 352098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 353098e51e5SPascal van Leeuwen EIP197_TOKEN_STAT_LAST_PACKET; 354098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST; 355098e51e5SPascal van Leeuwen atoken++; 356098e51e5SPascal van Leeuwen atoksize++; 357098e51e5SPascal van Leeuwen 358098e51e5SPascal van Leeuwen /* Verify ICV */ 359098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_VERIFY; 360098e51e5SPascal van Leeuwen atoken->packet_length = digestsize | 361098e51e5SPascal van Leeuwen EIP197_TOKEN_HASH_RESULT_VERIFY; 362098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 363098e51e5SPascal van Leeuwen EIP197_TOKEN_STAT_LAST_PACKET; 364098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT; 365098e51e5SPascal van Leeuwen } 366098e51e5SPascal van Leeuwen 367098e51e5SPascal van Leeuwen /* Fixup length of the token in the command descriptor */ 368098e51e5SPascal van Leeuwen cdesc->additional_cdata_size = atoksize; 369f6beaea3SAntoine Tenart } 370f6beaea3SAntoine Tenart 3718ac1283eSAntoine Tenart static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm, 3728ac1283eSAntoine Tenart const u8 *key, unsigned int len) 3731b44c5a6SAntoine Ténart { 3741b44c5a6SAntoine Ténart struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 3751b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 37618e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 3771b44c5a6SAntoine Ténart struct crypto_aes_ctx aes; 3781b44c5a6SAntoine Ténart int ret, i; 3791b44c5a6SAntoine Ténart 380363a90c2SArd Biesheuvel ret = aes_expandkey(&aes, key, len); 381674f368aSEric Biggers if (ret) 3821b44c5a6SAntoine Ténart return ret; 3831b44c5a6SAntoine Ténart 38453c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 3851b44c5a6SAntoine Ténart for (i = 0; i < len / sizeof(u32); i++) { 38613a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 3871b44c5a6SAntoine Ténart ctx->base.needs_inv = true; 3881b44c5a6SAntoine Ténart break; 3891b44c5a6SAntoine Ténart } 3901b44c5a6SAntoine Ténart } 391c4daf4ccSOfer Heifetz } 3921b44c5a6SAntoine Ténart 3931b44c5a6SAntoine Ténart for (i = 0; i < len / sizeof(u32); i++) 3941b44c5a6SAntoine Ténart ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 3951b44c5a6SAntoine Ténart 3961b44c5a6SAntoine Ténart ctx->key_len = len; 3971b44c5a6SAntoine Ténart 3981b44c5a6SAntoine Ténart memzero_explicit(&aes, sizeof(aes)); 3991b44c5a6SAntoine Ténart return 0; 4001b44c5a6SAntoine Ténart } 4011b44c5a6SAntoine Ténart 40277cdd4efSPascal van Leeuwen static int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key, 403f6beaea3SAntoine Tenart unsigned int len) 404f6beaea3SAntoine Tenart { 405f6beaea3SAntoine Tenart struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 406f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 40718e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 408f6beaea3SAntoine Tenart struct crypto_authenc_keys keys; 4090e17e362SPascal van Leeuwen struct crypto_aes_ctx aes; 41013a1bb93SPascal van Leeuwen int err = -EINVAL, i; 41163cdd870SHerbert Xu const char *alg; 412f6beaea3SAntoine Tenart 4131769f704SPascal van Leeuwen if (unlikely(crypto_authenc_extractkeys(&keys, key, len))) 414f6beaea3SAntoine Tenart goto badkey; 415f6beaea3SAntoine Tenart 4160e17e362SPascal van Leeuwen if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { 4171769f704SPascal van Leeuwen /* Must have at least space for the nonce here */ 4181769f704SPascal van Leeuwen if (unlikely(keys.enckeylen < CTR_RFC3686_NONCE_SIZE)) 419f6beaea3SAntoine Tenart goto badkey; 4200e17e362SPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 421f26882a3SPascal van Leeuwen ctx->nonce = *(u32 *)(keys.enckey + keys.enckeylen - 422f26882a3SPascal van Leeuwen CTR_RFC3686_NONCE_SIZE); 4230e17e362SPascal van Leeuwen /* exclude the nonce here */ 4241769f704SPascal van Leeuwen keys.enckeylen -= CTR_RFC3686_NONCE_SIZE; 4250e17e362SPascal van Leeuwen } 426f6beaea3SAntoine Tenart 427f6beaea3SAntoine Tenart /* Encryption key */ 4280e17e362SPascal van Leeuwen switch (ctx->alg) { 429bb7679b8SPascal van Leeuwen case SAFEXCEL_DES: 430bb7679b8SPascal van Leeuwen err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen); 431bb7679b8SPascal van Leeuwen if (unlikely(err)) 432674f368aSEric Biggers goto badkey; 433bb7679b8SPascal van Leeuwen break; 4340e17e362SPascal van Leeuwen case SAFEXCEL_3DES: 43521f5a15eSArd Biesheuvel err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen); 43677cdd4efSPascal van Leeuwen if (unlikely(err)) 437674f368aSEric Biggers goto badkey; 4380e17e362SPascal van Leeuwen break; 4390e17e362SPascal van Leeuwen case SAFEXCEL_AES: 4400e17e362SPascal van Leeuwen err = aes_expandkey(&aes, keys.enckey, keys.enckeylen); 4410e17e362SPascal van Leeuwen if (unlikely(err)) 4420e17e362SPascal van Leeuwen goto badkey; 4430e17e362SPascal van Leeuwen break; 4441769f704SPascal van Leeuwen case SAFEXCEL_SM4: 4451769f704SPascal van Leeuwen if (unlikely(keys.enckeylen != SM4_KEY_SIZE)) 4461769f704SPascal van Leeuwen goto badkey; 4471769f704SPascal van Leeuwen break; 4480e17e362SPascal van Leeuwen default: 4490e17e362SPascal van Leeuwen dev_err(priv->dev, "aead: unsupported cipher algorithm\n"); 4500e17e362SPascal van Leeuwen goto badkey; 45177cdd4efSPascal van Leeuwen } 45277cdd4efSPascal van Leeuwen 45313a1bb93SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 45413a1bb93SPascal van Leeuwen for (i = 0; i < keys.enckeylen / sizeof(u32); i++) { 455b8151220SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != 456b8151220SPascal van Leeuwen ((u32 *)keys.enckey)[i]) { 457f6beaea3SAntoine Tenart ctx->base.needs_inv = true; 45813a1bb93SPascal van Leeuwen break; 45913a1bb93SPascal van Leeuwen } 46013a1bb93SPascal van Leeuwen } 46113a1bb93SPascal van Leeuwen } 462f6beaea3SAntoine Tenart 463f6beaea3SAntoine Tenart /* Auth key */ 464a7dea8c0SOfer Heifetz switch (ctx->hash_alg) { 46501ba061dSAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA1: 46663cdd870SHerbert Xu alg = "safexcel-sha1"; 46701ba061dSAntoine Tenart break; 468678b2878SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA224: 46963cdd870SHerbert Xu alg = "safexcel-sha224"; 470678b2878SAntoine Tenart break; 471678b2878SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA256: 47263cdd870SHerbert Xu alg = "safexcel-sha256"; 473678b2878SAntoine Tenart break; 474ea23cb53SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA384: 47563cdd870SHerbert Xu alg = "safexcel-sha384"; 476ea23cb53SAntoine Tenart break; 47787eee125SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA512: 47863cdd870SHerbert Xu alg = "safexcel-sha512"; 47987eee125SAntoine Tenart break; 4801769f704SPascal van Leeuwen case CONTEXT_CONTROL_CRYPTO_ALG_SM3: 48163cdd870SHerbert Xu alg = "safexcel-sm3"; 4821769f704SPascal van Leeuwen break; 483678b2878SAntoine Tenart default: 4841a61af28SColin Ian King dev_err(priv->dev, "aead: unsupported hash algorithm\n"); 485678b2878SAntoine Tenart goto badkey; 486678b2878SAntoine Tenart } 487f6beaea3SAntoine Tenart 48863cdd870SHerbert Xu if (safexcel_hmac_setkey(&ctx->base, keys.authkey, keys.authkeylen, 48963cdd870SHerbert Xu alg, ctx->state_sz)) 49063cdd870SHerbert Xu goto badkey; 491f6beaea3SAntoine Tenart 492f6beaea3SAntoine Tenart /* Now copy the keys into the context */ 49313a1bb93SPascal van Leeuwen for (i = 0; i < keys.enckeylen / sizeof(u32); i++) 494b8151220SPascal van Leeuwen ctx->key[i] = cpu_to_le32(((u32 *)keys.enckey)[i]); 495f6beaea3SAntoine Tenart ctx->key_len = keys.enckeylen; 496f6beaea3SAntoine Tenart 497f6beaea3SAntoine Tenart memzero_explicit(&keys, sizeof(keys)); 498f6beaea3SAntoine Tenart return 0; 499f6beaea3SAntoine Tenart 500f6beaea3SAntoine Tenart badkey: 501f6beaea3SAntoine Tenart memzero_explicit(&keys, sizeof(keys)); 5020e17e362SPascal van Leeuwen return err; 503f6beaea3SAntoine Tenart } 504f6beaea3SAntoine Tenart 5051b44c5a6SAntoine Ténart static int safexcel_context_control(struct safexcel_cipher_ctx *ctx, 506847ccfc5SOfer Heifetz struct crypto_async_request *async, 5078ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 5081b44c5a6SAntoine Ténart struct safexcel_command_desc *cdesc) 5091b44c5a6SAntoine Ténart { 51018e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 511d2d9e6fdSPascal van Leeuwen int ctrl_size = ctx->key_len / sizeof(u32); 512d2d9e6fdSPascal van Leeuwen 513d2d9e6fdSPascal van Leeuwen cdesc->control_data.control1 = ctx->mode; 5141b44c5a6SAntoine Ténart 515f6beaea3SAntoine Tenart if (ctx->aead) { 516d2d9e6fdSPascal van Leeuwen /* Take in account the ipad+opad digests */ 5173e450886SPascal van Leeuwen if (ctx->xcm) { 5183e450886SPascal van Leeuwen ctrl_size += ctx->state_sz / sizeof(u32); 5193e450886SPascal van Leeuwen cdesc->control_data.control0 = 5203e450886SPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 5213e450886SPascal van Leeuwen CONTEXT_CONTROL_DIGEST_XCM | 5223e450886SPascal van Leeuwen ctx->hash_alg | 5233e450886SPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 524a6061921SPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_CHACHA20) { 525a6061921SPascal van Leeuwen /* Chacha20-Poly1305 */ 526a6061921SPascal van Leeuwen cdesc->control_data.control0 = 527a6061921SPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 528a6061921SPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 | 529a6061921SPascal van Leeuwen (sreq->direction == SAFEXCEL_ENCRYPT ? 530a6061921SPascal van Leeuwen CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT : 531a6061921SPascal van Leeuwen CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN) | 532a6061921SPascal van Leeuwen ctx->hash_alg | 533a6061921SPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 534a6061921SPascal van Leeuwen return 0; 5353e450886SPascal van Leeuwen } else { 536d2d9e6fdSPascal van Leeuwen ctrl_size += ctx->state_sz / sizeof(u32) * 2; 5373e450886SPascal van Leeuwen cdesc->control_data.control0 = 5383e450886SPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 5393e450886SPascal van Leeuwen CONTEXT_CONTROL_DIGEST_HMAC | 5403e450886SPascal van Leeuwen ctx->hash_alg | 5413e450886SPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 5423e450886SPascal van Leeuwen } 5434eb76fafSPascal van Leeuwen 54492c60cefSPascal van Leeuwen if (sreq->direction == SAFEXCEL_ENCRYPT && 54592c60cefSPascal van Leeuwen (ctx->xcm == EIP197_XCM_MODE_CCM || 54692c60cefSPascal van Leeuwen ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) 54792c60cefSPascal van Leeuwen cdesc->control_data.control0 |= 54892c60cefSPascal van Leeuwen CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT; 54992c60cefSPascal van Leeuwen else if (sreq->direction == SAFEXCEL_ENCRYPT) 55092c60cefSPascal van Leeuwen cdesc->control_data.control0 |= 55192c60cefSPascal van Leeuwen CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT; 55292c60cefSPascal van Leeuwen else if (ctx->xcm == EIP197_XCM_MODE_CCM) 55392c60cefSPascal van Leeuwen cdesc->control_data.control0 |= 55492c60cefSPascal van Leeuwen CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN; 555d2d9e6fdSPascal van Leeuwen else 5563e450886SPascal van Leeuwen cdesc->control_data.control0 |= 5573e450886SPascal van Leeuwen CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN; 558d2d9e6fdSPascal van Leeuwen } else { 559d2d9e6fdSPascal van Leeuwen if (sreq->direction == SAFEXCEL_ENCRYPT) 560d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 = 561d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_TYPE_CRYPTO_OUT | 562d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 563d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 564d2d9e6fdSPascal van Leeuwen else 565d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 = 566d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_TYPE_CRYPTO_IN | 567d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 568d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 569f6beaea3SAntoine Tenart } 5701b44c5a6SAntoine Ténart 571a7dea8c0SOfer Heifetz if (ctx->alg == SAFEXCEL_DES) { 572d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 573d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_DES; 57462469879SOfer Heifetz } else if (ctx->alg == SAFEXCEL_3DES) { 575d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 576d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_3DES; 577a7dea8c0SOfer Heifetz } else if (ctx->alg == SAFEXCEL_AES) { 578c7da38a7SPascal van Leeuwen switch (ctx->key_len >> ctx->xts) { 5791b44c5a6SAntoine Ténart case AES_KEYSIZE_128: 580d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 581d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_AES128; 5821b44c5a6SAntoine Ténart break; 5831b44c5a6SAntoine Ténart case AES_KEYSIZE_192: 584d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 585d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_AES192; 5861b44c5a6SAntoine Ténart break; 5871b44c5a6SAntoine Ténart case AES_KEYSIZE_256: 588d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 589d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_AES256; 5901b44c5a6SAntoine Ténart break; 5911b44c5a6SAntoine Ténart default: 5921b44c5a6SAntoine Ténart dev_err(priv->dev, "aes keysize not supported: %u\n", 593c7da38a7SPascal van Leeuwen ctx->key_len >> ctx->xts); 5941b44c5a6SAntoine Ténart return -EINVAL; 5951b44c5a6SAntoine Ténart } 5964a593fb3SPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_CHACHA20) { 5974a593fb3SPascal van Leeuwen cdesc->control_data.control0 |= 5984a593fb3SPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20; 599fcca797dSPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_SM4) { 600fcca797dSPascal van Leeuwen cdesc->control_data.control0 |= 601fcca797dSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_SM4; 602a7dea8c0SOfer Heifetz } 603fef0cfe5SAntoine Tenart 6041b44c5a6SAntoine Ténart return 0; 6051b44c5a6SAntoine Ténart } 6061b44c5a6SAntoine Ténart 6071eb7b403SOfer Heifetz static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring, 6081b44c5a6SAntoine Ténart struct crypto_async_request *async, 6098ac1283eSAntoine Tenart struct scatterlist *src, 6108ac1283eSAntoine Tenart struct scatterlist *dst, 6118ac1283eSAntoine Tenart unsigned int cryptlen, 6128ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 6131b44c5a6SAntoine Ténart bool *should_complete, int *ret) 6141b44c5a6SAntoine Ténart { 6155bdb6e6aSPascal van Leeuwen struct skcipher_request *areq = skcipher_request_cast(async); 6165bdb6e6aSPascal van Leeuwen struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq); 6175bdb6e6aSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(skcipher); 6181b44c5a6SAntoine Ténart struct safexcel_result_desc *rdesc; 6191b44c5a6SAntoine Ténart int ndesc = 0; 6201b44c5a6SAntoine Ténart 6211b44c5a6SAntoine Ténart *ret = 0; 6221b44c5a6SAntoine Ténart 62389332590SAntoine Tenart if (unlikely(!sreq->rdescs)) 62489332590SAntoine Tenart return 0; 62589332590SAntoine Tenart 62689332590SAntoine Tenart while (sreq->rdescs--) { 6271b44c5a6SAntoine Ténart rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr); 6281b44c5a6SAntoine Ténart if (IS_ERR(rdesc)) { 6291b44c5a6SAntoine Ténart dev_err(priv->dev, 6301b44c5a6SAntoine Ténart "cipher: result: could not retrieve the result descriptor\n"); 6311b44c5a6SAntoine Ténart *ret = PTR_ERR(rdesc); 6321b44c5a6SAntoine Ténart break; 6331b44c5a6SAntoine Ténart } 6341b44c5a6SAntoine Ténart 635bdfd1909SAntoine Tenart if (likely(!*ret)) 636bdfd1909SAntoine Tenart *ret = safexcel_rdesc_check_errors(priv, rdesc); 6371b44c5a6SAntoine Ténart 6381b44c5a6SAntoine Ténart ndesc++; 63989332590SAntoine Tenart } 6401b44c5a6SAntoine Ténart 6411b44c5a6SAntoine Ténart safexcel_complete(priv, ring); 6421b44c5a6SAntoine Ténart 6438ac1283eSAntoine Tenart if (src == dst) { 64419b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL); 6451b44c5a6SAntoine Ténart } else { 64619b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 64719b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE); 6481b44c5a6SAntoine Ténart } 6491b44c5a6SAntoine Ténart 6505bdb6e6aSPascal van Leeuwen /* 6515bdb6e6aSPascal van Leeuwen * Update IV in req from last crypto output word for CBC modes 6525bdb6e6aSPascal van Leeuwen */ 6535bdb6e6aSPascal van Leeuwen if ((!ctx->aead) && (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) && 6545bdb6e6aSPascal van Leeuwen (sreq->direction == SAFEXCEL_ENCRYPT)) { 6555bdb6e6aSPascal van Leeuwen /* For encrypt take the last output word */ 65619b347b3SPascal van Leeuwen sg_pcopy_to_buffer(dst, sreq->nr_dst, areq->iv, 6575bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher), 6585bdb6e6aSPascal van Leeuwen (cryptlen - 6595bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher))); 6605bdb6e6aSPascal van Leeuwen } 6615bdb6e6aSPascal van Leeuwen 6621b44c5a6SAntoine Ténart *should_complete = true; 6631b44c5a6SAntoine Ténart 6641b44c5a6SAntoine Ténart return ndesc; 6651b44c5a6SAntoine Ténart } 6661b44c5a6SAntoine Ténart 667a7dea8c0SOfer Heifetz static int safexcel_send_req(struct crypto_async_request *base, int ring, 6688ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 6698ac1283eSAntoine Tenart struct scatterlist *src, struct scatterlist *dst, 670f6beaea3SAntoine Tenart unsigned int cryptlen, unsigned int assoclen, 671f6beaea3SAntoine Tenart unsigned int digestsize, u8 *iv, int *commands, 6728ac1283eSAntoine Tenart int *results) 6731b44c5a6SAntoine Ténart { 6745bdb6e6aSPascal van Leeuwen struct skcipher_request *areq = skcipher_request_cast(base); 6755bdb6e6aSPascal van Leeuwen struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq); 6768ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 67718e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 6781b44c5a6SAntoine Ténart struct safexcel_command_desc *cdesc; 67919b347b3SPascal van Leeuwen struct safexcel_command_desc *first_cdesc = NULL; 680e5c8ee1fSAntoine Tenart struct safexcel_result_desc *rdesc, *first_rdesc = NULL; 6811b44c5a6SAntoine Ténart struct scatterlist *sg; 68219b347b3SPascal van Leeuwen unsigned int totlen; 68319b347b3SPascal van Leeuwen unsigned int totlen_src = cryptlen + assoclen; 68419b347b3SPascal van Leeuwen unsigned int totlen_dst = totlen_src; 685098e51e5SPascal van Leeuwen struct safexcel_token *atoken; 68619b347b3SPascal van Leeuwen int n_cdesc = 0, n_rdesc = 0; 68719b347b3SPascal van Leeuwen int queued, i, ret = 0; 68819b347b3SPascal van Leeuwen bool first = true; 6891b44c5a6SAntoine Ténart 69019b347b3SPascal van Leeuwen sreq->nr_src = sg_nents_for_len(src, totlen_src); 69119b347b3SPascal van Leeuwen 69219b347b3SPascal van Leeuwen if (ctx->aead) { 69319b347b3SPascal van Leeuwen /* 69419b347b3SPascal van Leeuwen * AEAD has auth tag appended to output for encrypt and 69519b347b3SPascal van Leeuwen * removed from the output for decrypt! 69619b347b3SPascal van Leeuwen */ 69719b347b3SPascal van Leeuwen if (sreq->direction == SAFEXCEL_DECRYPT) 69819b347b3SPascal van Leeuwen totlen_dst -= digestsize; 69919b347b3SPascal van Leeuwen else 70019b347b3SPascal van Leeuwen totlen_dst += digestsize; 70119b347b3SPascal van Leeuwen 70219b347b3SPascal van Leeuwen memcpy(ctx->base.ctxr->data + ctx->key_len / sizeof(u32), 70378cf1c8bSHerbert Xu &ctx->base.ipad, ctx->state_sz); 7043e450886SPascal van Leeuwen if (!ctx->xcm) 7053e450886SPascal van Leeuwen memcpy(ctx->base.ctxr->data + (ctx->key_len + 70678cf1c8bSHerbert Xu ctx->state_sz) / sizeof(u32), &ctx->base.opad, 7073e450886SPascal van Leeuwen ctx->state_sz); 70819b347b3SPascal van Leeuwen } else if ((ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) && 7095bdb6e6aSPascal van Leeuwen (sreq->direction == SAFEXCEL_DECRYPT)) { 7105bdb6e6aSPascal van Leeuwen /* 7115bdb6e6aSPascal van Leeuwen * Save IV from last crypto input word for CBC modes in decrypt 7125bdb6e6aSPascal van Leeuwen * direction. Need to do this first in case of inplace operation 7135bdb6e6aSPascal van Leeuwen * as it will be overwritten. 7145bdb6e6aSPascal van Leeuwen */ 71519b347b3SPascal van Leeuwen sg_pcopy_to_buffer(src, sreq->nr_src, areq->iv, 7165bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher), 71719b347b3SPascal van Leeuwen (totlen_src - 7185bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher))); 7195bdb6e6aSPascal van Leeuwen } 7205bdb6e6aSPascal van Leeuwen 72119b347b3SPascal van Leeuwen sreq->nr_dst = sg_nents_for_len(dst, totlen_dst); 7221b44c5a6SAntoine Ténart 72319b347b3SPascal van Leeuwen /* 72419b347b3SPascal van Leeuwen * Remember actual input length, source buffer length may be 72519b347b3SPascal van Leeuwen * updated in case of inline operation below. 72619b347b3SPascal van Leeuwen */ 72719b347b3SPascal van Leeuwen totlen = totlen_src; 72819b347b3SPascal van Leeuwen queued = totlen_src; 72919b347b3SPascal van Leeuwen 73019b347b3SPascal van Leeuwen if (src == dst) { 73119b347b3SPascal van Leeuwen sreq->nr_src = max(sreq->nr_src, sreq->nr_dst); 73219b347b3SPascal van Leeuwen sreq->nr_dst = sreq->nr_src; 73319b347b3SPascal van Leeuwen if (unlikely((totlen_src || totlen_dst) && 73419b347b3SPascal van Leeuwen (sreq->nr_src <= 0))) { 73519b347b3SPascal van Leeuwen dev_err(priv->dev, "In-place buffer not large enough (need %d bytes)!", 73619b347b3SPascal van Leeuwen max(totlen_src, totlen_dst)); 7371b44c5a6SAntoine Ténart return -EINVAL; 7381b44c5a6SAntoine Ténart } 73919b347b3SPascal van Leeuwen dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL); 74019b347b3SPascal van Leeuwen } else { 74119b347b3SPascal van Leeuwen if (unlikely(totlen_src && (sreq->nr_src <= 0))) { 74219b347b3SPascal van Leeuwen dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!", 74319b347b3SPascal van Leeuwen totlen_src); 74419b347b3SPascal van Leeuwen return -EINVAL; 74519b347b3SPascal van Leeuwen } 74619b347b3SPascal van Leeuwen dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 74719b347b3SPascal van Leeuwen 74819b347b3SPascal van Leeuwen if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) { 74919b347b3SPascal van Leeuwen dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!", 75019b347b3SPascal van Leeuwen totlen_dst); 75119b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, 75219b347b3SPascal van Leeuwen DMA_TO_DEVICE); 75319b347b3SPascal van Leeuwen return -EINVAL; 75419b347b3SPascal van Leeuwen } 75519b347b3SPascal van Leeuwen dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE); 7561b44c5a6SAntoine Ténart } 7571b44c5a6SAntoine Ténart 7581b44c5a6SAntoine Ténart memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len); 7591b44c5a6SAntoine Ténart 760cb97aa94SPascal van Leeuwen if (!totlen) { 761cb97aa94SPascal van Leeuwen /* 762cb97aa94SPascal van Leeuwen * The EIP97 cannot deal with zero length input packets! 763cb97aa94SPascal van Leeuwen * So stuff a dummy command descriptor indicating a 1 byte 764cb97aa94SPascal van Leeuwen * (dummy) input packet, using the context record as source. 765cb97aa94SPascal van Leeuwen */ 766cb97aa94SPascal van Leeuwen first_cdesc = safexcel_add_cdesc(priv, ring, 767cb97aa94SPascal van Leeuwen 1, 1, ctx->base.ctxr_dma, 768cb97aa94SPascal van Leeuwen 1, 1, ctx->base.ctxr_dma, 769cb97aa94SPascal van Leeuwen &atoken); 770cb97aa94SPascal van Leeuwen if (IS_ERR(first_cdesc)) { 771cb97aa94SPascal van Leeuwen /* No space left in the command descriptor ring */ 772cb97aa94SPascal van Leeuwen ret = PTR_ERR(first_cdesc); 773cb97aa94SPascal van Leeuwen goto cdesc_rollback; 774cb97aa94SPascal van Leeuwen } 775cb97aa94SPascal van Leeuwen n_cdesc = 1; 776cb97aa94SPascal van Leeuwen goto skip_cdesc; 777cb97aa94SPascal van Leeuwen } 778f6beaea3SAntoine Tenart 7791b44c5a6SAntoine Ténart /* command descriptors */ 78019b347b3SPascal van Leeuwen for_each_sg(src, sg, sreq->nr_src, i) { 7811b44c5a6SAntoine Ténart int len = sg_dma_len(sg); 7821b44c5a6SAntoine Ténart 7831b44c5a6SAntoine Ténart /* Do not overflow the request */ 784cb97aa94SPascal van Leeuwen if (queued < len) 7851b44c5a6SAntoine Ténart len = queued; 7861b44c5a6SAntoine Ténart 78719b347b3SPascal van Leeuwen cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc, 78819b347b3SPascal van Leeuwen !(queued - len), 789f6beaea3SAntoine Tenart sg_dma_address(sg), len, totlen, 790098e51e5SPascal van Leeuwen ctx->base.ctxr_dma, &atoken); 7911b44c5a6SAntoine Ténart if (IS_ERR(cdesc)) { 7921b44c5a6SAntoine Ténart /* No space left in the command descriptor ring */ 7931b44c5a6SAntoine Ténart ret = PTR_ERR(cdesc); 7941b44c5a6SAntoine Ténart goto cdesc_rollback; 7951b44c5a6SAntoine Ténart } 7961b44c5a6SAntoine Ténart 797cb97aa94SPascal van Leeuwen if (!n_cdesc) 79819b347b3SPascal van Leeuwen first_cdesc = cdesc; 7991b44c5a6SAntoine Ténart 800cb97aa94SPascal van Leeuwen n_cdesc++; 8011b44c5a6SAntoine Ténart queued -= len; 8021b44c5a6SAntoine Ténart if (!queued) 8031b44c5a6SAntoine Ténart break; 8041b44c5a6SAntoine Ténart } 805cb97aa94SPascal van Leeuwen skip_cdesc: 80619b347b3SPascal van Leeuwen /* Add context control words and token to first command descriptor */ 80719b347b3SPascal van Leeuwen safexcel_context_control(ctx, base, sreq, first_cdesc); 80819b347b3SPascal van Leeuwen if (ctx->aead) 809098e51e5SPascal van Leeuwen safexcel_aead_token(ctx, iv, first_cdesc, atoken, 81019b347b3SPascal van Leeuwen sreq->direction, cryptlen, 81119b347b3SPascal van Leeuwen assoclen, digestsize); 81219b347b3SPascal van Leeuwen else 813098e51e5SPascal van Leeuwen safexcel_skcipher_token(ctx, iv, first_cdesc, atoken, 81419b347b3SPascal van Leeuwen cryptlen); 81519b347b3SPascal van Leeuwen 8161b44c5a6SAntoine Ténart /* result descriptors */ 81719b347b3SPascal van Leeuwen for_each_sg(dst, sg, sreq->nr_dst, i) { 81819b347b3SPascal van Leeuwen bool last = (i == sreq->nr_dst - 1); 8191b44c5a6SAntoine Ténart u32 len = sg_dma_len(sg); 8201b44c5a6SAntoine Ténart 82119b347b3SPascal van Leeuwen /* only allow the part of the buffer we know we need */ 82219b347b3SPascal van Leeuwen if (len > totlen_dst) 82319b347b3SPascal van Leeuwen len = totlen_dst; 82419b347b3SPascal van Leeuwen if (unlikely(!len)) 82519b347b3SPascal van Leeuwen break; 82619b347b3SPascal van Leeuwen totlen_dst -= len; 82719b347b3SPascal van Leeuwen 82819b347b3SPascal van Leeuwen /* skip over AAD space in buffer - not written */ 82919b347b3SPascal van Leeuwen if (assoclen) { 83019b347b3SPascal van Leeuwen if (assoclen >= len) { 83119b347b3SPascal van Leeuwen assoclen -= len; 83219b347b3SPascal van Leeuwen continue; 83319b347b3SPascal van Leeuwen } 8341b44c5a6SAntoine Ténart rdesc = safexcel_add_rdesc(priv, ring, first, last, 83519b347b3SPascal van Leeuwen sg_dma_address(sg) + 83619b347b3SPascal van Leeuwen assoclen, 83719b347b3SPascal van Leeuwen len - assoclen); 83819b347b3SPascal van Leeuwen assoclen = 0; 83919b347b3SPascal van Leeuwen } else { 84019b347b3SPascal van Leeuwen rdesc = safexcel_add_rdesc(priv, ring, first, last, 84119b347b3SPascal van Leeuwen sg_dma_address(sg), 84219b347b3SPascal van Leeuwen len); 84319b347b3SPascal van Leeuwen } 8441b44c5a6SAntoine Ténart if (IS_ERR(rdesc)) { 8451b44c5a6SAntoine Ténart /* No space left in the result descriptor ring */ 8461b44c5a6SAntoine Ténart ret = PTR_ERR(rdesc); 8471b44c5a6SAntoine Ténart goto rdesc_rollback; 8481b44c5a6SAntoine Ténart } 84919b347b3SPascal van Leeuwen if (first) { 8509744fec9SOfer Heifetz first_rdesc = rdesc; 85119b347b3SPascal van Leeuwen first = false; 85219b347b3SPascal van Leeuwen } 8531b44c5a6SAntoine Ténart n_rdesc++; 8541b44c5a6SAntoine Ténart } 8551b44c5a6SAntoine Ténart 85619b347b3SPascal van Leeuwen if (unlikely(first)) { 85719b347b3SPascal van Leeuwen /* 85819b347b3SPascal van Leeuwen * Special case: AEAD decrypt with only AAD data. 85919b347b3SPascal van Leeuwen * In this case there is NO output data from the engine, 86019b347b3SPascal van Leeuwen * but the engine still needs a result descriptor! 86119b347b3SPascal van Leeuwen * Create a dummy one just for catching the result token. 86219b347b3SPascal van Leeuwen */ 86319b347b3SPascal van Leeuwen rdesc = safexcel_add_rdesc(priv, ring, true, true, 0, 0); 86419b347b3SPascal van Leeuwen if (IS_ERR(rdesc)) { 86519b347b3SPascal van Leeuwen /* No space left in the result descriptor ring */ 86619b347b3SPascal van Leeuwen ret = PTR_ERR(rdesc); 86719b347b3SPascal van Leeuwen goto rdesc_rollback; 86819b347b3SPascal van Leeuwen } 86919b347b3SPascal van Leeuwen first_rdesc = rdesc; 87019b347b3SPascal van Leeuwen n_rdesc = 1; 87119b347b3SPascal van Leeuwen } 87219b347b3SPascal van Leeuwen 8739744fec9SOfer Heifetz safexcel_rdr_req_set(priv, ring, first_rdesc, base); 87497858434SAntoine Ténart 8751b44c5a6SAntoine Ténart *commands = n_cdesc; 876152bdf4cSOfer Heifetz *results = n_rdesc; 8771b44c5a6SAntoine Ténart return 0; 8781b44c5a6SAntoine Ténart 8791b44c5a6SAntoine Ténart rdesc_rollback: 8801b44c5a6SAntoine Ténart for (i = 0; i < n_rdesc; i++) 8811b44c5a6SAntoine Ténart safexcel_ring_rollback_wptr(priv, &priv->ring[ring].rdr); 8821b44c5a6SAntoine Ténart cdesc_rollback: 8831b44c5a6SAntoine Ténart for (i = 0; i < n_cdesc; i++) 8841b44c5a6SAntoine Ténart safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr); 8851b44c5a6SAntoine Ténart 8868ac1283eSAntoine Tenart if (src == dst) { 88719b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL); 8881b44c5a6SAntoine Ténart } else { 88919b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 89019b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE); 8911b44c5a6SAntoine Ténart } 8921b44c5a6SAntoine Ténart 8931b44c5a6SAntoine Ténart return ret; 8941b44c5a6SAntoine Ténart } 8951b44c5a6SAntoine Ténart 8961b44c5a6SAntoine Ténart static int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv, 8971b44c5a6SAntoine Ténart int ring, 8988ac1283eSAntoine Tenart struct crypto_async_request *base, 89989332590SAntoine Tenart struct safexcel_cipher_req *sreq, 9001b44c5a6SAntoine Ténart bool *should_complete, int *ret) 9011b44c5a6SAntoine Ténart { 9028ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 9031b44c5a6SAntoine Ténart struct safexcel_result_desc *rdesc; 9041b44c5a6SAntoine Ténart int ndesc = 0, enq_ret; 9051b44c5a6SAntoine Ténart 9061b44c5a6SAntoine Ténart *ret = 0; 9071b44c5a6SAntoine Ténart 90889332590SAntoine Tenart if (unlikely(!sreq->rdescs)) 90989332590SAntoine Tenart return 0; 91089332590SAntoine Tenart 91189332590SAntoine Tenart while (sreq->rdescs--) { 9121b44c5a6SAntoine Ténart rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr); 9131b44c5a6SAntoine Ténart if (IS_ERR(rdesc)) { 9141b44c5a6SAntoine Ténart dev_err(priv->dev, 9151b44c5a6SAntoine Ténart "cipher: invalidate: could not retrieve the result descriptor\n"); 9161b44c5a6SAntoine Ténart *ret = PTR_ERR(rdesc); 9171b44c5a6SAntoine Ténart break; 9181b44c5a6SAntoine Ténart } 9191b44c5a6SAntoine Ténart 920cda3e73aSAntoine Tenart if (likely(!*ret)) 921cda3e73aSAntoine Tenart *ret = safexcel_rdesc_check_errors(priv, rdesc); 9221b44c5a6SAntoine Ténart 9231b44c5a6SAntoine Ténart ndesc++; 92489332590SAntoine Tenart } 9251b44c5a6SAntoine Ténart 9261b44c5a6SAntoine Ténart safexcel_complete(priv, ring); 9271b44c5a6SAntoine Ténart 9281b44c5a6SAntoine Ténart if (ctx->base.exit_inv) { 9291b44c5a6SAntoine Ténart dma_pool_free(priv->context_pool, ctx->base.ctxr, 9301b44c5a6SAntoine Ténart ctx->base.ctxr_dma); 9311b44c5a6SAntoine Ténart 9321b44c5a6SAntoine Ténart *should_complete = true; 9331b44c5a6SAntoine Ténart 9341b44c5a6SAntoine Ténart return ndesc; 9351b44c5a6SAntoine Ténart } 9361b44c5a6SAntoine Ténart 93786671abbSAntoine Ténart ring = safexcel_select_ring(priv); 93886671abbSAntoine Ténart ctx->base.ring = ring; 9391b44c5a6SAntoine Ténart 94086671abbSAntoine Ténart spin_lock_bh(&priv->ring[ring].queue_lock); 9418ac1283eSAntoine Tenart enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, base); 94286671abbSAntoine Ténart spin_unlock_bh(&priv->ring[ring].queue_lock); 9431b44c5a6SAntoine Ténart 9441b44c5a6SAntoine Ténart if (enq_ret != -EINPROGRESS) 9451b44c5a6SAntoine Ténart *ret = enq_ret; 9461b44c5a6SAntoine Ténart 9478472e778SAntoine Ténart queue_work(priv->ring[ring].workqueue, 9488472e778SAntoine Ténart &priv->ring[ring].work_data.work); 94986671abbSAntoine Ténart 9501b44c5a6SAntoine Ténart *should_complete = false; 9511b44c5a6SAntoine Ténart 9521b44c5a6SAntoine Ténart return ndesc; 9531b44c5a6SAntoine Ténart } 9541b44c5a6SAntoine Ténart 9558ac1283eSAntoine Tenart static int safexcel_skcipher_handle_result(struct safexcel_crypto_priv *priv, 9568ac1283eSAntoine Tenart int ring, 9571eb7b403SOfer Heifetz struct crypto_async_request *async, 9581eb7b403SOfer Heifetz bool *should_complete, int *ret) 9591eb7b403SOfer Heifetz { 9601eb7b403SOfer Heifetz struct skcipher_request *req = skcipher_request_cast(async); 9611eb7b403SOfer Heifetz struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 9621eb7b403SOfer Heifetz int err; 9631eb7b403SOfer Heifetz 9641eb7b403SOfer Heifetz if (sreq->needs_inv) { 9651eb7b403SOfer Heifetz sreq->needs_inv = false; 96689332590SAntoine Tenart err = safexcel_handle_inv_result(priv, ring, async, sreq, 9671eb7b403SOfer Heifetz should_complete, ret); 9681eb7b403SOfer Heifetz } else { 9698ac1283eSAntoine Tenart err = safexcel_handle_req_result(priv, ring, async, req->src, 9708ac1283eSAntoine Tenart req->dst, req->cryptlen, sreq, 9711eb7b403SOfer Heifetz should_complete, ret); 9721eb7b403SOfer Heifetz } 9731eb7b403SOfer Heifetz 9741eb7b403SOfer Heifetz return err; 9751eb7b403SOfer Heifetz } 9761eb7b403SOfer Heifetz 977f6beaea3SAntoine Tenart static int safexcel_aead_handle_result(struct safexcel_crypto_priv *priv, 978f6beaea3SAntoine Tenart int ring, 979f6beaea3SAntoine Tenart struct crypto_async_request *async, 980f6beaea3SAntoine Tenart bool *should_complete, int *ret) 981f6beaea3SAntoine Tenart { 982f6beaea3SAntoine Tenart struct aead_request *req = aead_request_cast(async); 983f6beaea3SAntoine Tenart struct crypto_aead *tfm = crypto_aead_reqtfm(req); 984f6beaea3SAntoine Tenart struct safexcel_cipher_req *sreq = aead_request_ctx(req); 985f6beaea3SAntoine Tenart int err; 986f6beaea3SAntoine Tenart 987f6beaea3SAntoine Tenart if (sreq->needs_inv) { 988f6beaea3SAntoine Tenart sreq->needs_inv = false; 98989332590SAntoine Tenart err = safexcel_handle_inv_result(priv, ring, async, sreq, 990f6beaea3SAntoine Tenart should_complete, ret); 991f6beaea3SAntoine Tenart } else { 992f6beaea3SAntoine Tenart err = safexcel_handle_req_result(priv, ring, async, req->src, 993f6beaea3SAntoine Tenart req->dst, 994f6beaea3SAntoine Tenart req->cryptlen + crypto_aead_authsize(tfm), 995f6beaea3SAntoine Tenart sreq, should_complete, ret); 996f6beaea3SAntoine Tenart } 997f6beaea3SAntoine Tenart 998f6beaea3SAntoine Tenart return err; 999f6beaea3SAntoine Tenart } 1000f6beaea3SAntoine Tenart 10018ac1283eSAntoine Tenart static int safexcel_cipher_send_inv(struct crypto_async_request *base, 10029744fec9SOfer Heifetz int ring, int *commands, int *results) 10031b44c5a6SAntoine Ténart { 10048ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 100518e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 10061b44c5a6SAntoine Ténart int ret; 10071b44c5a6SAntoine Ténart 10089744fec9SOfer Heifetz ret = safexcel_invalidate_cache(base, priv, ctx->base.ctxr_dma, ring); 10091b44c5a6SAntoine Ténart if (unlikely(ret)) 10101b44c5a6SAntoine Ténart return ret; 10111b44c5a6SAntoine Ténart 10121b44c5a6SAntoine Ténart *commands = 1; 10131b44c5a6SAntoine Ténart *results = 1; 10141b44c5a6SAntoine Ténart 10151b44c5a6SAntoine Ténart return 0; 10161b44c5a6SAntoine Ténart } 10171b44c5a6SAntoine Ténart 10188ac1283eSAntoine Tenart static int safexcel_skcipher_send(struct crypto_async_request *async, int ring, 10191eb7b403SOfer Heifetz int *commands, int *results) 10201eb7b403SOfer Heifetz { 10211eb7b403SOfer Heifetz struct skcipher_request *req = skcipher_request_cast(async); 1022871df319SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 10231eb7b403SOfer Heifetz struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 102418e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 10251eb7b403SOfer Heifetz int ret; 10261eb7b403SOfer Heifetz 102753c83e91SAntoine Tenart BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv); 1028871df319SAntoine Ténart 10295bdb6e6aSPascal van Leeuwen if (sreq->needs_inv) { 10309744fec9SOfer Heifetz ret = safexcel_cipher_send_inv(async, ring, commands, results); 10315bdb6e6aSPascal van Leeuwen } else { 10325bdb6e6aSPascal van Leeuwen struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 10335bdb6e6aSPascal van Leeuwen u8 input_iv[AES_BLOCK_SIZE]; 10345bdb6e6aSPascal van Leeuwen 10355bdb6e6aSPascal van Leeuwen /* 10365bdb6e6aSPascal van Leeuwen * Save input IV in case of CBC decrypt mode 10375bdb6e6aSPascal van Leeuwen * Will be overwritten with output IV prior to use! 10385bdb6e6aSPascal van Leeuwen */ 10395bdb6e6aSPascal van Leeuwen memcpy(input_iv, req->iv, crypto_skcipher_ivsize(skcipher)); 10405bdb6e6aSPascal van Leeuwen 10419744fec9SOfer Heifetz ret = safexcel_send_req(async, ring, sreq, req->src, 10425bdb6e6aSPascal van Leeuwen req->dst, req->cryptlen, 0, 0, input_iv, 1043f6beaea3SAntoine Tenart commands, results); 10445bdb6e6aSPascal van Leeuwen } 104589332590SAntoine Tenart 104689332590SAntoine Tenart sreq->rdescs = *results; 1047f6beaea3SAntoine Tenart return ret; 1048f6beaea3SAntoine Tenart } 1049f6beaea3SAntoine Tenart 1050f6beaea3SAntoine Tenart static int safexcel_aead_send(struct crypto_async_request *async, int ring, 10519744fec9SOfer Heifetz int *commands, int *results) 1052f6beaea3SAntoine Tenart { 1053f6beaea3SAntoine Tenart struct aead_request *req = aead_request_cast(async); 1054f6beaea3SAntoine Tenart struct crypto_aead *tfm = crypto_aead_reqtfm(req); 1055f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 1056f6beaea3SAntoine Tenart struct safexcel_cipher_req *sreq = aead_request_ctx(req); 105718e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 1058f6beaea3SAntoine Tenart int ret; 1059f6beaea3SAntoine Tenart 106053c83e91SAntoine Tenart BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv); 1061f6beaea3SAntoine Tenart 1062f6beaea3SAntoine Tenart if (sreq->needs_inv) 10639744fec9SOfer Heifetz ret = safexcel_cipher_send_inv(async, ring, commands, results); 1064f6beaea3SAntoine Tenart else 10659744fec9SOfer Heifetz ret = safexcel_send_req(async, ring, sreq, req->src, req->dst, 10669744fec9SOfer Heifetz req->cryptlen, req->assoclen, 1067f6beaea3SAntoine Tenart crypto_aead_authsize(tfm), req->iv, 10681eb7b403SOfer Heifetz commands, results); 106989332590SAntoine Tenart sreq->rdescs = *results; 10701eb7b403SOfer Heifetz return ret; 10711eb7b403SOfer Heifetz } 10721eb7b403SOfer Heifetz 10738ac1283eSAntoine Tenart static int safexcel_cipher_exit_inv(struct crypto_tfm *tfm, 10748ac1283eSAntoine Tenart struct crypto_async_request *base, 10758ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 10768ac1283eSAntoine Tenart struct safexcel_inv_result *result) 10771b44c5a6SAntoine Ténart { 10781b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 107918e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 108086671abbSAntoine Ténart int ring = ctx->base.ring; 10811b44c5a6SAntoine Ténart 10828ac1283eSAntoine Tenart init_completion(&result->completion); 10831b44c5a6SAntoine Ténart 10848ac1283eSAntoine Tenart ctx = crypto_tfm_ctx(base->tfm); 10851b44c5a6SAntoine Ténart ctx->base.exit_inv = true; 10861eb7b403SOfer Heifetz sreq->needs_inv = true; 10871b44c5a6SAntoine Ténart 108886671abbSAntoine Ténart spin_lock_bh(&priv->ring[ring].queue_lock); 10898ac1283eSAntoine Tenart crypto_enqueue_request(&priv->ring[ring].queue, base); 109086671abbSAntoine Ténart spin_unlock_bh(&priv->ring[ring].queue_lock); 10911b44c5a6SAntoine Ténart 10928472e778SAntoine Ténart queue_work(priv->ring[ring].workqueue, 10938472e778SAntoine Ténart &priv->ring[ring].work_data.work); 10941b44c5a6SAntoine Ténart 10958ac1283eSAntoine Tenart wait_for_completion(&result->completion); 10961b44c5a6SAntoine Ténart 10978ac1283eSAntoine Tenart if (result->error) { 10981b44c5a6SAntoine Ténart dev_warn(priv->dev, 10991b44c5a6SAntoine Ténart "cipher: sync: invalidate: completion error %d\n", 11008ac1283eSAntoine Tenart result->error); 11018ac1283eSAntoine Tenart return result->error; 11021b44c5a6SAntoine Ténart } 11031b44c5a6SAntoine Ténart 11041b44c5a6SAntoine Ténart return 0; 11051b44c5a6SAntoine Ténart } 11061b44c5a6SAntoine Ténart 11078ac1283eSAntoine Tenart static int safexcel_skcipher_exit_inv(struct crypto_tfm *tfm) 11088ac1283eSAntoine Tenart { 11098ac1283eSAntoine Tenart EIP197_REQUEST_ON_STACK(req, skcipher, EIP197_SKCIPHER_REQ_SIZE); 11108ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 11118ac1283eSAntoine Tenart struct safexcel_inv_result result = {}; 11128ac1283eSAntoine Tenart 11138ac1283eSAntoine Tenart memset(req, 0, sizeof(struct skcipher_request)); 11148ac1283eSAntoine Tenart 11158ac1283eSAntoine Tenart skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 11168ac1283eSAntoine Tenart safexcel_inv_complete, &result); 11178ac1283eSAntoine Tenart skcipher_request_set_tfm(req, __crypto_skcipher_cast(tfm)); 11188ac1283eSAntoine Tenart 11198ac1283eSAntoine Tenart return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result); 11208ac1283eSAntoine Tenart } 11218ac1283eSAntoine Tenart 1122f6beaea3SAntoine Tenart static int safexcel_aead_exit_inv(struct crypto_tfm *tfm) 1123f6beaea3SAntoine Tenart { 1124f6beaea3SAntoine Tenart EIP197_REQUEST_ON_STACK(req, aead, EIP197_AEAD_REQ_SIZE); 1125f6beaea3SAntoine Tenart struct safexcel_cipher_req *sreq = aead_request_ctx(req); 1126f6beaea3SAntoine Tenart struct safexcel_inv_result result = {}; 1127f6beaea3SAntoine Tenart 1128f6beaea3SAntoine Tenart memset(req, 0, sizeof(struct aead_request)); 1129f6beaea3SAntoine Tenart 1130f6beaea3SAntoine Tenart aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 1131f6beaea3SAntoine Tenart safexcel_inv_complete, &result); 1132f6beaea3SAntoine Tenart aead_request_set_tfm(req, __crypto_aead_cast(tfm)); 1133f6beaea3SAntoine Tenart 1134f6beaea3SAntoine Tenart return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result); 1135f6beaea3SAntoine Tenart } 1136f6beaea3SAntoine Tenart 1137a7dea8c0SOfer Heifetz static int safexcel_queue_req(struct crypto_async_request *base, 11388ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 113993369b5dSPascal van Leeuwen enum safexcel_cipher_direction dir) 11401b44c5a6SAntoine Ténart { 11418ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 114218e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 114386671abbSAntoine Ténart int ret, ring; 11441b44c5a6SAntoine Ténart 11451eb7b403SOfer Heifetz sreq->needs_inv = false; 1146847ccfc5SOfer Heifetz sreq->direction = dir; 11471b44c5a6SAntoine Ténart 11481b44c5a6SAntoine Ténart if (ctx->base.ctxr) { 114953c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE && ctx->base.needs_inv) { 11501eb7b403SOfer Heifetz sreq->needs_inv = true; 11511eb7b403SOfer Heifetz ctx->base.needs_inv = false; 11521eb7b403SOfer Heifetz } 11531b44c5a6SAntoine Ténart } else { 11541b44c5a6SAntoine Ténart ctx->base.ring = safexcel_select_ring(priv); 11551b44c5a6SAntoine Ténart ctx->base.ctxr = dma_pool_zalloc(priv->context_pool, 11568ac1283eSAntoine Tenart EIP197_GFP_FLAGS(*base), 11571b44c5a6SAntoine Ténart &ctx->base.ctxr_dma); 11581b44c5a6SAntoine Ténart if (!ctx->base.ctxr) 11591b44c5a6SAntoine Ténart return -ENOMEM; 11601b44c5a6SAntoine Ténart } 11611b44c5a6SAntoine Ténart 116286671abbSAntoine Ténart ring = ctx->base.ring; 11631b44c5a6SAntoine Ténart 116486671abbSAntoine Ténart spin_lock_bh(&priv->ring[ring].queue_lock); 11658ac1283eSAntoine Tenart ret = crypto_enqueue_request(&priv->ring[ring].queue, base); 116686671abbSAntoine Ténart spin_unlock_bh(&priv->ring[ring].queue_lock); 116786671abbSAntoine Ténart 11688472e778SAntoine Ténart queue_work(priv->ring[ring].workqueue, 11698472e778SAntoine Ténart &priv->ring[ring].work_data.work); 11701b44c5a6SAntoine Ténart 11711b44c5a6SAntoine Ténart return ret; 11721b44c5a6SAntoine Ténart } 11731b44c5a6SAntoine Ténart 117493369b5dSPascal van Leeuwen static int safexcel_encrypt(struct skcipher_request *req) 11751b44c5a6SAntoine Ténart { 1176a7dea8c0SOfer Heifetz return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 117793369b5dSPascal van Leeuwen SAFEXCEL_ENCRYPT); 11781b44c5a6SAntoine Ténart } 11791b44c5a6SAntoine Ténart 118093369b5dSPascal van Leeuwen static int safexcel_decrypt(struct skcipher_request *req) 11811b44c5a6SAntoine Ténart { 1182a7dea8c0SOfer Heifetz return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 118393369b5dSPascal van Leeuwen SAFEXCEL_DECRYPT); 11841b44c5a6SAntoine Ténart } 11851b44c5a6SAntoine Ténart 11861b44c5a6SAntoine Ténart static int safexcel_skcipher_cra_init(struct crypto_tfm *tfm) 11871b44c5a6SAntoine Ténart { 11881b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 11891b44c5a6SAntoine Ténart struct safexcel_alg_template *tmpl = 11901b44c5a6SAntoine Ténart container_of(tfm->__crt_alg, struct safexcel_alg_template, 11911b44c5a6SAntoine Ténart alg.skcipher.base); 11921b44c5a6SAntoine Ténart 11931eb7b403SOfer Heifetz crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), 11941eb7b403SOfer Heifetz sizeof(struct safexcel_cipher_req)); 11951b44c5a6SAntoine Ténart 119618e51895SHerbert Xu ctx->base.priv = tmpl->priv; 11978ac1283eSAntoine Tenart 11988ac1283eSAntoine Tenart ctx->base.send = safexcel_skcipher_send; 11998ac1283eSAntoine Tenart ctx->base.handle_result = safexcel_skcipher_handle_result; 1200098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD; 1201098e51e5SPascal van Leeuwen ctx->ctrinit = 1; 12028ac1283eSAntoine Tenart return 0; 12038ac1283eSAntoine Tenart } 12048ac1283eSAntoine Tenart 12058ac1283eSAntoine Tenart static int safexcel_cipher_cra_exit(struct crypto_tfm *tfm) 12068ac1283eSAntoine Tenart { 12078ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 12088ac1283eSAntoine Tenart 1209ce679559SAntoine Tenart memzero_explicit(ctx->key, sizeof(ctx->key)); 12108ac1283eSAntoine Tenart 12118ac1283eSAntoine Tenart /* context not allocated, skip invalidation */ 12128ac1283eSAntoine Tenart if (!ctx->base.ctxr) 12138ac1283eSAntoine Tenart return -ENOMEM; 12148ac1283eSAntoine Tenart 1215ce679559SAntoine Tenart memzero_explicit(ctx->base.ctxr->data, sizeof(ctx->base.ctxr->data)); 12161b44c5a6SAntoine Ténart return 0; 12171b44c5a6SAntoine Ténart } 12181b44c5a6SAntoine Ténart 12191b44c5a6SAntoine Ténart static void safexcel_skcipher_cra_exit(struct crypto_tfm *tfm) 12201b44c5a6SAntoine Ténart { 12211b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 122218e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 12231b44c5a6SAntoine Ténart int ret; 12241b44c5a6SAntoine Ténart 12258ac1283eSAntoine Tenart if (safexcel_cipher_cra_exit(tfm)) 12261b44c5a6SAntoine Ténart return; 12271b44c5a6SAntoine Ténart 122853c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE) { 12298ac1283eSAntoine Tenart ret = safexcel_skcipher_exit_inv(tfm); 12301b44c5a6SAntoine Ténart if (ret) 12318ac1283eSAntoine Tenart dev_warn(priv->dev, "skcipher: invalidation error %d\n", 12328ac1283eSAntoine Tenart ret); 1233871df319SAntoine Ténart } else { 1234871df319SAntoine Ténart dma_pool_free(priv->context_pool, ctx->base.ctxr, 1235871df319SAntoine Ténart ctx->base.ctxr_dma); 1236871df319SAntoine Ténart } 12371b44c5a6SAntoine Ténart } 12381b44c5a6SAntoine Ténart 1239f6beaea3SAntoine Tenart static void safexcel_aead_cra_exit(struct crypto_tfm *tfm) 1240f6beaea3SAntoine Tenart { 1241f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 124218e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 1243f6beaea3SAntoine Tenart int ret; 1244f6beaea3SAntoine Tenart 1245f6beaea3SAntoine Tenart if (safexcel_cipher_cra_exit(tfm)) 1246f6beaea3SAntoine Tenart return; 1247f6beaea3SAntoine Tenart 124853c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE) { 1249f6beaea3SAntoine Tenart ret = safexcel_aead_exit_inv(tfm); 1250f6beaea3SAntoine Tenart if (ret) 1251f6beaea3SAntoine Tenart dev_warn(priv->dev, "aead: invalidation error %d\n", 1252f6beaea3SAntoine Tenart ret); 1253f6beaea3SAntoine Tenart } else { 1254f6beaea3SAntoine Tenart dma_pool_free(priv->context_pool, ctx->base.ctxr, 1255f6beaea3SAntoine Tenart ctx->base.ctxr_dma); 1256f6beaea3SAntoine Tenart } 1257f6beaea3SAntoine Tenart } 1258f6beaea3SAntoine Tenart 125993369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_ecb_cra_init(struct crypto_tfm *tfm) 126093369b5dSPascal van Leeuwen { 126193369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 126293369b5dSPascal van Leeuwen 126393369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 126493369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 126593369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 1266098e51e5SPascal van Leeuwen ctx->blocksz = 0; 1267098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 126893369b5dSPascal van Leeuwen return 0; 126993369b5dSPascal van Leeuwen } 127093369b5dSPascal van Leeuwen 12711b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_ecb_aes = { 12721b44c5a6SAntoine Ténart .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1273062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES, 12741b44c5a6SAntoine Ténart .alg.skcipher = { 12758ac1283eSAntoine Tenart .setkey = safexcel_skcipher_aes_setkey, 127693369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 127793369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 12781b44c5a6SAntoine Ténart .min_keysize = AES_MIN_KEY_SIZE, 12791b44c5a6SAntoine Ténart .max_keysize = AES_MAX_KEY_SIZE, 12801b44c5a6SAntoine Ténart .base = { 12811b44c5a6SAntoine Ténart .cra_name = "ecb(aes)", 12821b44c5a6SAntoine Ténart .cra_driver_name = "safexcel-ecb-aes", 1283aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 12842c95e6d9SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1285b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 12861b44c5a6SAntoine Ténart CRYPTO_ALG_KERN_DRIVER_ONLY, 12871b44c5a6SAntoine Ténart .cra_blocksize = AES_BLOCK_SIZE, 12881b44c5a6SAntoine Ténart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 12891b44c5a6SAntoine Ténart .cra_alignmask = 0, 129093369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_ecb_cra_init, 12911b44c5a6SAntoine Ténart .cra_exit = safexcel_skcipher_cra_exit, 12921b44c5a6SAntoine Ténart .cra_module = THIS_MODULE, 12931b44c5a6SAntoine Ténart }, 12941b44c5a6SAntoine Ténart }, 12951b44c5a6SAntoine Ténart }; 12961b44c5a6SAntoine Ténart 129793369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_cbc_cra_init(struct crypto_tfm *tfm) 12981b44c5a6SAntoine Ténart { 129993369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 13001b44c5a6SAntoine Ténart 130193369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 130293369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 1303098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 130493369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 130593369b5dSPascal van Leeuwen return 0; 13061b44c5a6SAntoine Ténart } 13071b44c5a6SAntoine Ténart 13081b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_cbc_aes = { 13091b44c5a6SAntoine Ténart .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1310062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES, 13111b44c5a6SAntoine Ténart .alg.skcipher = { 13128ac1283eSAntoine Tenart .setkey = safexcel_skcipher_aes_setkey, 131393369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 131493369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 13151b44c5a6SAntoine Ténart .min_keysize = AES_MIN_KEY_SIZE, 13161b44c5a6SAntoine Ténart .max_keysize = AES_MAX_KEY_SIZE, 13171b44c5a6SAntoine Ténart .ivsize = AES_BLOCK_SIZE, 13181b44c5a6SAntoine Ténart .base = { 13191b44c5a6SAntoine Ténart .cra_name = "cbc(aes)", 13201b44c5a6SAntoine Ténart .cra_driver_name = "safexcel-cbc-aes", 1321aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 13222c95e6d9SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1323b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 13241b44c5a6SAntoine Ténart CRYPTO_ALG_KERN_DRIVER_ONLY, 13251b44c5a6SAntoine Ténart .cra_blocksize = AES_BLOCK_SIZE, 13261b44c5a6SAntoine Ténart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 13271b44c5a6SAntoine Ténart .cra_alignmask = 0, 132893369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_cbc_cra_init, 13291b44c5a6SAntoine Ténart .cra_exit = safexcel_skcipher_cra_exit, 13301b44c5a6SAntoine Ténart .cra_module = THIS_MODULE, 13311b44c5a6SAntoine Ténart }, 13321b44c5a6SAntoine Ténart }, 13331b44c5a6SAntoine Ténart }; 1334f6beaea3SAntoine Tenart 133548e97afaSPascal van Leeuwen static int safexcel_skcipher_aes_cfb_cra_init(struct crypto_tfm *tfm) 133648e97afaSPascal van Leeuwen { 133748e97afaSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 133848e97afaSPascal van Leeuwen 133948e97afaSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 134048e97afaSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 1341098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 134248e97afaSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; 134348e97afaSPascal van Leeuwen return 0; 134448e97afaSPascal van Leeuwen } 134548e97afaSPascal van Leeuwen 134648e97afaSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cfb_aes = { 134748e97afaSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 134848e97afaSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB, 134948e97afaSPascal van Leeuwen .alg.skcipher = { 135048e97afaSPascal van Leeuwen .setkey = safexcel_skcipher_aes_setkey, 135148e97afaSPascal van Leeuwen .encrypt = safexcel_encrypt, 135248e97afaSPascal van Leeuwen .decrypt = safexcel_decrypt, 135348e97afaSPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE, 135448e97afaSPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE, 135548e97afaSPascal van Leeuwen .ivsize = AES_BLOCK_SIZE, 135648e97afaSPascal van Leeuwen .base = { 135748e97afaSPascal van Leeuwen .cra_name = "cfb(aes)", 135848e97afaSPascal van Leeuwen .cra_driver_name = "safexcel-cfb-aes", 135948e97afaSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 136048e97afaSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1361b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 136248e97afaSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 136348e97afaSPascal van Leeuwen .cra_blocksize = 1, 136448e97afaSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 136548e97afaSPascal van Leeuwen .cra_alignmask = 0, 136648e97afaSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_cfb_cra_init, 136748e97afaSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 136848e97afaSPascal van Leeuwen .cra_module = THIS_MODULE, 136948e97afaSPascal van Leeuwen }, 137048e97afaSPascal van Leeuwen }, 137148e97afaSPascal van Leeuwen }; 137248e97afaSPascal van Leeuwen 137350485dfbSPascal van Leeuwen static int safexcel_skcipher_aes_ofb_cra_init(struct crypto_tfm *tfm) 137450485dfbSPascal van Leeuwen { 137550485dfbSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 137650485dfbSPascal van Leeuwen 137750485dfbSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 137850485dfbSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 1379098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 138050485dfbSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; 138150485dfbSPascal van Leeuwen return 0; 138250485dfbSPascal van Leeuwen } 138350485dfbSPascal van Leeuwen 138450485dfbSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ofb_aes = { 138550485dfbSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 138650485dfbSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB, 138750485dfbSPascal van Leeuwen .alg.skcipher = { 138850485dfbSPascal van Leeuwen .setkey = safexcel_skcipher_aes_setkey, 138950485dfbSPascal van Leeuwen .encrypt = safexcel_encrypt, 139050485dfbSPascal van Leeuwen .decrypt = safexcel_decrypt, 139150485dfbSPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE, 139250485dfbSPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE, 139350485dfbSPascal van Leeuwen .ivsize = AES_BLOCK_SIZE, 139450485dfbSPascal van Leeuwen .base = { 139550485dfbSPascal van Leeuwen .cra_name = "ofb(aes)", 139650485dfbSPascal van Leeuwen .cra_driver_name = "safexcel-ofb-aes", 139750485dfbSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 139850485dfbSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1399b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 140050485dfbSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 140150485dfbSPascal van Leeuwen .cra_blocksize = 1, 140250485dfbSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 140350485dfbSPascal van Leeuwen .cra_alignmask = 0, 140450485dfbSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_ofb_cra_init, 140550485dfbSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 140650485dfbSPascal van Leeuwen .cra_module = THIS_MODULE, 140750485dfbSPascal van Leeuwen }, 140850485dfbSPascal van Leeuwen }, 140950485dfbSPascal van Leeuwen }; 141050485dfbSPascal van Leeuwen 141154f9e8faSPascal van Leeuwen static int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm, 141254f9e8faSPascal van Leeuwen const u8 *key, unsigned int len) 141354f9e8faSPascal van Leeuwen { 141454f9e8faSPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 141554f9e8faSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 141618e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 141754f9e8faSPascal van Leeuwen struct crypto_aes_ctx aes; 141854f9e8faSPascal van Leeuwen int ret, i; 141954f9e8faSPascal van Leeuwen unsigned int keylen; 142054f9e8faSPascal van Leeuwen 142154f9e8faSPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 1422f26882a3SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 142354f9e8faSPascal van Leeuwen /* exclude the nonce here */ 1424f26882a3SPascal van Leeuwen keylen = len - CTR_RFC3686_NONCE_SIZE; 142554f9e8faSPascal van Leeuwen ret = aes_expandkey(&aes, key, keylen); 1426674f368aSEric Biggers if (ret) 142754f9e8faSPascal van Leeuwen return ret; 142854f9e8faSPascal van Leeuwen 142954f9e8faSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 143054f9e8faSPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) { 143113a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 143254f9e8faSPascal van Leeuwen ctx->base.needs_inv = true; 143354f9e8faSPascal van Leeuwen break; 143454f9e8faSPascal van Leeuwen } 143554f9e8faSPascal van Leeuwen } 143654f9e8faSPascal van Leeuwen } 143754f9e8faSPascal van Leeuwen 143854f9e8faSPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) 143954f9e8faSPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 144054f9e8faSPascal van Leeuwen 144154f9e8faSPascal van Leeuwen ctx->key_len = keylen; 144254f9e8faSPascal van Leeuwen 144354f9e8faSPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 144454f9e8faSPascal van Leeuwen return 0; 144554f9e8faSPascal van Leeuwen } 144654f9e8faSPascal van Leeuwen 144793369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_ctr_cra_init(struct crypto_tfm *tfm) 144893369b5dSPascal van Leeuwen { 144993369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 145093369b5dSPascal van Leeuwen 145193369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 145293369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 1453098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 145493369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 145593369b5dSPascal van Leeuwen return 0; 145693369b5dSPascal van Leeuwen } 145793369b5dSPascal van Leeuwen 145854f9e8faSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ctr_aes = { 145954f9e8faSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1460062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES, 146154f9e8faSPascal van Leeuwen .alg.skcipher = { 146254f9e8faSPascal van Leeuwen .setkey = safexcel_skcipher_aesctr_setkey, 146393369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 146493369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 1465f26882a3SPascal van Leeuwen /* Add nonce size */ 1466f26882a3SPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 1467f26882a3SPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 1468f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 146954f9e8faSPascal van Leeuwen .base = { 147054f9e8faSPascal van Leeuwen .cra_name = "rfc3686(ctr(aes))", 147154f9e8faSPascal van Leeuwen .cra_driver_name = "safexcel-ctr-aes", 1472aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 147354f9e8faSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1474b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 147554f9e8faSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 147654f9e8faSPascal van Leeuwen .cra_blocksize = 1, 147754f9e8faSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 147854f9e8faSPascal van Leeuwen .cra_alignmask = 0, 147993369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_ctr_cra_init, 148054f9e8faSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 148154f9e8faSPascal van Leeuwen .cra_module = THIS_MODULE, 148254f9e8faSPascal van Leeuwen }, 148354f9e8faSPascal van Leeuwen }, 148454f9e8faSPascal van Leeuwen }; 148554f9e8faSPascal van Leeuwen 1486a7dea8c0SOfer Heifetz static int safexcel_des_setkey(struct crypto_skcipher *ctfm, const u8 *key, 1487a7dea8c0SOfer Heifetz unsigned int len) 1488a7dea8c0SOfer Heifetz { 148921f5a15eSArd Biesheuvel struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 149018e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 1491a7dea8c0SOfer Heifetz int ret; 1492a7dea8c0SOfer Heifetz 149321f5a15eSArd Biesheuvel ret = verify_skcipher_des_key(ctfm, key); 149421f5a15eSArd Biesheuvel if (ret) 149521f5a15eSArd Biesheuvel return ret; 1496a7dea8c0SOfer Heifetz 1497a7dea8c0SOfer Heifetz /* if context exits and key changed, need to invalidate it */ 1498177e358cSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 1499a7dea8c0SOfer Heifetz if (memcmp(ctx->key, key, len)) 1500a7dea8c0SOfer Heifetz ctx->base.needs_inv = true; 1501a7dea8c0SOfer Heifetz 1502a7dea8c0SOfer Heifetz memcpy(ctx->key, key, len); 1503a7dea8c0SOfer Heifetz ctx->key_len = len; 1504a7dea8c0SOfer Heifetz 1505a7dea8c0SOfer Heifetz return 0; 1506a7dea8c0SOfer Heifetz } 1507a7dea8c0SOfer Heifetz 150893369b5dSPascal van Leeuwen static int safexcel_skcipher_des_cbc_cra_init(struct crypto_tfm *tfm) 150993369b5dSPascal van Leeuwen { 151093369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 151193369b5dSPascal van Leeuwen 151293369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 151393369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; 1514098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 1515098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 151693369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 151793369b5dSPascal van Leeuwen return 0; 151893369b5dSPascal van Leeuwen } 151993369b5dSPascal van Leeuwen 1520a7dea8c0SOfer Heifetz struct safexcel_alg_template safexcel_alg_cbc_des = { 1521a7dea8c0SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1522062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 1523a7dea8c0SOfer Heifetz .alg.skcipher = { 1524a7dea8c0SOfer Heifetz .setkey = safexcel_des_setkey, 152593369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 152693369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 1527a7dea8c0SOfer Heifetz .min_keysize = DES_KEY_SIZE, 1528a7dea8c0SOfer Heifetz .max_keysize = DES_KEY_SIZE, 1529a7dea8c0SOfer Heifetz .ivsize = DES_BLOCK_SIZE, 1530a7dea8c0SOfer Heifetz .base = { 1531a7dea8c0SOfer Heifetz .cra_name = "cbc(des)", 1532a7dea8c0SOfer Heifetz .cra_driver_name = "safexcel-cbc-des", 1533aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 15342b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1535b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 1536a7dea8c0SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 1537a7dea8c0SOfer Heifetz .cra_blocksize = DES_BLOCK_SIZE, 1538a7dea8c0SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1539a7dea8c0SOfer Heifetz .cra_alignmask = 0, 154093369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des_cbc_cra_init, 1541a7dea8c0SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 1542a7dea8c0SOfer Heifetz .cra_module = THIS_MODULE, 1543a7dea8c0SOfer Heifetz }, 1544a7dea8c0SOfer Heifetz }, 1545a7dea8c0SOfer Heifetz }; 1546a7dea8c0SOfer Heifetz 154793369b5dSPascal van Leeuwen static int safexcel_skcipher_des_ecb_cra_init(struct crypto_tfm *tfm) 1548a7dea8c0SOfer Heifetz { 154993369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1550a7dea8c0SOfer Heifetz 155193369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 155293369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; 155393369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 1554098e51e5SPascal van Leeuwen ctx->blocksz = 0; 1555098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 155693369b5dSPascal van Leeuwen return 0; 1557a7dea8c0SOfer Heifetz } 1558a7dea8c0SOfer Heifetz 1559a7dea8c0SOfer Heifetz struct safexcel_alg_template safexcel_alg_ecb_des = { 1560a7dea8c0SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1561062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 1562a7dea8c0SOfer Heifetz .alg.skcipher = { 1563a7dea8c0SOfer Heifetz .setkey = safexcel_des_setkey, 156493369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 156593369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 1566a7dea8c0SOfer Heifetz .min_keysize = DES_KEY_SIZE, 1567a7dea8c0SOfer Heifetz .max_keysize = DES_KEY_SIZE, 1568a7dea8c0SOfer Heifetz .base = { 1569a7dea8c0SOfer Heifetz .cra_name = "ecb(des)", 1570a7dea8c0SOfer Heifetz .cra_driver_name = "safexcel-ecb-des", 1571aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 15722b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1573b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 1574a7dea8c0SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 1575a7dea8c0SOfer Heifetz .cra_blocksize = DES_BLOCK_SIZE, 1576a7dea8c0SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1577a7dea8c0SOfer Heifetz .cra_alignmask = 0, 157893369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des_ecb_cra_init, 1579a7dea8c0SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 1580a7dea8c0SOfer Heifetz .cra_module = THIS_MODULE, 1581a7dea8c0SOfer Heifetz }, 1582a7dea8c0SOfer Heifetz }, 1583a7dea8c0SOfer Heifetz }; 158462469879SOfer Heifetz 158562469879SOfer Heifetz static int safexcel_des3_ede_setkey(struct crypto_skcipher *ctfm, 158662469879SOfer Heifetz const u8 *key, unsigned int len) 158762469879SOfer Heifetz { 158867ac62bfSHerbert Xu struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 158918e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 159067ac62bfSHerbert Xu int err; 159162469879SOfer Heifetz 159221f5a15eSArd Biesheuvel err = verify_skcipher_des3_key(ctfm, key); 159321f5a15eSArd Biesheuvel if (err) 159467ac62bfSHerbert Xu return err; 159562469879SOfer Heifetz 159662469879SOfer Heifetz /* if context exits and key changed, need to invalidate it */ 1597177e358cSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 159862469879SOfer Heifetz if (memcmp(ctx->key, key, len)) 159962469879SOfer Heifetz ctx->base.needs_inv = true; 160062469879SOfer Heifetz 160162469879SOfer Heifetz memcpy(ctx->key, key, len); 160262469879SOfer Heifetz ctx->key_len = len; 160362469879SOfer Heifetz 160462469879SOfer Heifetz return 0; 160562469879SOfer Heifetz } 160662469879SOfer Heifetz 160793369b5dSPascal van Leeuwen static int safexcel_skcipher_des3_cbc_cra_init(struct crypto_tfm *tfm) 160893369b5dSPascal van Leeuwen { 160993369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 161093369b5dSPascal van Leeuwen 161193369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 161293369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; 1613098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 1614098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 161593369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 161693369b5dSPascal van Leeuwen return 0; 161793369b5dSPascal van Leeuwen } 161893369b5dSPascal van Leeuwen 161962469879SOfer Heifetz struct safexcel_alg_template safexcel_alg_cbc_des3_ede = { 162062469879SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1621062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 162262469879SOfer Heifetz .alg.skcipher = { 162362469879SOfer Heifetz .setkey = safexcel_des3_ede_setkey, 162493369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 162593369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 162662469879SOfer Heifetz .min_keysize = DES3_EDE_KEY_SIZE, 162762469879SOfer Heifetz .max_keysize = DES3_EDE_KEY_SIZE, 162862469879SOfer Heifetz .ivsize = DES3_EDE_BLOCK_SIZE, 162962469879SOfer Heifetz .base = { 163062469879SOfer Heifetz .cra_name = "cbc(des3_ede)", 163162469879SOfer Heifetz .cra_driver_name = "safexcel-cbc-des3_ede", 1632aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 16332b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1634b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 163562469879SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 163662469879SOfer Heifetz .cra_blocksize = DES3_EDE_BLOCK_SIZE, 163762469879SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 163862469879SOfer Heifetz .cra_alignmask = 0, 163993369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des3_cbc_cra_init, 164062469879SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 164162469879SOfer Heifetz .cra_module = THIS_MODULE, 164262469879SOfer Heifetz }, 164362469879SOfer Heifetz }, 164462469879SOfer Heifetz }; 164562469879SOfer Heifetz 164693369b5dSPascal van Leeuwen static int safexcel_skcipher_des3_ecb_cra_init(struct crypto_tfm *tfm) 164762469879SOfer Heifetz { 164893369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 164962469879SOfer Heifetz 165093369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 165193369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; 165293369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 1653098e51e5SPascal van Leeuwen ctx->blocksz = 0; 1654098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 165593369b5dSPascal van Leeuwen return 0; 165662469879SOfer Heifetz } 165762469879SOfer Heifetz 165862469879SOfer Heifetz struct safexcel_alg_template safexcel_alg_ecb_des3_ede = { 165962469879SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1660062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 166162469879SOfer Heifetz .alg.skcipher = { 166262469879SOfer Heifetz .setkey = safexcel_des3_ede_setkey, 166393369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 166493369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 166562469879SOfer Heifetz .min_keysize = DES3_EDE_KEY_SIZE, 166662469879SOfer Heifetz .max_keysize = DES3_EDE_KEY_SIZE, 166762469879SOfer Heifetz .base = { 166862469879SOfer Heifetz .cra_name = "ecb(des3_ede)", 166962469879SOfer Heifetz .cra_driver_name = "safexcel-ecb-des3_ede", 1670aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 16712b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1672b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 167362469879SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 167462469879SOfer Heifetz .cra_blocksize = DES3_EDE_BLOCK_SIZE, 167562469879SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 167662469879SOfer Heifetz .cra_alignmask = 0, 167793369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des3_ecb_cra_init, 167862469879SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 167962469879SOfer Heifetz .cra_module = THIS_MODULE, 168062469879SOfer Heifetz }, 168162469879SOfer Heifetz }, 168262469879SOfer Heifetz }; 168362469879SOfer Heifetz 168493369b5dSPascal van Leeuwen static int safexcel_aead_encrypt(struct aead_request *req) 1685f6beaea3SAntoine Tenart { 1686f6beaea3SAntoine Tenart struct safexcel_cipher_req *creq = aead_request_ctx(req); 1687f6beaea3SAntoine Tenart 168893369b5dSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 1689f6beaea3SAntoine Tenart } 1690f6beaea3SAntoine Tenart 169193369b5dSPascal van Leeuwen static int safexcel_aead_decrypt(struct aead_request *req) 1692f6beaea3SAntoine Tenart { 1693f6beaea3SAntoine Tenart struct safexcel_cipher_req *creq = aead_request_ctx(req); 1694f6beaea3SAntoine Tenart 169593369b5dSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 1696f6beaea3SAntoine Tenart } 1697f6beaea3SAntoine Tenart 1698f6beaea3SAntoine Tenart static int safexcel_aead_cra_init(struct crypto_tfm *tfm) 1699f6beaea3SAntoine Tenart { 1700f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1701f6beaea3SAntoine Tenart struct safexcel_alg_template *tmpl = 1702f6beaea3SAntoine Tenart container_of(tfm->__crt_alg, struct safexcel_alg_template, 1703f6beaea3SAntoine Tenart alg.aead.base); 1704f6beaea3SAntoine Tenart 1705f6beaea3SAntoine Tenart crypto_aead_set_reqsize(__crypto_aead_cast(tfm), 1706f6beaea3SAntoine Tenart sizeof(struct safexcel_cipher_req)); 1707f6beaea3SAntoine Tenart 170818e51895SHerbert Xu ctx->base.priv = tmpl->priv; 1709f6beaea3SAntoine Tenart 17100e17e362SPascal van Leeuwen ctx->alg = SAFEXCEL_AES; /* default */ 1711098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 1712098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD; 1713098e51e5SPascal van Leeuwen ctx->ctrinit = 1; 171493369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; /* default */ 1715f6beaea3SAntoine Tenart ctx->aead = true; 1716f6beaea3SAntoine Tenart ctx->base.send = safexcel_aead_send; 1717f6beaea3SAntoine Tenart ctx->base.handle_result = safexcel_aead_handle_result; 1718f6beaea3SAntoine Tenart return 0; 1719f6beaea3SAntoine Tenart } 1720f6beaea3SAntoine Tenart 172101ba061dSAntoine Tenart static int safexcel_aead_sha1_cra_init(struct crypto_tfm *tfm) 172201ba061dSAntoine Tenart { 172301ba061dSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 172401ba061dSAntoine Tenart 172501ba061dSAntoine Tenart safexcel_aead_cra_init(tfm); 1726a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; 172701ba061dSAntoine Tenart ctx->state_sz = SHA1_DIGEST_SIZE; 172801ba061dSAntoine Tenart return 0; 172901ba061dSAntoine Tenart } 173001ba061dSAntoine Tenart 173101ba061dSAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_aes = { 173201ba061dSAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1733062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1, 173401ba061dSAntoine Tenart .alg.aead = { 173577cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 173693369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 173793369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 173801ba061dSAntoine Tenart .ivsize = AES_BLOCK_SIZE, 173901ba061dSAntoine Tenart .maxauthsize = SHA1_DIGEST_SIZE, 174001ba061dSAntoine Tenart .base = { 174101ba061dSAntoine Tenart .cra_name = "authenc(hmac(sha1),cbc(aes))", 174201ba061dSAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-aes", 1743aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 17443f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1745b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 174601ba061dSAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 174701ba061dSAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 174801ba061dSAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 174901ba061dSAntoine Tenart .cra_alignmask = 0, 175001ba061dSAntoine Tenart .cra_init = safexcel_aead_sha1_cra_init, 175101ba061dSAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 175201ba061dSAntoine Tenart .cra_module = THIS_MODULE, 175301ba061dSAntoine Tenart }, 175401ba061dSAntoine Tenart }, 175501ba061dSAntoine Tenart }; 175601ba061dSAntoine Tenart 1757f6beaea3SAntoine Tenart static int safexcel_aead_sha256_cra_init(struct crypto_tfm *tfm) 1758f6beaea3SAntoine Tenart { 1759f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1760f6beaea3SAntoine Tenart 1761f6beaea3SAntoine Tenart safexcel_aead_cra_init(tfm); 1762a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256; 1763f6beaea3SAntoine Tenart ctx->state_sz = SHA256_DIGEST_SIZE; 1764f6beaea3SAntoine Tenart return 0; 1765f6beaea3SAntoine Tenart } 1766f6beaea3SAntoine Tenart 1767f6beaea3SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_aes = { 1768f6beaea3SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1769062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 1770f6beaea3SAntoine Tenart .alg.aead = { 177177cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 177293369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 177393369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1774f6beaea3SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 1775f6beaea3SAntoine Tenart .maxauthsize = SHA256_DIGEST_SIZE, 1776f6beaea3SAntoine Tenart .base = { 1777f6beaea3SAntoine Tenart .cra_name = "authenc(hmac(sha256),cbc(aes))", 1778f6beaea3SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-aes", 1779aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 17803f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1781b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 1782f6beaea3SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 1783f6beaea3SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 1784f6beaea3SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1785f6beaea3SAntoine Tenart .cra_alignmask = 0, 1786f6beaea3SAntoine Tenart .cra_init = safexcel_aead_sha256_cra_init, 1787f6beaea3SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 1788f6beaea3SAntoine Tenart .cra_module = THIS_MODULE, 1789f6beaea3SAntoine Tenart }, 1790f6beaea3SAntoine Tenart }, 1791f6beaea3SAntoine Tenart }; 1792678b2878SAntoine Tenart 1793678b2878SAntoine Tenart static int safexcel_aead_sha224_cra_init(struct crypto_tfm *tfm) 1794678b2878SAntoine Tenart { 1795678b2878SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1796678b2878SAntoine Tenart 1797678b2878SAntoine Tenart safexcel_aead_cra_init(tfm); 1798a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224; 1799678b2878SAntoine Tenart ctx->state_sz = SHA256_DIGEST_SIZE; 1800678b2878SAntoine Tenart return 0; 1801678b2878SAntoine Tenart } 1802678b2878SAntoine Tenart 1803678b2878SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_aes = { 1804678b2878SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1805062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 1806678b2878SAntoine Tenart .alg.aead = { 180777cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 180893369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 180993369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1810678b2878SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 1811678b2878SAntoine Tenart .maxauthsize = SHA224_DIGEST_SIZE, 1812678b2878SAntoine Tenart .base = { 1813678b2878SAntoine Tenart .cra_name = "authenc(hmac(sha224),cbc(aes))", 1814678b2878SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-aes", 1815aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 18163f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1817b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 1818678b2878SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 1819678b2878SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 1820678b2878SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1821678b2878SAntoine Tenart .cra_alignmask = 0, 1822678b2878SAntoine Tenart .cra_init = safexcel_aead_sha224_cra_init, 1823678b2878SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 1824678b2878SAntoine Tenart .cra_module = THIS_MODULE, 1825678b2878SAntoine Tenart }, 1826678b2878SAntoine Tenart }, 1827678b2878SAntoine Tenart }; 182887eee125SAntoine Tenart 182987eee125SAntoine Tenart static int safexcel_aead_sha512_cra_init(struct crypto_tfm *tfm) 183087eee125SAntoine Tenart { 183187eee125SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 183287eee125SAntoine Tenart 183387eee125SAntoine Tenart safexcel_aead_cra_init(tfm); 1834a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512; 183587eee125SAntoine Tenart ctx->state_sz = SHA512_DIGEST_SIZE; 183687eee125SAntoine Tenart return 0; 183787eee125SAntoine Tenart } 183887eee125SAntoine Tenart 183987eee125SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_aes = { 184087eee125SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1841062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 184287eee125SAntoine Tenart .alg.aead = { 184377cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 184493369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 184593369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 184687eee125SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 184787eee125SAntoine Tenart .maxauthsize = SHA512_DIGEST_SIZE, 184887eee125SAntoine Tenart .base = { 184987eee125SAntoine Tenart .cra_name = "authenc(hmac(sha512),cbc(aes))", 185087eee125SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-aes", 1851aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 18523f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1853b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 185487eee125SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 185587eee125SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 185687eee125SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 185787eee125SAntoine Tenart .cra_alignmask = 0, 185887eee125SAntoine Tenart .cra_init = safexcel_aead_sha512_cra_init, 185987eee125SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 186087eee125SAntoine Tenart .cra_module = THIS_MODULE, 186187eee125SAntoine Tenart }, 186287eee125SAntoine Tenart }, 186387eee125SAntoine Tenart }; 1864ea23cb53SAntoine Tenart 1865ea23cb53SAntoine Tenart static int safexcel_aead_sha384_cra_init(struct crypto_tfm *tfm) 1866ea23cb53SAntoine Tenart { 1867ea23cb53SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1868ea23cb53SAntoine Tenart 1869ea23cb53SAntoine Tenart safexcel_aead_cra_init(tfm); 1870a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384; 1871ea23cb53SAntoine Tenart ctx->state_sz = SHA512_DIGEST_SIZE; 1872ea23cb53SAntoine Tenart return 0; 1873ea23cb53SAntoine Tenart } 1874ea23cb53SAntoine Tenart 1875ea23cb53SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_aes = { 1876ea23cb53SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1877062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 1878ea23cb53SAntoine Tenart .alg.aead = { 187977cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 188093369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 188193369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1882ea23cb53SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 1883ea23cb53SAntoine Tenart .maxauthsize = SHA384_DIGEST_SIZE, 1884ea23cb53SAntoine Tenart .base = { 1885ea23cb53SAntoine Tenart .cra_name = "authenc(hmac(sha384),cbc(aes))", 1886ea23cb53SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-aes", 1887aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 18883f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1889b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 1890ea23cb53SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 1891ea23cb53SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 1892ea23cb53SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1893ea23cb53SAntoine Tenart .cra_alignmask = 0, 1894ea23cb53SAntoine Tenart .cra_init = safexcel_aead_sha384_cra_init, 1895ea23cb53SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 1896ea23cb53SAntoine Tenart .cra_module = THIS_MODULE, 1897ea23cb53SAntoine Tenart }, 1898ea23cb53SAntoine Tenart }, 1899ea23cb53SAntoine Tenart }; 190077cdd4efSPascal van Leeuwen 19010e17e362SPascal van Leeuwen static int safexcel_aead_sha1_des3_cra_init(struct crypto_tfm *tfm) 19020e17e362SPascal van Leeuwen { 19030e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 19040e17e362SPascal van Leeuwen 19050e17e362SPascal van Leeuwen safexcel_aead_sha1_cra_init(tfm); 19060e17e362SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1907098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 1908098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 19090e17e362SPascal van Leeuwen return 0; 19100e17e362SPascal van Leeuwen } 19110e17e362SPascal van Leeuwen 191277cdd4efSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des3_ede = { 191377cdd4efSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1914062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, 191577cdd4efSPascal van Leeuwen .alg.aead = { 191677cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 191793369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 191893369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 191977cdd4efSPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 192077cdd4efSPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 192177cdd4efSPascal van Leeuwen .base = { 192277cdd4efSPascal van Leeuwen .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", 192377cdd4efSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des3_ede", 1924aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 192577cdd4efSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1926b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 192777cdd4efSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 192877cdd4efSPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 192977cdd4efSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 193077cdd4efSPascal van Leeuwen .cra_alignmask = 0, 19310e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha1_des3_cra_init, 19320e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 19330e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 19340e17e362SPascal van Leeuwen }, 19350e17e362SPascal van Leeuwen }, 19360e17e362SPascal van Leeuwen }; 19370e17e362SPascal van Leeuwen 1938f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha256_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_sha256_cra_init(tfm); 1943f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1944098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 1945098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 1946f0a8bdf0SPascal van Leeuwen return 0; 1947f0a8bdf0SPascal van Leeuwen } 1948f0a8bdf0SPascal van Leeuwen 1949f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede = { 1950f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1951f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 1952f0a8bdf0SPascal van Leeuwen .alg.aead = { 1953f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 1954f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 1955f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1956f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 1957f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA256_DIGEST_SIZE, 1958f0a8bdf0SPascal van Leeuwen .base = { 1959f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", 1960f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des3_ede", 1961f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 1962f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1963b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 1964f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 1965f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 1966f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1967f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 1968f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha256_des3_cra_init, 1969f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 1970f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 1971f0a8bdf0SPascal van Leeuwen }, 1972f0a8bdf0SPascal van Leeuwen }, 1973f0a8bdf0SPascal van Leeuwen }; 1974f0a8bdf0SPascal van Leeuwen 1975f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha224_des3_cra_init(struct crypto_tfm *tfm) 1976f0a8bdf0SPascal van Leeuwen { 1977f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1978f0a8bdf0SPascal van Leeuwen 1979f0a8bdf0SPascal van Leeuwen safexcel_aead_sha224_cra_init(tfm); 1980f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1981098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 1982098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 1983f0a8bdf0SPascal van Leeuwen return 0; 1984f0a8bdf0SPascal van Leeuwen } 1985f0a8bdf0SPascal van Leeuwen 1986f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede = { 1987f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1988f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 1989f0a8bdf0SPascal van Leeuwen .alg.aead = { 1990f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 1991f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 1992f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1993f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 1994f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA224_DIGEST_SIZE, 1995f0a8bdf0SPascal van Leeuwen .base = { 1996f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha224),cbc(des3_ede))", 1997f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des3_ede", 1998f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 1999f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2000b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2001f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2002f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2003f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2004f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 2005f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha224_des3_cra_init, 2006f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2007f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 2008f0a8bdf0SPascal van Leeuwen }, 2009f0a8bdf0SPascal van Leeuwen }, 2010f0a8bdf0SPascal van Leeuwen }; 2011f0a8bdf0SPascal van Leeuwen 2012f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha512_des3_cra_init(struct crypto_tfm *tfm) 2013f0a8bdf0SPascal van Leeuwen { 2014f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2015f0a8bdf0SPascal van Leeuwen 2016f0a8bdf0SPascal van Leeuwen safexcel_aead_sha512_cra_init(tfm); 2017f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 2018098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 2019098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2020f0a8bdf0SPascal van Leeuwen return 0; 2021f0a8bdf0SPascal van Leeuwen } 2022f0a8bdf0SPascal van Leeuwen 2023f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede = { 2024f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2025f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2026f0a8bdf0SPascal van Leeuwen .alg.aead = { 2027f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 2028f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2029f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2030f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 2031f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA512_DIGEST_SIZE, 2032f0a8bdf0SPascal van Leeuwen .base = { 2033f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha512),cbc(des3_ede))", 2034f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des3_ede", 2035f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2036f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2037b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2038f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2039f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2040f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2041f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 2042f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha512_des3_cra_init, 2043f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2044f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 2045f0a8bdf0SPascal van Leeuwen }, 2046f0a8bdf0SPascal van Leeuwen }, 2047f0a8bdf0SPascal van Leeuwen }; 2048f0a8bdf0SPascal van Leeuwen 2049f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha384_des3_cra_init(struct crypto_tfm *tfm) 2050f0a8bdf0SPascal van Leeuwen { 2051f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2052f0a8bdf0SPascal van Leeuwen 2053f0a8bdf0SPascal van Leeuwen safexcel_aead_sha384_cra_init(tfm); 2054f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 2055098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 2056098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2057f0a8bdf0SPascal van Leeuwen return 0; 2058f0a8bdf0SPascal van Leeuwen } 2059f0a8bdf0SPascal van Leeuwen 2060f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede = { 2061f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2062f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2063f0a8bdf0SPascal van Leeuwen .alg.aead = { 2064f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 2065f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2066f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2067f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 2068f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA384_DIGEST_SIZE, 2069f0a8bdf0SPascal van Leeuwen .base = { 2070f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha384),cbc(des3_ede))", 2071f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des3_ede", 2072f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2073f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2074b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2075f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2076f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2077f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2078f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 2079f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha384_des3_cra_init, 2080f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2081f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 2082f0a8bdf0SPascal van Leeuwen }, 2083f0a8bdf0SPascal van Leeuwen }, 2084f0a8bdf0SPascal van Leeuwen }; 2085f0a8bdf0SPascal van Leeuwen 2086bb7679b8SPascal van Leeuwen static int safexcel_aead_sha1_des_cra_init(struct crypto_tfm *tfm) 2087bb7679b8SPascal van Leeuwen { 2088bb7679b8SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2089bb7679b8SPascal van Leeuwen 2090bb7679b8SPascal van Leeuwen safexcel_aead_sha1_cra_init(tfm); 2091bb7679b8SPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2092098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2093098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2094bb7679b8SPascal van Leeuwen return 0; 2095bb7679b8SPascal van Leeuwen } 2096bb7679b8SPascal van Leeuwen 2097bb7679b8SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des = { 2098bb7679b8SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2099bb7679b8SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, 2100bb7679b8SPascal van Leeuwen .alg.aead = { 2101bb7679b8SPascal van Leeuwen .setkey = safexcel_aead_setkey, 2102bb7679b8SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2103bb7679b8SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2104bb7679b8SPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2105bb7679b8SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 2106bb7679b8SPascal van Leeuwen .base = { 2107bb7679b8SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),cbc(des))", 2108bb7679b8SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des", 2109bb7679b8SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2110bb7679b8SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2111b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2112bb7679b8SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2113bb7679b8SPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2114bb7679b8SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2115bb7679b8SPascal van Leeuwen .cra_alignmask = 0, 2116bb7679b8SPascal van Leeuwen .cra_init = safexcel_aead_sha1_des_cra_init, 2117bb7679b8SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2118bb7679b8SPascal van Leeuwen .cra_module = THIS_MODULE, 2119bb7679b8SPascal van Leeuwen }, 2120bb7679b8SPascal van Leeuwen }, 2121bb7679b8SPascal van Leeuwen }; 2122bb7679b8SPascal van Leeuwen 2123457a6fdfSPascal van Leeuwen static int safexcel_aead_sha256_des_cra_init(struct crypto_tfm *tfm) 2124457a6fdfSPascal van Leeuwen { 2125457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2126457a6fdfSPascal van Leeuwen 2127457a6fdfSPascal van Leeuwen safexcel_aead_sha256_cra_init(tfm); 2128457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2129098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2130098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2131457a6fdfSPascal van Leeuwen return 0; 2132457a6fdfSPascal van Leeuwen } 2133457a6fdfSPascal van Leeuwen 2134457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des = { 2135457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2136457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 2137457a6fdfSPascal van Leeuwen .alg.aead = { 2138457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2139457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2140457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2141457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2142457a6fdfSPascal van Leeuwen .maxauthsize = SHA256_DIGEST_SIZE, 2143457a6fdfSPascal van Leeuwen .base = { 2144457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha256),cbc(des))", 2145457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des", 2146457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2147457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2148b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2149457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2150457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2151457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2152457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2153457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha256_des_cra_init, 2154457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2155457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2156457a6fdfSPascal van Leeuwen }, 2157457a6fdfSPascal van Leeuwen }, 2158457a6fdfSPascal van Leeuwen }; 2159457a6fdfSPascal van Leeuwen 2160457a6fdfSPascal van Leeuwen static int safexcel_aead_sha224_des_cra_init(struct crypto_tfm *tfm) 2161457a6fdfSPascal van Leeuwen { 2162457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2163457a6fdfSPascal van Leeuwen 2164457a6fdfSPascal van Leeuwen safexcel_aead_sha224_cra_init(tfm); 2165457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2166098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2167098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2168457a6fdfSPascal van Leeuwen return 0; 2169457a6fdfSPascal van Leeuwen } 2170457a6fdfSPascal van Leeuwen 2171457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des = { 2172457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2173457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 2174457a6fdfSPascal van Leeuwen .alg.aead = { 2175457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2176457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2177457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2178457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2179457a6fdfSPascal van Leeuwen .maxauthsize = SHA224_DIGEST_SIZE, 2180457a6fdfSPascal van Leeuwen .base = { 2181457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha224),cbc(des))", 2182457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des", 2183457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2184457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2185b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2186457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2187457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2188457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2189457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2190457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha224_des_cra_init, 2191457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2192457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2193457a6fdfSPascal van Leeuwen }, 2194457a6fdfSPascal van Leeuwen }, 2195457a6fdfSPascal van Leeuwen }; 2196457a6fdfSPascal van Leeuwen 2197457a6fdfSPascal van Leeuwen static int safexcel_aead_sha512_des_cra_init(struct crypto_tfm *tfm) 2198457a6fdfSPascal van Leeuwen { 2199457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2200457a6fdfSPascal van Leeuwen 2201457a6fdfSPascal van Leeuwen safexcel_aead_sha512_cra_init(tfm); 2202457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2203098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2204098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2205457a6fdfSPascal van Leeuwen return 0; 2206457a6fdfSPascal van Leeuwen } 2207457a6fdfSPascal van Leeuwen 2208457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des = { 2209457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2210457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2211457a6fdfSPascal van Leeuwen .alg.aead = { 2212457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2213457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2214457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2215457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2216457a6fdfSPascal van Leeuwen .maxauthsize = SHA512_DIGEST_SIZE, 2217457a6fdfSPascal van Leeuwen .base = { 2218457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha512),cbc(des))", 2219457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des", 2220457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2221457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2222b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2223457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2224457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2225457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2226457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2227457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha512_des_cra_init, 2228457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2229457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2230457a6fdfSPascal van Leeuwen }, 2231457a6fdfSPascal van Leeuwen }, 2232457a6fdfSPascal van Leeuwen }; 2233457a6fdfSPascal van Leeuwen 2234457a6fdfSPascal van Leeuwen static int safexcel_aead_sha384_des_cra_init(struct crypto_tfm *tfm) 2235457a6fdfSPascal van Leeuwen { 2236457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2237457a6fdfSPascal van Leeuwen 2238457a6fdfSPascal van Leeuwen safexcel_aead_sha384_cra_init(tfm); 2239457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2240098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2241098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2242457a6fdfSPascal van Leeuwen return 0; 2243457a6fdfSPascal van Leeuwen } 2244457a6fdfSPascal van Leeuwen 2245457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des = { 2246457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2247457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2248457a6fdfSPascal van Leeuwen .alg.aead = { 2249457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2250457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2251457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2252457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2253457a6fdfSPascal van Leeuwen .maxauthsize = SHA384_DIGEST_SIZE, 2254457a6fdfSPascal van Leeuwen .base = { 2255457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha384),cbc(des))", 2256457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des", 2257457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2258457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2259b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2260457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2261457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2262457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2263457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2264457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha384_des_cra_init, 2265457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2266457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2267457a6fdfSPascal van Leeuwen }, 2268457a6fdfSPascal van Leeuwen }, 2269457a6fdfSPascal van Leeuwen }; 2270457a6fdfSPascal van Leeuwen 22710e17e362SPascal van Leeuwen static int safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm *tfm) 22720e17e362SPascal van Leeuwen { 22730e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 22740e17e362SPascal van Leeuwen 22750e17e362SPascal van Leeuwen safexcel_aead_sha1_cra_init(tfm); 22760e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 22770e17e362SPascal van Leeuwen return 0; 22780e17e362SPascal van Leeuwen } 22790e17e362SPascal van Leeuwen 22800e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_aes = { 22810e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2282062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1, 22830e17e362SPascal van Leeuwen .alg.aead = { 22840e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 228593369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 228693369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2287f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 22880e17e362SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 22890e17e362SPascal van Leeuwen .base = { 22900e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))", 22910e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-aes", 2292aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 22930e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2294b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 22950e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 22960e17e362SPascal van Leeuwen .cra_blocksize = 1, 22970e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 22980e17e362SPascal van Leeuwen .cra_alignmask = 0, 22990e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha1_ctr_cra_init, 23000e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 23010e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 23020e17e362SPascal van Leeuwen }, 23030e17e362SPascal van Leeuwen }, 23040e17e362SPascal van Leeuwen }; 23050e17e362SPascal van Leeuwen 23060e17e362SPascal van Leeuwen static int safexcel_aead_sha256_ctr_cra_init(struct crypto_tfm *tfm) 23070e17e362SPascal van Leeuwen { 23080e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 23090e17e362SPascal van Leeuwen 23100e17e362SPascal van Leeuwen safexcel_aead_sha256_cra_init(tfm); 23110e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 23120e17e362SPascal van Leeuwen return 0; 23130e17e362SPascal van Leeuwen } 23140e17e362SPascal van Leeuwen 23150e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes = { 23160e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2317062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 23180e17e362SPascal van Leeuwen .alg.aead = { 23190e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 232093369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 232193369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2322f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 23230e17e362SPascal van Leeuwen .maxauthsize = SHA256_DIGEST_SIZE, 23240e17e362SPascal van Leeuwen .base = { 23250e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))", 23260e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha256-ctr-aes", 2327aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 23280e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2329b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 23300e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 23310e17e362SPascal van Leeuwen .cra_blocksize = 1, 23320e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 23330e17e362SPascal van Leeuwen .cra_alignmask = 0, 23340e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha256_ctr_cra_init, 23350e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 23360e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 23370e17e362SPascal van Leeuwen }, 23380e17e362SPascal van Leeuwen }, 23390e17e362SPascal van Leeuwen }; 23400e17e362SPascal van Leeuwen 23410e17e362SPascal van Leeuwen static int safexcel_aead_sha224_ctr_cra_init(struct crypto_tfm *tfm) 23420e17e362SPascal van Leeuwen { 23430e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 23440e17e362SPascal van Leeuwen 23450e17e362SPascal van Leeuwen safexcel_aead_sha224_cra_init(tfm); 23460e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 23470e17e362SPascal van Leeuwen return 0; 23480e17e362SPascal van Leeuwen } 23490e17e362SPascal van Leeuwen 23500e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_ctr_aes = { 23510e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2352062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 23530e17e362SPascal van Leeuwen .alg.aead = { 23540e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 235593369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 235693369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2357f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 23580e17e362SPascal van Leeuwen .maxauthsize = SHA224_DIGEST_SIZE, 23590e17e362SPascal van Leeuwen .base = { 23600e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))", 23610e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha224-ctr-aes", 2362aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 23630e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2364b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 23650e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 23660e17e362SPascal van Leeuwen .cra_blocksize = 1, 23670e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 23680e17e362SPascal van Leeuwen .cra_alignmask = 0, 23690e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha224_ctr_cra_init, 23700e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 23710e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 23720e17e362SPascal van Leeuwen }, 23730e17e362SPascal van Leeuwen }, 23740e17e362SPascal van Leeuwen }; 23750e17e362SPascal van Leeuwen 23760e17e362SPascal van Leeuwen static int safexcel_aead_sha512_ctr_cra_init(struct crypto_tfm *tfm) 23770e17e362SPascal van Leeuwen { 23780e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 23790e17e362SPascal van Leeuwen 23800e17e362SPascal van Leeuwen safexcel_aead_sha512_cra_init(tfm); 23810e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 23820e17e362SPascal van Leeuwen return 0; 23830e17e362SPascal van Leeuwen } 23840e17e362SPascal van Leeuwen 23850e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes = { 23860e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2387062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 23880e17e362SPascal van Leeuwen .alg.aead = { 23890e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 239093369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 239193369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2392f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 23930e17e362SPascal van Leeuwen .maxauthsize = SHA512_DIGEST_SIZE, 23940e17e362SPascal van Leeuwen .base = { 23950e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha512),rfc3686(ctr(aes)))", 23960e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha512-ctr-aes", 2397aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 23980e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2399b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 24000e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 24010e17e362SPascal van Leeuwen .cra_blocksize = 1, 24020e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 24030e17e362SPascal van Leeuwen .cra_alignmask = 0, 24040e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha512_ctr_cra_init, 24050e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 24060e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 24070e17e362SPascal van Leeuwen }, 24080e17e362SPascal van Leeuwen }, 24090e17e362SPascal van Leeuwen }; 24100e17e362SPascal van Leeuwen 24110e17e362SPascal van Leeuwen static int safexcel_aead_sha384_ctr_cra_init(struct crypto_tfm *tfm) 24120e17e362SPascal van Leeuwen { 24130e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 24140e17e362SPascal van Leeuwen 24150e17e362SPascal van Leeuwen safexcel_aead_sha384_cra_init(tfm); 24160e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 24170e17e362SPascal van Leeuwen return 0; 24180e17e362SPascal van Leeuwen } 24190e17e362SPascal van Leeuwen 24200e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes = { 24210e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2422062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 24230e17e362SPascal van Leeuwen .alg.aead = { 24240e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 242593369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 242693369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2427f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 24280e17e362SPascal van Leeuwen .maxauthsize = SHA384_DIGEST_SIZE, 24290e17e362SPascal van Leeuwen .base = { 24300e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha384),rfc3686(ctr(aes)))", 24310e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha384-ctr-aes", 2432aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 24330e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2434b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 24350e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 24360e17e362SPascal van Leeuwen .cra_blocksize = 1, 24370e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 24380e17e362SPascal van Leeuwen .cra_alignmask = 0, 24390e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha384_ctr_cra_init, 244077cdd4efSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 244177cdd4efSPascal van Leeuwen .cra_module = THIS_MODULE, 244277cdd4efSPascal van Leeuwen }, 244377cdd4efSPascal van Leeuwen }, 244477cdd4efSPascal van Leeuwen }; 2445c7da38a7SPascal van Leeuwen 2446c7da38a7SPascal van Leeuwen static int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm, 2447c7da38a7SPascal van Leeuwen const u8 *key, unsigned int len) 2448c7da38a7SPascal van Leeuwen { 2449c7da38a7SPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 2450c7da38a7SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 245118e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 2452c7da38a7SPascal van Leeuwen struct crypto_aes_ctx aes; 2453c7da38a7SPascal van Leeuwen int ret, i; 2454c7da38a7SPascal van Leeuwen unsigned int keylen; 2455c7da38a7SPascal van Leeuwen 2456c7da38a7SPascal van Leeuwen /* Check for illegal XTS keys */ 2457c7da38a7SPascal van Leeuwen ret = xts_verify_key(ctfm, key, len); 2458c7da38a7SPascal van Leeuwen if (ret) 2459c7da38a7SPascal van Leeuwen return ret; 2460c7da38a7SPascal van Leeuwen 2461c7da38a7SPascal van Leeuwen /* Only half of the key data is cipher key */ 2462c7da38a7SPascal van Leeuwen keylen = (len >> 1); 2463c7da38a7SPascal van Leeuwen ret = aes_expandkey(&aes, key, keylen); 2464674f368aSEric Biggers if (ret) 2465c7da38a7SPascal van Leeuwen return ret; 2466c7da38a7SPascal van Leeuwen 2467c7da38a7SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 2468c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) { 246913a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 2470c7da38a7SPascal van Leeuwen ctx->base.needs_inv = true; 2471c7da38a7SPascal van Leeuwen break; 2472c7da38a7SPascal van Leeuwen } 2473c7da38a7SPascal van Leeuwen } 2474c7da38a7SPascal van Leeuwen } 2475c7da38a7SPascal van Leeuwen 2476c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) 2477c7da38a7SPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 2478c7da38a7SPascal van Leeuwen 2479c7da38a7SPascal van Leeuwen /* The other half is the tweak key */ 2480c7da38a7SPascal van Leeuwen ret = aes_expandkey(&aes, (u8 *)(key + keylen), keylen); 2481674f368aSEric Biggers if (ret) 2482c7da38a7SPascal van Leeuwen return ret; 2483c7da38a7SPascal van Leeuwen 2484c7da38a7SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 2485c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) { 248613a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i + keylen / sizeof(u32)]) != 248713a1bb93SPascal van Leeuwen aes.key_enc[i]) { 2488c7da38a7SPascal van Leeuwen ctx->base.needs_inv = true; 2489c7da38a7SPascal van Leeuwen break; 2490c7da38a7SPascal van Leeuwen } 2491c7da38a7SPascal van Leeuwen } 2492c7da38a7SPascal van Leeuwen } 2493c7da38a7SPascal van Leeuwen 2494c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) 2495c7da38a7SPascal van Leeuwen ctx->key[i + keylen / sizeof(u32)] = 2496c7da38a7SPascal van Leeuwen cpu_to_le32(aes.key_enc[i]); 2497c7da38a7SPascal van Leeuwen 2498c7da38a7SPascal van Leeuwen ctx->key_len = keylen << 1; 2499c7da38a7SPascal van Leeuwen 2500c7da38a7SPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 2501c7da38a7SPascal van Leeuwen return 0; 2502c7da38a7SPascal van Leeuwen } 2503c7da38a7SPascal van Leeuwen 2504c7da38a7SPascal van Leeuwen static int safexcel_skcipher_aes_xts_cra_init(struct crypto_tfm *tfm) 2505c7da38a7SPascal van Leeuwen { 2506c7da38a7SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2507c7da38a7SPascal van Leeuwen 2508c7da38a7SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 2509c7da38a7SPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 2510098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 2511c7da38a7SPascal van Leeuwen ctx->xts = 1; 2512c7da38a7SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS; 2513c7da38a7SPascal van Leeuwen return 0; 2514c7da38a7SPascal van Leeuwen } 2515c7da38a7SPascal van Leeuwen 2516c7da38a7SPascal van Leeuwen static int safexcel_encrypt_xts(struct skcipher_request *req) 2517c7da38a7SPascal van Leeuwen { 2518c7da38a7SPascal van Leeuwen if (req->cryptlen < XTS_BLOCK_SIZE) 2519c7da38a7SPascal van Leeuwen return -EINVAL; 2520c7da38a7SPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 2521c7da38a7SPascal van Leeuwen SAFEXCEL_ENCRYPT); 2522c7da38a7SPascal van Leeuwen } 2523c7da38a7SPascal van Leeuwen 2524c7da38a7SPascal van Leeuwen static int safexcel_decrypt_xts(struct skcipher_request *req) 2525c7da38a7SPascal van Leeuwen { 2526c7da38a7SPascal van Leeuwen if (req->cryptlen < XTS_BLOCK_SIZE) 2527c7da38a7SPascal van Leeuwen return -EINVAL; 2528c7da38a7SPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 2529c7da38a7SPascal van Leeuwen SAFEXCEL_DECRYPT); 2530c7da38a7SPascal van Leeuwen } 2531c7da38a7SPascal van Leeuwen 2532c7da38a7SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_xts_aes = { 2533c7da38a7SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 2534062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XTS, 2535c7da38a7SPascal van Leeuwen .alg.skcipher = { 2536c7da38a7SPascal van Leeuwen .setkey = safexcel_skcipher_aesxts_setkey, 2537c7da38a7SPascal van Leeuwen .encrypt = safexcel_encrypt_xts, 2538c7da38a7SPascal van Leeuwen .decrypt = safexcel_decrypt_xts, 2539c7da38a7SPascal van Leeuwen /* XTS actually uses 2 AES keys glued together */ 2540c7da38a7SPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE * 2, 2541c7da38a7SPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE * 2, 2542c7da38a7SPascal van Leeuwen .ivsize = XTS_BLOCK_SIZE, 2543c7da38a7SPascal van Leeuwen .base = { 2544c7da38a7SPascal van Leeuwen .cra_name = "xts(aes)", 2545c7da38a7SPascal van Leeuwen .cra_driver_name = "safexcel-xts-aes", 2546aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2547c7da38a7SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2548b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2549c7da38a7SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2550c7da38a7SPascal van Leeuwen .cra_blocksize = XTS_BLOCK_SIZE, 2551c7da38a7SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2552c7da38a7SPascal van Leeuwen .cra_alignmask = 0, 2553c7da38a7SPascal van Leeuwen .cra_init = safexcel_skcipher_aes_xts_cra_init, 2554c7da38a7SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 2555c7da38a7SPascal van Leeuwen .cra_module = THIS_MODULE, 2556c7da38a7SPascal van Leeuwen }, 2557c7da38a7SPascal van Leeuwen }, 2558c7da38a7SPascal van Leeuwen }; 25593e450886SPascal van Leeuwen 25603e450886SPascal van Leeuwen static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, 25613e450886SPascal van Leeuwen unsigned int len) 25623e450886SPascal van Leeuwen { 25633e450886SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 25643e450886SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 256518e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 25663e450886SPascal van Leeuwen struct crypto_aes_ctx aes; 25673e450886SPascal van Leeuwen u32 hashkey[AES_BLOCK_SIZE >> 2]; 25683e450886SPascal van Leeuwen int ret, i; 25693e450886SPascal van Leeuwen 25703e450886SPascal van Leeuwen ret = aes_expandkey(&aes, key, len); 25713e450886SPascal van Leeuwen if (ret) { 25723e450886SPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 25733e450886SPascal van Leeuwen return ret; 25743e450886SPascal van Leeuwen } 25753e450886SPascal van Leeuwen 25763e450886SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 25773e450886SPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) { 257813a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 25793e450886SPascal van Leeuwen ctx->base.needs_inv = true; 25803e450886SPascal van Leeuwen break; 25813e450886SPascal van Leeuwen } 25823e450886SPascal van Leeuwen } 25833e450886SPascal van Leeuwen } 25843e450886SPascal van Leeuwen 25853e450886SPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) 25863e450886SPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 25873e450886SPascal van Leeuwen 25883e450886SPascal van Leeuwen ctx->key_len = len; 25893e450886SPascal van Leeuwen 25903e450886SPascal van Leeuwen /* Compute hash key by encrypting zeroes with cipher key */ 25913e450886SPascal van Leeuwen crypto_cipher_clear_flags(ctx->hkaes, CRYPTO_TFM_REQ_MASK); 25923e450886SPascal van Leeuwen crypto_cipher_set_flags(ctx->hkaes, crypto_aead_get_flags(ctfm) & 25933e450886SPascal van Leeuwen CRYPTO_TFM_REQ_MASK); 25943e450886SPascal van Leeuwen ret = crypto_cipher_setkey(ctx->hkaes, key, len); 25953e450886SPascal van Leeuwen if (ret) 25963e450886SPascal van Leeuwen return ret; 25973e450886SPascal van Leeuwen 25983e450886SPascal van Leeuwen memset(hashkey, 0, AES_BLOCK_SIZE); 25993e450886SPascal van Leeuwen crypto_cipher_encrypt_one(ctx->hkaes, (u8 *)hashkey, (u8 *)hashkey); 26003e450886SPascal van Leeuwen 26013e450886SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 26023e450886SPascal van Leeuwen for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) { 260378cf1c8bSHerbert Xu if (be32_to_cpu(ctx->base.ipad.be[i]) != hashkey[i]) { 26043e450886SPascal van Leeuwen ctx->base.needs_inv = true; 26053e450886SPascal van Leeuwen break; 26063e450886SPascal van Leeuwen } 26073e450886SPascal van Leeuwen } 26083e450886SPascal van Leeuwen } 26093e450886SPascal van Leeuwen 26103e450886SPascal van Leeuwen for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) 261178cf1c8bSHerbert Xu ctx->base.ipad.be[i] = cpu_to_be32(hashkey[i]); 26123e450886SPascal van Leeuwen 26133e450886SPascal van Leeuwen memzero_explicit(hashkey, AES_BLOCK_SIZE); 26143e450886SPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 26153e450886SPascal van Leeuwen return 0; 26163e450886SPascal van Leeuwen } 26173e450886SPascal van Leeuwen 26183e450886SPascal van Leeuwen static int safexcel_aead_gcm_cra_init(struct crypto_tfm *tfm) 26193e450886SPascal van Leeuwen { 26203e450886SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 26213e450886SPascal van Leeuwen 26223e450886SPascal van Leeuwen safexcel_aead_cra_init(tfm); 26233e450886SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_GHASH; 26243e450886SPascal van Leeuwen ctx->state_sz = GHASH_BLOCK_SIZE; 26254eb76fafSPascal van Leeuwen ctx->xcm = EIP197_XCM_MODE_GCM; 26263e450886SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ 26273e450886SPascal van Leeuwen 26283e450886SPascal van Leeuwen ctx->hkaes = crypto_alloc_cipher("aes", 0, 0); 26293f61b052Szhengbin return PTR_ERR_OR_ZERO(ctx->hkaes); 26303e450886SPascal van Leeuwen } 26313e450886SPascal van Leeuwen 26323e450886SPascal van Leeuwen static void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm) 26333e450886SPascal van Leeuwen { 26343e450886SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 26353e450886SPascal van Leeuwen 26363e450886SPascal van Leeuwen crypto_free_cipher(ctx->hkaes); 26373e450886SPascal van Leeuwen safexcel_aead_cra_exit(tfm); 26383e450886SPascal van Leeuwen } 26393e450886SPascal van Leeuwen 26403e450886SPascal van Leeuwen static int safexcel_aead_gcm_setauthsize(struct crypto_aead *tfm, 26413e450886SPascal van Leeuwen unsigned int authsize) 26423e450886SPascal van Leeuwen { 26433e450886SPascal van Leeuwen return crypto_gcm_check_authsize(authsize); 26443e450886SPascal van Leeuwen } 26453e450886SPascal van Leeuwen 26463e450886SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_gcm = { 26473e450886SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 26483e450886SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 26493e450886SPascal van Leeuwen .alg.aead = { 26503e450886SPascal van Leeuwen .setkey = safexcel_aead_gcm_setkey, 26513e450886SPascal van Leeuwen .setauthsize = safexcel_aead_gcm_setauthsize, 26523e450886SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 26533e450886SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 26543e450886SPascal van Leeuwen .ivsize = GCM_AES_IV_SIZE, 26553e450886SPascal van Leeuwen .maxauthsize = GHASH_DIGEST_SIZE, 26563e450886SPascal van Leeuwen .base = { 26573e450886SPascal van Leeuwen .cra_name = "gcm(aes)", 26583e450886SPascal van Leeuwen .cra_driver_name = "safexcel-gcm-aes", 26593e450886SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 26603e450886SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2661b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 26623e450886SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 26633e450886SPascal van Leeuwen .cra_blocksize = 1, 26643e450886SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 26653e450886SPascal van Leeuwen .cra_alignmask = 0, 26663e450886SPascal van Leeuwen .cra_init = safexcel_aead_gcm_cra_init, 26673e450886SPascal van Leeuwen .cra_exit = safexcel_aead_gcm_cra_exit, 26683e450886SPascal van Leeuwen .cra_module = THIS_MODULE, 26693e450886SPascal van Leeuwen }, 26703e450886SPascal van Leeuwen }, 26713e450886SPascal van Leeuwen }; 26724eb76fafSPascal van Leeuwen 26734eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, 26744eb76fafSPascal van Leeuwen unsigned int len) 26754eb76fafSPascal van Leeuwen { 26764eb76fafSPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 26774eb76fafSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 267818e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 26794eb76fafSPascal van Leeuwen struct crypto_aes_ctx aes; 26804eb76fafSPascal van Leeuwen int ret, i; 26814eb76fafSPascal van Leeuwen 26824eb76fafSPascal van Leeuwen ret = aes_expandkey(&aes, key, len); 26834eb76fafSPascal van Leeuwen if (ret) { 26844eb76fafSPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 26854eb76fafSPascal van Leeuwen return ret; 26864eb76fafSPascal van Leeuwen } 26874eb76fafSPascal van Leeuwen 26884eb76fafSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 26894eb76fafSPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) { 269013a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 26914eb76fafSPascal van Leeuwen ctx->base.needs_inv = true; 26924eb76fafSPascal van Leeuwen break; 26934eb76fafSPascal van Leeuwen } 26944eb76fafSPascal van Leeuwen } 26954eb76fafSPascal van Leeuwen } 26964eb76fafSPascal van Leeuwen 26974eb76fafSPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) { 26984eb76fafSPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 269978cf1c8bSHerbert Xu ctx->base.ipad.be[i + 2 * AES_BLOCK_SIZE / sizeof(u32)] = 27004eb76fafSPascal van Leeuwen cpu_to_be32(aes.key_enc[i]); 27014eb76fafSPascal van Leeuwen } 27024eb76fafSPascal van Leeuwen 27034eb76fafSPascal van Leeuwen ctx->key_len = len; 27044eb76fafSPascal van Leeuwen ctx->state_sz = 2 * AES_BLOCK_SIZE + len; 27054eb76fafSPascal van Leeuwen 27064eb76fafSPascal van Leeuwen if (len == AES_KEYSIZE_192) 27074eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192; 27084eb76fafSPascal van Leeuwen else if (len == AES_KEYSIZE_256) 27094eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256; 27104eb76fafSPascal van Leeuwen else 27114eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; 27124eb76fafSPascal van Leeuwen 27134eb76fafSPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 27144eb76fafSPascal van Leeuwen return 0; 27154eb76fafSPascal van Leeuwen } 27164eb76fafSPascal van Leeuwen 27174eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_cra_init(struct crypto_tfm *tfm) 27184eb76fafSPascal van Leeuwen { 27194eb76fafSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 27204eb76fafSPascal van Leeuwen 27214eb76fafSPascal van Leeuwen safexcel_aead_cra_init(tfm); 27224eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; 27234eb76fafSPascal van Leeuwen ctx->state_sz = 3 * AES_BLOCK_SIZE; 27244eb76fafSPascal van Leeuwen ctx->xcm = EIP197_XCM_MODE_CCM; 27254eb76fafSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ 2726098e51e5SPascal van Leeuwen ctx->ctrinit = 0; 27274eb76fafSPascal van Leeuwen return 0; 27284eb76fafSPascal van Leeuwen } 27294eb76fafSPascal van Leeuwen 27304eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_setauthsize(struct crypto_aead *tfm, 27314eb76fafSPascal van Leeuwen unsigned int authsize) 27324eb76fafSPascal van Leeuwen { 27334eb76fafSPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 27344eb76fafSPascal van Leeuwen switch (authsize) { 27354eb76fafSPascal van Leeuwen case 4: 27364eb76fafSPascal van Leeuwen case 6: 27374eb76fafSPascal van Leeuwen case 8: 27384eb76fafSPascal van Leeuwen case 10: 27394eb76fafSPascal van Leeuwen case 12: 27404eb76fafSPascal van Leeuwen case 14: 27414eb76fafSPascal van Leeuwen case 16: 27424eb76fafSPascal van Leeuwen break; 27434eb76fafSPascal van Leeuwen default: 27444eb76fafSPascal van Leeuwen return -EINVAL; 27454eb76fafSPascal van Leeuwen } 27464eb76fafSPascal van Leeuwen 27474eb76fafSPascal van Leeuwen return 0; 27484eb76fafSPascal van Leeuwen } 27494eb76fafSPascal van Leeuwen 27504eb76fafSPascal van Leeuwen static int safexcel_ccm_encrypt(struct aead_request *req) 27514eb76fafSPascal van Leeuwen { 27524eb76fafSPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 27534eb76fafSPascal van Leeuwen 27544eb76fafSPascal van Leeuwen if (req->iv[0] < 1 || req->iv[0] > 7) 27554eb76fafSPascal van Leeuwen return -EINVAL; 27564eb76fafSPascal van Leeuwen 27574eb76fafSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 27584eb76fafSPascal van Leeuwen } 27594eb76fafSPascal van Leeuwen 27604eb76fafSPascal van Leeuwen static int safexcel_ccm_decrypt(struct aead_request *req) 27614eb76fafSPascal van Leeuwen { 27624eb76fafSPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 27634eb76fafSPascal van Leeuwen 27644eb76fafSPascal van Leeuwen if (req->iv[0] < 1 || req->iv[0] > 7) 27654eb76fafSPascal van Leeuwen return -EINVAL; 27664eb76fafSPascal van Leeuwen 27674eb76fafSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 27684eb76fafSPascal van Leeuwen } 27694eb76fafSPascal van Leeuwen 27704eb76fafSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ccm = { 27714eb76fafSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 27724eb76fafSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, 27734eb76fafSPascal van Leeuwen .alg.aead = { 27744eb76fafSPascal van Leeuwen .setkey = safexcel_aead_ccm_setkey, 27754eb76fafSPascal van Leeuwen .setauthsize = safexcel_aead_ccm_setauthsize, 27764eb76fafSPascal van Leeuwen .encrypt = safexcel_ccm_encrypt, 27774eb76fafSPascal van Leeuwen .decrypt = safexcel_ccm_decrypt, 27784eb76fafSPascal van Leeuwen .ivsize = AES_BLOCK_SIZE, 27794eb76fafSPascal van Leeuwen .maxauthsize = AES_BLOCK_SIZE, 27804eb76fafSPascal van Leeuwen .base = { 27814eb76fafSPascal van Leeuwen .cra_name = "ccm(aes)", 27824eb76fafSPascal van Leeuwen .cra_driver_name = "safexcel-ccm-aes", 27834eb76fafSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 27844eb76fafSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2785b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 27864eb76fafSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 27874eb76fafSPascal van Leeuwen .cra_blocksize = 1, 27884eb76fafSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 27894eb76fafSPascal van Leeuwen .cra_alignmask = 0, 27904eb76fafSPascal van Leeuwen .cra_init = safexcel_aead_ccm_cra_init, 27914eb76fafSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 27924eb76fafSPascal van Leeuwen .cra_module = THIS_MODULE, 27934eb76fafSPascal van Leeuwen }, 27944eb76fafSPascal van Leeuwen }, 27954eb76fafSPascal van Leeuwen }; 27964a593fb3SPascal van Leeuwen 2797a6061921SPascal van Leeuwen static void safexcel_chacha20_setkey(struct safexcel_cipher_ctx *ctx, 2798a6061921SPascal van Leeuwen const u8 *key) 27994a593fb3SPascal van Leeuwen { 280018e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 28014a593fb3SPascal van Leeuwen 280213a1bb93SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 280313a1bb93SPascal van Leeuwen if (memcmp(ctx->key, key, CHACHA_KEY_SIZE)) 28044a593fb3SPascal van Leeuwen ctx->base.needs_inv = true; 28054a593fb3SPascal van Leeuwen 280613a1bb93SPascal van Leeuwen memcpy(ctx->key, key, CHACHA_KEY_SIZE); 28074a593fb3SPascal van Leeuwen ctx->key_len = CHACHA_KEY_SIZE; 2808a6061921SPascal van Leeuwen } 2809a6061921SPascal van Leeuwen 2810a6061921SPascal van Leeuwen static int safexcel_skcipher_chacha20_setkey(struct crypto_skcipher *ctfm, 2811a6061921SPascal van Leeuwen const u8 *key, unsigned int len) 2812a6061921SPascal van Leeuwen { 2813a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 2814a6061921SPascal van Leeuwen 2815674f368aSEric Biggers if (len != CHACHA_KEY_SIZE) 2816a6061921SPascal van Leeuwen return -EINVAL; 2817674f368aSEric Biggers 2818a6061921SPascal van Leeuwen safexcel_chacha20_setkey(ctx, key); 28194a593fb3SPascal van Leeuwen 28204a593fb3SPascal van Leeuwen return 0; 28214a593fb3SPascal van Leeuwen } 28224a593fb3SPascal van Leeuwen 28234a593fb3SPascal van Leeuwen static int safexcel_skcipher_chacha20_cra_init(struct crypto_tfm *tfm) 28244a593fb3SPascal van Leeuwen { 28254a593fb3SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 28264a593fb3SPascal van Leeuwen 28274a593fb3SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 28284a593fb3SPascal van Leeuwen ctx->alg = SAFEXCEL_CHACHA20; 2829098e51e5SPascal van Leeuwen ctx->ctrinit = 0; 28304a593fb3SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32; 28314a593fb3SPascal van Leeuwen return 0; 28324a593fb3SPascal van Leeuwen } 28334a593fb3SPascal van Leeuwen 28344a593fb3SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chacha20 = { 28354a593fb3SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 28364a593fb3SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_CHACHA20, 28374a593fb3SPascal van Leeuwen .alg.skcipher = { 28384a593fb3SPascal van Leeuwen .setkey = safexcel_skcipher_chacha20_setkey, 28394a593fb3SPascal van Leeuwen .encrypt = safexcel_encrypt, 28404a593fb3SPascal van Leeuwen .decrypt = safexcel_decrypt, 28414a593fb3SPascal van Leeuwen .min_keysize = CHACHA_KEY_SIZE, 28424a593fb3SPascal van Leeuwen .max_keysize = CHACHA_KEY_SIZE, 28434a593fb3SPascal van Leeuwen .ivsize = CHACHA_IV_SIZE, 28444a593fb3SPascal van Leeuwen .base = { 28454a593fb3SPascal van Leeuwen .cra_name = "chacha20", 28464a593fb3SPascal van Leeuwen .cra_driver_name = "safexcel-chacha20", 28474a593fb3SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 28484a593fb3SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2849b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 28504a593fb3SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 28514a593fb3SPascal van Leeuwen .cra_blocksize = 1, 28524a593fb3SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 28534a593fb3SPascal van Leeuwen .cra_alignmask = 0, 28544a593fb3SPascal van Leeuwen .cra_init = safexcel_skcipher_chacha20_cra_init, 28554a593fb3SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 28564a593fb3SPascal van Leeuwen .cra_module = THIS_MODULE, 28574a593fb3SPascal van Leeuwen }, 28584a593fb3SPascal van Leeuwen }, 28594a593fb3SPascal van Leeuwen }; 2860a6061921SPascal van Leeuwen 2861a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_setkey(struct crypto_aead *ctfm, 2862a6061921SPascal van Leeuwen const u8 *key, unsigned int len) 2863a6061921SPascal van Leeuwen { 2864a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_aead_ctx(ctfm); 2865a6061921SPascal van Leeuwen 2866a6061921SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP && 2867a6061921SPascal van Leeuwen len > EIP197_AEAD_IPSEC_NONCE_SIZE) { 2868a6061921SPascal van Leeuwen /* ESP variant has nonce appended to key */ 2869a6061921SPascal van Leeuwen len -= EIP197_AEAD_IPSEC_NONCE_SIZE; 2870a6061921SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len); 2871a6061921SPascal van Leeuwen } 2872674f368aSEric Biggers if (len != CHACHA_KEY_SIZE) 2873a6061921SPascal van Leeuwen return -EINVAL; 2874674f368aSEric Biggers 2875a6061921SPascal van Leeuwen safexcel_chacha20_setkey(ctx, key); 2876a6061921SPascal van Leeuwen 2877a6061921SPascal van Leeuwen return 0; 2878a6061921SPascal van Leeuwen } 2879a6061921SPascal van Leeuwen 2880a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_setauthsize(struct crypto_aead *tfm, 2881a6061921SPascal van Leeuwen unsigned int authsize) 2882a6061921SPascal van Leeuwen { 2883a6061921SPascal van Leeuwen if (authsize != POLY1305_DIGEST_SIZE) 2884a6061921SPascal van Leeuwen return -EINVAL; 2885a6061921SPascal van Leeuwen return 0; 2886a6061921SPascal van Leeuwen } 2887a6061921SPascal van Leeuwen 2888a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_crypt(struct aead_request *req, 2889a6061921SPascal van Leeuwen enum safexcel_cipher_direction dir) 2890a6061921SPascal van Leeuwen { 2891a6061921SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 2892a6061921SPascal van Leeuwen struct crypto_aead *aead = crypto_aead_reqtfm(req); 2893a6061921SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(aead); 2894a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2895a6061921SPascal van Leeuwen struct aead_request *subreq = aead_request_ctx(req); 2896a6061921SPascal van Leeuwen u32 key[CHACHA_KEY_SIZE / sizeof(u32) + 1]; 289713a1bb93SPascal van Leeuwen int ret = 0; 2898a6061921SPascal van Leeuwen 2899a6061921SPascal van Leeuwen /* 2900a6061921SPascal van Leeuwen * Instead of wasting time detecting umpteen silly corner cases, 2901a6061921SPascal van Leeuwen * just dump all "small" requests to the fallback implementation. 2902a6061921SPascal van Leeuwen * HW would not be faster on such small requests anyway. 2903a6061921SPascal van Leeuwen */ 2904a6061921SPascal van Leeuwen if (likely((ctx->aead != EIP197_AEAD_TYPE_IPSEC_ESP || 2905a6061921SPascal van Leeuwen req->assoclen >= EIP197_AEAD_IPSEC_IV_SIZE) && 2906a6061921SPascal van Leeuwen req->cryptlen > POLY1305_DIGEST_SIZE)) { 2907a6061921SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, dir); 2908a6061921SPascal van Leeuwen } 2909a6061921SPascal van Leeuwen 2910a6061921SPascal van Leeuwen /* HW cannot do full (AAD+payload) zero length, use fallback */ 291113a1bb93SPascal van Leeuwen memcpy(key, ctx->key, CHACHA_KEY_SIZE); 2912a6061921SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 2913a6061921SPascal van Leeuwen /* ESP variant has nonce appended to the key */ 2914a6061921SPascal van Leeuwen key[CHACHA_KEY_SIZE / sizeof(u32)] = ctx->nonce; 2915a6061921SPascal van Leeuwen ret = crypto_aead_setkey(ctx->fback, (u8 *)key, 2916a6061921SPascal van Leeuwen CHACHA_KEY_SIZE + 2917a6061921SPascal van Leeuwen EIP197_AEAD_IPSEC_NONCE_SIZE); 2918a6061921SPascal van Leeuwen } else { 2919a6061921SPascal van Leeuwen ret = crypto_aead_setkey(ctx->fback, (u8 *)key, 2920a6061921SPascal van Leeuwen CHACHA_KEY_SIZE); 2921a6061921SPascal van Leeuwen } 2922a6061921SPascal van Leeuwen if (ret) { 2923a6061921SPascal van Leeuwen crypto_aead_clear_flags(aead, CRYPTO_TFM_REQ_MASK); 2924a6061921SPascal van Leeuwen crypto_aead_set_flags(aead, crypto_aead_get_flags(ctx->fback) & 2925a6061921SPascal van Leeuwen CRYPTO_TFM_REQ_MASK); 2926a6061921SPascal van Leeuwen return ret; 2927a6061921SPascal van Leeuwen } 2928a6061921SPascal van Leeuwen 2929a6061921SPascal van Leeuwen aead_request_set_tfm(subreq, ctx->fback); 2930a6061921SPascal van Leeuwen aead_request_set_callback(subreq, req->base.flags, req->base.complete, 2931a6061921SPascal van Leeuwen req->base.data); 2932a6061921SPascal van Leeuwen aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 2933a6061921SPascal van Leeuwen req->iv); 2934a6061921SPascal van Leeuwen aead_request_set_ad(subreq, req->assoclen); 2935a6061921SPascal van Leeuwen 2936a6061921SPascal van Leeuwen return (dir == SAFEXCEL_ENCRYPT) ? 2937a6061921SPascal van Leeuwen crypto_aead_encrypt(subreq) : 2938a6061921SPascal van Leeuwen crypto_aead_decrypt(subreq); 2939a6061921SPascal van Leeuwen } 2940a6061921SPascal van Leeuwen 2941a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_encrypt(struct aead_request *req) 2942a6061921SPascal van Leeuwen { 2943a6061921SPascal van Leeuwen return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_ENCRYPT); 2944a6061921SPascal van Leeuwen } 2945a6061921SPascal van Leeuwen 2946a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_decrypt(struct aead_request *req) 2947a6061921SPascal van Leeuwen { 2948a6061921SPascal van Leeuwen return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_DECRYPT); 2949a6061921SPascal van Leeuwen } 2950a6061921SPascal van Leeuwen 29511769f704SPascal van Leeuwen static int safexcel_aead_fallback_cra_init(struct crypto_tfm *tfm) 2952a6061921SPascal van Leeuwen { 2953a6061921SPascal van Leeuwen struct crypto_aead *aead = __crypto_aead_cast(tfm); 2954a6061921SPascal van Leeuwen struct aead_alg *alg = crypto_aead_alg(aead); 2955a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2956a6061921SPascal van Leeuwen 2957a6061921SPascal van Leeuwen safexcel_aead_cra_init(tfm); 2958a6061921SPascal van Leeuwen 2959a6061921SPascal van Leeuwen /* Allocate fallback implementation */ 2960a6061921SPascal van Leeuwen ctx->fback = crypto_alloc_aead(alg->base.cra_name, 0, 2961a6061921SPascal van Leeuwen CRYPTO_ALG_ASYNC | 2962a6061921SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK); 2963a6061921SPascal van Leeuwen if (IS_ERR(ctx->fback)) 2964a6061921SPascal van Leeuwen return PTR_ERR(ctx->fback); 2965a6061921SPascal van Leeuwen 2966a6061921SPascal van Leeuwen crypto_aead_set_reqsize(aead, max(sizeof(struct safexcel_cipher_req), 2967a6061921SPascal van Leeuwen sizeof(struct aead_request) + 2968a6061921SPascal van Leeuwen crypto_aead_reqsize(ctx->fback))); 2969a6061921SPascal van Leeuwen 2970a6061921SPascal van Leeuwen return 0; 2971a6061921SPascal van Leeuwen } 2972a6061921SPascal van Leeuwen 29731769f704SPascal van Leeuwen static int safexcel_aead_chachapoly_cra_init(struct crypto_tfm *tfm) 29741769f704SPascal van Leeuwen { 29751769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 29761769f704SPascal van Leeuwen 29771769f704SPascal van Leeuwen safexcel_aead_fallback_cra_init(tfm); 29781769f704SPascal van Leeuwen ctx->alg = SAFEXCEL_CHACHA20; 29791769f704SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32 | 29801769f704SPascal van Leeuwen CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK; 2981098e51e5SPascal van Leeuwen ctx->ctrinit = 0; 29821769f704SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_POLY1305; 29831769f704SPascal van Leeuwen ctx->state_sz = 0; /* Precomputed by HW */ 29841769f704SPascal van Leeuwen return 0; 29851769f704SPascal van Leeuwen } 29861769f704SPascal van Leeuwen 29871769f704SPascal van Leeuwen static void safexcel_aead_fallback_cra_exit(struct crypto_tfm *tfm) 2988a6061921SPascal van Leeuwen { 2989a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2990a6061921SPascal van Leeuwen 2991a6061921SPascal van Leeuwen crypto_free_aead(ctx->fback); 2992a6061921SPascal van Leeuwen safexcel_aead_cra_exit(tfm); 2993a6061921SPascal van Leeuwen } 2994a6061921SPascal van Leeuwen 2995a6061921SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chachapoly = { 2996a6061921SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2997a6061921SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, 2998a6061921SPascal van Leeuwen .alg.aead = { 2999a6061921SPascal van Leeuwen .setkey = safexcel_aead_chachapoly_setkey, 3000a6061921SPascal van Leeuwen .setauthsize = safexcel_aead_chachapoly_setauthsize, 3001a6061921SPascal van Leeuwen .encrypt = safexcel_aead_chachapoly_encrypt, 3002a6061921SPascal van Leeuwen .decrypt = safexcel_aead_chachapoly_decrypt, 3003a6061921SPascal van Leeuwen .ivsize = CHACHAPOLY_IV_SIZE, 3004a6061921SPascal van Leeuwen .maxauthsize = POLY1305_DIGEST_SIZE, 3005a6061921SPascal van Leeuwen .base = { 3006a6061921SPascal van Leeuwen .cra_name = "rfc7539(chacha20,poly1305)", 3007a6061921SPascal van Leeuwen .cra_driver_name = "safexcel-chacha20-poly1305", 3008a6061921SPascal van Leeuwen /* +1 to put it above HW chacha + SW poly */ 3009a6061921SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, 3010a6061921SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3011b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 3012a6061921SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY | 3013a6061921SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK, 3014a6061921SPascal van Leeuwen .cra_blocksize = 1, 3015a6061921SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3016a6061921SPascal van Leeuwen .cra_alignmask = 0, 3017a6061921SPascal van Leeuwen .cra_init = safexcel_aead_chachapoly_cra_init, 30181769f704SPascal van Leeuwen .cra_exit = safexcel_aead_fallback_cra_exit, 3019a6061921SPascal van Leeuwen .cra_module = THIS_MODULE, 3020a6061921SPascal van Leeuwen }, 3021a6061921SPascal van Leeuwen }, 3022a6061921SPascal van Leeuwen }; 3023a6061921SPascal van Leeuwen 3024a6061921SPascal van Leeuwen static int safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm *tfm) 3025a6061921SPascal van Leeuwen { 3026a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3027a6061921SPascal van Leeuwen int ret; 3028a6061921SPascal van Leeuwen 3029a6061921SPascal van Leeuwen ret = safexcel_aead_chachapoly_cra_init(tfm); 3030a6061921SPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 3031098e51e5SPascal van Leeuwen ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 3032a6061921SPascal van Leeuwen return ret; 3033a6061921SPascal van Leeuwen } 3034a6061921SPascal van Leeuwen 3035a6061921SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chachapoly_esp = { 3036a6061921SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3037a6061921SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, 3038a6061921SPascal van Leeuwen .alg.aead = { 3039a6061921SPascal van Leeuwen .setkey = safexcel_aead_chachapoly_setkey, 3040a6061921SPascal van Leeuwen .setauthsize = safexcel_aead_chachapoly_setauthsize, 3041a6061921SPascal van Leeuwen .encrypt = safexcel_aead_chachapoly_encrypt, 3042a6061921SPascal van Leeuwen .decrypt = safexcel_aead_chachapoly_decrypt, 3043a6061921SPascal van Leeuwen .ivsize = CHACHAPOLY_IV_SIZE - EIP197_AEAD_IPSEC_NONCE_SIZE, 3044a6061921SPascal van Leeuwen .maxauthsize = POLY1305_DIGEST_SIZE, 3045a6061921SPascal van Leeuwen .base = { 3046a6061921SPascal van Leeuwen .cra_name = "rfc7539esp(chacha20,poly1305)", 3047a6061921SPascal van Leeuwen .cra_driver_name = "safexcel-chacha20-poly1305-esp", 3048a6061921SPascal van Leeuwen /* +1 to put it above HW chacha + SW poly */ 3049a6061921SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, 3050a6061921SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3051b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 3052a6061921SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY | 3053a6061921SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK, 3054a6061921SPascal van Leeuwen .cra_blocksize = 1, 3055a6061921SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3056a6061921SPascal van Leeuwen .cra_alignmask = 0, 3057a6061921SPascal van Leeuwen .cra_init = safexcel_aead_chachapolyesp_cra_init, 30581769f704SPascal van Leeuwen .cra_exit = safexcel_aead_fallback_cra_exit, 3059a6061921SPascal van Leeuwen .cra_module = THIS_MODULE, 3060a6061921SPascal van Leeuwen }, 3061a6061921SPascal van Leeuwen }, 3062a6061921SPascal van Leeuwen }; 3063fcca797dSPascal van Leeuwen 3064fcca797dSPascal van Leeuwen static int safexcel_skcipher_sm4_setkey(struct crypto_skcipher *ctfm, 3065fcca797dSPascal van Leeuwen const u8 *key, unsigned int len) 3066fcca797dSPascal van Leeuwen { 3067fcca797dSPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 3068fcca797dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 306918e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 3070fcca797dSPascal van Leeuwen 3071674f368aSEric Biggers if (len != SM4_KEY_SIZE) 3072fcca797dSPascal van Leeuwen return -EINVAL; 3073fcca797dSPascal van Leeuwen 307413a1bb93SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 307513a1bb93SPascal van Leeuwen if (memcmp(ctx->key, key, SM4_KEY_SIZE)) 3076fcca797dSPascal van Leeuwen ctx->base.needs_inv = true; 3077fcca797dSPascal van Leeuwen 307813a1bb93SPascal van Leeuwen memcpy(ctx->key, key, SM4_KEY_SIZE); 3079fcca797dSPascal van Leeuwen ctx->key_len = SM4_KEY_SIZE; 3080fcca797dSPascal van Leeuwen 3081fcca797dSPascal van Leeuwen return 0; 3082fcca797dSPascal van Leeuwen } 3083fcca797dSPascal van Leeuwen 3084fcca797dSPascal van Leeuwen static int safexcel_sm4_blk_encrypt(struct skcipher_request *req) 3085fcca797dSPascal van Leeuwen { 3086fcca797dSPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 3087fcca797dSPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 3088fcca797dSPascal van Leeuwen return -EINVAL; 3089fcca797dSPascal van Leeuwen else 3090fcca797dSPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 3091fcca797dSPascal van Leeuwen SAFEXCEL_ENCRYPT); 3092fcca797dSPascal van Leeuwen } 3093fcca797dSPascal van Leeuwen 3094fcca797dSPascal van Leeuwen static int safexcel_sm4_blk_decrypt(struct skcipher_request *req) 3095fcca797dSPascal van Leeuwen { 3096fcca797dSPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 3097fcca797dSPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 3098fcca797dSPascal van Leeuwen return -EINVAL; 3099fcca797dSPascal van Leeuwen else 3100fcca797dSPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 3101fcca797dSPascal van Leeuwen SAFEXCEL_DECRYPT); 3102fcca797dSPascal van Leeuwen } 3103fcca797dSPascal van Leeuwen 3104fcca797dSPascal van Leeuwen static int safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm *tfm) 3105fcca797dSPascal van Leeuwen { 3106fcca797dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3107fcca797dSPascal van Leeuwen 3108fcca797dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 3109fcca797dSPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3110fcca797dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 3111098e51e5SPascal van Leeuwen ctx->blocksz = 0; 3112098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 3113fcca797dSPascal van Leeuwen return 0; 3114fcca797dSPascal van Leeuwen } 3115fcca797dSPascal van Leeuwen 3116fcca797dSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ecb_sm4 = { 3117fcca797dSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 3118fcca797dSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4, 3119fcca797dSPascal van Leeuwen .alg.skcipher = { 3120fcca797dSPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 3121fcca797dSPascal van Leeuwen .encrypt = safexcel_sm4_blk_encrypt, 3122fcca797dSPascal van Leeuwen .decrypt = safexcel_sm4_blk_decrypt, 3123fcca797dSPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 3124fcca797dSPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 3125fcca797dSPascal van Leeuwen .base = { 3126fcca797dSPascal van Leeuwen .cra_name = "ecb(sm4)", 3127fcca797dSPascal van Leeuwen .cra_driver_name = "safexcel-ecb-sm4", 3128fcca797dSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3129fcca797dSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3130b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 3131fcca797dSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3132fcca797dSPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 3133fcca797dSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3134fcca797dSPascal van Leeuwen .cra_alignmask = 0, 3135fcca797dSPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_ecb_cra_init, 3136fcca797dSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 3137fcca797dSPascal van Leeuwen .cra_module = THIS_MODULE, 3138fcca797dSPascal van Leeuwen }, 3139fcca797dSPascal van Leeuwen }, 3140fcca797dSPascal van Leeuwen }; 31416f2d1428SPascal van Leeuwen 31426f2d1428SPascal van Leeuwen static int safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm *tfm) 31436f2d1428SPascal van Leeuwen { 31446f2d1428SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 31456f2d1428SPascal van Leeuwen 31466f2d1428SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 31476f2d1428SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3148098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 31496f2d1428SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 31506f2d1428SPascal van Leeuwen return 0; 31516f2d1428SPascal van Leeuwen } 31526f2d1428SPascal van Leeuwen 31536f2d1428SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cbc_sm4 = { 31546f2d1428SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 31556f2d1428SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4, 31566f2d1428SPascal van Leeuwen .alg.skcipher = { 31576f2d1428SPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 31586f2d1428SPascal van Leeuwen .encrypt = safexcel_sm4_blk_encrypt, 31596f2d1428SPascal van Leeuwen .decrypt = safexcel_sm4_blk_decrypt, 31606f2d1428SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 31616f2d1428SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 31626f2d1428SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 31636f2d1428SPascal van Leeuwen .base = { 31646f2d1428SPascal van Leeuwen .cra_name = "cbc(sm4)", 31656f2d1428SPascal van Leeuwen .cra_driver_name = "safexcel-cbc-sm4", 31666f2d1428SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 31676f2d1428SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3168b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 31696f2d1428SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 31706f2d1428SPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 31716f2d1428SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 31726f2d1428SPascal van Leeuwen .cra_alignmask = 0, 31736f2d1428SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_cbc_cra_init, 31746f2d1428SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 31756f2d1428SPascal van Leeuwen .cra_module = THIS_MODULE, 31766f2d1428SPascal van Leeuwen }, 31776f2d1428SPascal van Leeuwen }, 31786f2d1428SPascal van Leeuwen }; 317903a6cfb9SPascal van Leeuwen 318003a6cfb9SPascal van Leeuwen static int safexcel_skcipher_sm4_ofb_cra_init(struct crypto_tfm *tfm) 318103a6cfb9SPascal van Leeuwen { 318203a6cfb9SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 318303a6cfb9SPascal van Leeuwen 318403a6cfb9SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 318503a6cfb9SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3186098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 318703a6cfb9SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; 318803a6cfb9SPascal van Leeuwen return 0; 318903a6cfb9SPascal van Leeuwen } 319003a6cfb9SPascal van Leeuwen 319103a6cfb9SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ofb_sm4 = { 319203a6cfb9SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 319303a6cfb9SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, 319403a6cfb9SPascal van Leeuwen .alg.skcipher = { 319503a6cfb9SPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 319603a6cfb9SPascal van Leeuwen .encrypt = safexcel_encrypt, 319703a6cfb9SPascal van Leeuwen .decrypt = safexcel_decrypt, 319803a6cfb9SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 319903a6cfb9SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 320003a6cfb9SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 320103a6cfb9SPascal van Leeuwen .base = { 320203a6cfb9SPascal van Leeuwen .cra_name = "ofb(sm4)", 320303a6cfb9SPascal van Leeuwen .cra_driver_name = "safexcel-ofb-sm4", 320403a6cfb9SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 320503a6cfb9SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3206b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 320703a6cfb9SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 320803a6cfb9SPascal van Leeuwen .cra_blocksize = 1, 320903a6cfb9SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 321003a6cfb9SPascal van Leeuwen .cra_alignmask = 0, 321103a6cfb9SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_ofb_cra_init, 321203a6cfb9SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 321303a6cfb9SPascal van Leeuwen .cra_module = THIS_MODULE, 321403a6cfb9SPascal van Leeuwen }, 321503a6cfb9SPascal van Leeuwen }, 321603a6cfb9SPascal van Leeuwen }; 32177468ab22SPascal van Leeuwen 32187468ab22SPascal van Leeuwen static int safexcel_skcipher_sm4_cfb_cra_init(struct crypto_tfm *tfm) 32197468ab22SPascal van Leeuwen { 32207468ab22SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 32217468ab22SPascal van Leeuwen 32227468ab22SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 32237468ab22SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3224098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 32257468ab22SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; 32267468ab22SPascal van Leeuwen return 0; 32277468ab22SPascal van Leeuwen } 32287468ab22SPascal van Leeuwen 32297468ab22SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cfb_sm4 = { 32307468ab22SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 32317468ab22SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, 32327468ab22SPascal van Leeuwen .alg.skcipher = { 32337468ab22SPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 32347468ab22SPascal van Leeuwen .encrypt = safexcel_encrypt, 32357468ab22SPascal van Leeuwen .decrypt = safexcel_decrypt, 32367468ab22SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 32377468ab22SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 32387468ab22SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 32397468ab22SPascal van Leeuwen .base = { 32407468ab22SPascal van Leeuwen .cra_name = "cfb(sm4)", 32417468ab22SPascal van Leeuwen .cra_driver_name = "safexcel-cfb-sm4", 32427468ab22SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 32437468ab22SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3244b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 32457468ab22SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 32467468ab22SPascal van Leeuwen .cra_blocksize = 1, 32477468ab22SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 32487468ab22SPascal van Leeuwen .cra_alignmask = 0, 32497468ab22SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_cfb_cra_init, 32507468ab22SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 32517468ab22SPascal van Leeuwen .cra_module = THIS_MODULE, 32527468ab22SPascal van Leeuwen }, 32537468ab22SPascal van Leeuwen }, 32547468ab22SPascal van Leeuwen }; 3255f77e5dc0SPascal van Leeuwen 3256f77e5dc0SPascal van Leeuwen static int safexcel_skcipher_sm4ctr_setkey(struct crypto_skcipher *ctfm, 3257f77e5dc0SPascal van Leeuwen const u8 *key, unsigned int len) 3258f77e5dc0SPascal van Leeuwen { 3259f77e5dc0SPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 3260f77e5dc0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3261f77e5dc0SPascal van Leeuwen 3262f77e5dc0SPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 3263f77e5dc0SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 3264f77e5dc0SPascal van Leeuwen /* exclude the nonce here */ 3265f77e5dc0SPascal van Leeuwen len -= CTR_RFC3686_NONCE_SIZE; 3266f77e5dc0SPascal van Leeuwen 3267f77e5dc0SPascal van Leeuwen return safexcel_skcipher_sm4_setkey(ctfm, key, len); 3268f77e5dc0SPascal van Leeuwen } 3269f77e5dc0SPascal van Leeuwen 3270f77e5dc0SPascal van Leeuwen static int safexcel_skcipher_sm4_ctr_cra_init(struct crypto_tfm *tfm) 3271f77e5dc0SPascal van Leeuwen { 3272f77e5dc0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3273f77e5dc0SPascal van Leeuwen 3274f77e5dc0SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 3275f77e5dc0SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3276098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 3277f77e5dc0SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 3278f77e5dc0SPascal van Leeuwen return 0; 3279f77e5dc0SPascal van Leeuwen } 3280f77e5dc0SPascal van Leeuwen 3281f77e5dc0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ctr_sm4 = { 3282f77e5dc0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 3283f77e5dc0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4, 3284f77e5dc0SPascal van Leeuwen .alg.skcipher = { 3285f77e5dc0SPascal van Leeuwen .setkey = safexcel_skcipher_sm4ctr_setkey, 3286f77e5dc0SPascal van Leeuwen .encrypt = safexcel_encrypt, 3287f77e5dc0SPascal van Leeuwen .decrypt = safexcel_decrypt, 3288f77e5dc0SPascal van Leeuwen /* Add nonce size */ 3289f77e5dc0SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 3290f77e5dc0SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 3291f77e5dc0SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 3292f77e5dc0SPascal van Leeuwen .base = { 3293f77e5dc0SPascal van Leeuwen .cra_name = "rfc3686(ctr(sm4))", 3294f77e5dc0SPascal van Leeuwen .cra_driver_name = "safexcel-ctr-sm4", 3295f77e5dc0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3296f77e5dc0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3297b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 3298f77e5dc0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3299f77e5dc0SPascal van Leeuwen .cra_blocksize = 1, 3300f77e5dc0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3301f77e5dc0SPascal van Leeuwen .cra_alignmask = 0, 3302f77e5dc0SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_ctr_cra_init, 3303f77e5dc0SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 3304f77e5dc0SPascal van Leeuwen .cra_module = THIS_MODULE, 3305f77e5dc0SPascal van Leeuwen }, 3306f77e5dc0SPascal van Leeuwen }, 3307f77e5dc0SPascal van Leeuwen }; 33081769f704SPascal van Leeuwen 33091769f704SPascal van Leeuwen static int safexcel_aead_sm4_blk_encrypt(struct aead_request *req) 33101769f704SPascal van Leeuwen { 33111769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 33121769f704SPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 33131769f704SPascal van Leeuwen return -EINVAL; 33141769f704SPascal van Leeuwen 33151769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, aead_request_ctx(req), 33161769f704SPascal van Leeuwen SAFEXCEL_ENCRYPT); 33171769f704SPascal van Leeuwen } 33181769f704SPascal van Leeuwen 33191769f704SPascal van Leeuwen static int safexcel_aead_sm4_blk_decrypt(struct aead_request *req) 33201769f704SPascal van Leeuwen { 33211769f704SPascal van Leeuwen struct crypto_aead *tfm = crypto_aead_reqtfm(req); 33221769f704SPascal van Leeuwen 33231769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 33241769f704SPascal van Leeuwen if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) 33251769f704SPascal van Leeuwen return -EINVAL; 33261769f704SPascal van Leeuwen 33271769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, aead_request_ctx(req), 33281769f704SPascal van Leeuwen SAFEXCEL_DECRYPT); 33291769f704SPascal van Leeuwen } 33301769f704SPascal van Leeuwen 33311769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sha1_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_cra_init(tfm); 33361769f704SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3337098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 33381769f704SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; 33391769f704SPascal van Leeuwen ctx->state_sz = SHA1_DIGEST_SIZE; 33401769f704SPascal van Leeuwen return 0; 33411769f704SPascal van Leeuwen } 33421769f704SPascal van Leeuwen 33431769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4 = { 33441769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 33451769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, 33461769f704SPascal van Leeuwen .alg.aead = { 33471769f704SPascal van Leeuwen .setkey = safexcel_aead_setkey, 33481769f704SPascal van Leeuwen .encrypt = safexcel_aead_sm4_blk_encrypt, 33491769f704SPascal van Leeuwen .decrypt = safexcel_aead_sm4_blk_decrypt, 33501769f704SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 33511769f704SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 33521769f704SPascal van Leeuwen .base = { 33531769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),cbc(sm4))", 33541769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-sm4", 33551769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 33561769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3357b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 33581769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 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_sha1_cra_init, 33631769f704SPascal van Leeuwen .cra_exit = safexcel_aead_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_fallback_setkey(struct crypto_aead *ctfm, 33701769f704SPascal van Leeuwen const u8 *key, unsigned int len) 33711769f704SPascal van Leeuwen { 33721769f704SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 33731769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33741769f704SPascal van Leeuwen 33751769f704SPascal van Leeuwen /* Keep fallback cipher synchronized */ 33761769f704SPascal van Leeuwen return crypto_aead_setkey(ctx->fback, (u8 *)key, len) ?: 33771769f704SPascal van Leeuwen safexcel_aead_setkey(ctfm, key, len); 33781769f704SPascal van Leeuwen } 33791769f704SPascal van Leeuwen 33801769f704SPascal van Leeuwen static int safexcel_aead_fallback_setauthsize(struct crypto_aead *ctfm, 33811769f704SPascal van Leeuwen unsigned int authsize) 33821769f704SPascal van Leeuwen { 33831769f704SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 33841769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33851769f704SPascal van Leeuwen 33861769f704SPascal van Leeuwen /* Keep fallback cipher synchronized */ 33871769f704SPascal van Leeuwen return crypto_aead_setauthsize(ctx->fback, authsize); 33881769f704SPascal van Leeuwen } 33891769f704SPascal van Leeuwen 33901769f704SPascal van Leeuwen static int safexcel_aead_fallback_crypt(struct aead_request *req, 33911769f704SPascal van Leeuwen enum safexcel_cipher_direction dir) 33921769f704SPascal van Leeuwen { 33931769f704SPascal van Leeuwen struct crypto_aead *aead = crypto_aead_reqtfm(req); 33941769f704SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(aead); 33951769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33961769f704SPascal van Leeuwen struct aead_request *subreq = aead_request_ctx(req); 33971769f704SPascal van Leeuwen 33981769f704SPascal van Leeuwen aead_request_set_tfm(subreq, ctx->fback); 33991769f704SPascal van Leeuwen aead_request_set_callback(subreq, req->base.flags, req->base.complete, 34001769f704SPascal van Leeuwen req->base.data); 34011769f704SPascal van Leeuwen aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 34021769f704SPascal van Leeuwen req->iv); 34031769f704SPascal van Leeuwen aead_request_set_ad(subreq, req->assoclen); 34041769f704SPascal van Leeuwen 34051769f704SPascal van Leeuwen return (dir == SAFEXCEL_ENCRYPT) ? 34061769f704SPascal van Leeuwen crypto_aead_encrypt(subreq) : 34071769f704SPascal van Leeuwen crypto_aead_decrypt(subreq); 34081769f704SPascal van Leeuwen } 34091769f704SPascal van Leeuwen 34101769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request *req) 34111769f704SPascal van Leeuwen { 34121769f704SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 34131769f704SPascal van Leeuwen 34141769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 34151769f704SPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 34161769f704SPascal van Leeuwen return -EINVAL; 34171769f704SPascal van Leeuwen else if (req->cryptlen || req->assoclen) /* If input length > 0 only */ 34181769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 34191769f704SPascal van Leeuwen 34201769f704SPascal van Leeuwen /* HW cannot do full (AAD+payload) zero length, use fallback */ 34211769f704SPascal van Leeuwen return safexcel_aead_fallback_crypt(req, SAFEXCEL_ENCRYPT); 34221769f704SPascal van Leeuwen } 34231769f704SPascal van Leeuwen 34241769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request *req) 34251769f704SPascal van Leeuwen { 34261769f704SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 34271769f704SPascal van Leeuwen struct crypto_aead *tfm = crypto_aead_reqtfm(req); 34281769f704SPascal van Leeuwen 34291769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 34301769f704SPascal van Leeuwen if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) 34311769f704SPascal van Leeuwen return -EINVAL; 34321769f704SPascal van Leeuwen else if (req->cryptlen > crypto_aead_authsize(tfm) || req->assoclen) 34331769f704SPascal van Leeuwen /* If input length > 0 only */ 34341769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 34351769f704SPascal van Leeuwen 34361769f704SPascal van Leeuwen /* HW cannot do full (AAD+payload) zero length, use fallback */ 34371769f704SPascal van Leeuwen return safexcel_aead_fallback_crypt(req, SAFEXCEL_DECRYPT); 34381769f704SPascal van Leeuwen } 34391769f704SPascal van Leeuwen 34401769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm *tfm) 34411769f704SPascal van Leeuwen { 34421769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 34431769f704SPascal van Leeuwen 34441769f704SPascal van Leeuwen safexcel_aead_fallback_cra_init(tfm); 34451769f704SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3446098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 34471769f704SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3; 34481769f704SPascal van Leeuwen ctx->state_sz = SM3_DIGEST_SIZE; 34491769f704SPascal van Leeuwen return 0; 34501769f704SPascal van Leeuwen } 34511769f704SPascal van Leeuwen 34521769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4 = { 34531769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 34541769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, 34551769f704SPascal van Leeuwen .alg.aead = { 34561769f704SPascal van Leeuwen .setkey = safexcel_aead_fallback_setkey, 34571769f704SPascal van Leeuwen .setauthsize = safexcel_aead_fallback_setauthsize, 34581769f704SPascal van Leeuwen .encrypt = safexcel_aead_sm4cbc_sm3_encrypt, 34591769f704SPascal van Leeuwen .decrypt = safexcel_aead_sm4cbc_sm3_decrypt, 34601769f704SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 34611769f704SPascal van Leeuwen .maxauthsize = SM3_DIGEST_SIZE, 34621769f704SPascal van Leeuwen .base = { 34631769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sm3),cbc(sm4))", 34641769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sm3-cbc-sm4", 34651769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 34661769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3467b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 34681769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY | 34691769f704SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK, 34701769f704SPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 34711769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 34721769f704SPascal van Leeuwen .cra_alignmask = 0, 34731769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4cbc_sm3_cra_init, 34741769f704SPascal van Leeuwen .cra_exit = safexcel_aead_fallback_cra_exit, 34751769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 34761769f704SPascal van Leeuwen }, 34771769f704SPascal van Leeuwen }, 34781769f704SPascal van Leeuwen }; 34791769f704SPascal van Leeuwen 34801769f704SPascal van Leeuwen static int safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm *tfm) 34811769f704SPascal van Leeuwen { 34821769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 34831769f704SPascal van Leeuwen 34841769f704SPascal van Leeuwen safexcel_aead_sm4cbc_sha1_cra_init(tfm); 34851769f704SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 34861769f704SPascal van Leeuwen return 0; 34871769f704SPascal van Leeuwen } 34881769f704SPascal van Leeuwen 34891769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4 = { 34901769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 34911769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, 34921769f704SPascal van Leeuwen .alg.aead = { 34931769f704SPascal van Leeuwen .setkey = safexcel_aead_setkey, 34941769f704SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 34951769f704SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 34961769f704SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 34971769f704SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 34981769f704SPascal van Leeuwen .base = { 34991769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),rfc3686(ctr(sm4)))", 35001769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-sm4", 35011769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 35021769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3503b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 35041769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 35051769f704SPascal van Leeuwen .cra_blocksize = 1, 35061769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 35071769f704SPascal van Leeuwen .cra_alignmask = 0, 35081769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4ctr_sha1_cra_init, 35091769f704SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 35101769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 35111769f704SPascal van Leeuwen }, 35121769f704SPascal van Leeuwen }, 35131769f704SPascal van Leeuwen }; 35141769f704SPascal van Leeuwen 35151769f704SPascal van Leeuwen static int safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm *tfm) 35161769f704SPascal van Leeuwen { 35171769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 35181769f704SPascal van Leeuwen 35191769f704SPascal van Leeuwen safexcel_aead_sm4cbc_sm3_cra_init(tfm); 35201769f704SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 35211769f704SPascal van Leeuwen return 0; 35221769f704SPascal van Leeuwen } 35231769f704SPascal van Leeuwen 35241769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4 = { 35251769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 35261769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, 35271769f704SPascal van Leeuwen .alg.aead = { 35281769f704SPascal van Leeuwen .setkey = safexcel_aead_setkey, 35291769f704SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 35301769f704SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 35311769f704SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 35321769f704SPascal van Leeuwen .maxauthsize = SM3_DIGEST_SIZE, 35331769f704SPascal van Leeuwen .base = { 35341769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sm3),rfc3686(ctr(sm4)))", 35351769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sm3-ctr-sm4", 35361769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 35371769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3538b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 35391769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 35401769f704SPascal van Leeuwen .cra_blocksize = 1, 35411769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 35421769f704SPascal van Leeuwen .cra_alignmask = 0, 35431769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4ctr_sm3_cra_init, 35441769f704SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 35451769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 35461769f704SPascal van Leeuwen }, 35471769f704SPascal van Leeuwen }, 35481769f704SPascal van Leeuwen }; 3549a19052d4SPascal van Leeuwen 3550a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, 3551a19052d4SPascal van Leeuwen unsigned int len) 3552a19052d4SPascal van Leeuwen { 3553a19052d4SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 3554a19052d4SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3555a19052d4SPascal van Leeuwen 3556a19052d4SPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 3557a19052d4SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 3558a19052d4SPascal van Leeuwen 3559a19052d4SPascal van Leeuwen len -= CTR_RFC3686_NONCE_SIZE; 3560a19052d4SPascal van Leeuwen return safexcel_aead_gcm_setkey(ctfm, key, len); 3561a19052d4SPascal van Leeuwen } 3562a19052d4SPascal van Leeuwen 3563a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_setauthsize(struct crypto_aead *tfm, 3564a19052d4SPascal van Leeuwen unsigned int authsize) 3565a19052d4SPascal van Leeuwen { 3566a19052d4SPascal van Leeuwen return crypto_rfc4106_check_authsize(authsize); 3567a19052d4SPascal van Leeuwen } 3568a19052d4SPascal van Leeuwen 3569a19052d4SPascal van Leeuwen static int safexcel_rfc4106_encrypt(struct aead_request *req) 3570a19052d4SPascal van Leeuwen { 3571a19052d4SPascal van Leeuwen return crypto_ipsec_check_assoclen(req->assoclen) ?: 3572a19052d4SPascal van Leeuwen safexcel_aead_encrypt(req); 3573a19052d4SPascal van Leeuwen } 3574a19052d4SPascal van Leeuwen 3575a19052d4SPascal van Leeuwen static int safexcel_rfc4106_decrypt(struct aead_request *req) 3576a19052d4SPascal van Leeuwen { 3577a19052d4SPascal van Leeuwen return crypto_ipsec_check_assoclen(req->assoclen) ?: 3578a19052d4SPascal van Leeuwen safexcel_aead_decrypt(req); 3579a19052d4SPascal van Leeuwen } 3580a19052d4SPascal van Leeuwen 3581a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_cra_init(struct crypto_tfm *tfm) 3582a19052d4SPascal van Leeuwen { 3583a19052d4SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3584a19052d4SPascal van Leeuwen int ret; 3585a19052d4SPascal van Leeuwen 3586a19052d4SPascal van Leeuwen ret = safexcel_aead_gcm_cra_init(tfm); 3587a19052d4SPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 3588098e51e5SPascal van Leeuwen ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 3589a19052d4SPascal van Leeuwen return ret; 3590a19052d4SPascal van Leeuwen } 3591a19052d4SPascal van Leeuwen 3592a19052d4SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4106_gcm = { 3593a19052d4SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3594a19052d4SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 3595a19052d4SPascal van Leeuwen .alg.aead = { 3596a19052d4SPascal van Leeuwen .setkey = safexcel_rfc4106_gcm_setkey, 3597a19052d4SPascal van Leeuwen .setauthsize = safexcel_rfc4106_gcm_setauthsize, 3598a19052d4SPascal van Leeuwen .encrypt = safexcel_rfc4106_encrypt, 3599a19052d4SPascal van Leeuwen .decrypt = safexcel_rfc4106_decrypt, 3600a19052d4SPascal van Leeuwen .ivsize = GCM_RFC4106_IV_SIZE, 3601a19052d4SPascal van Leeuwen .maxauthsize = GHASH_DIGEST_SIZE, 3602a19052d4SPascal van Leeuwen .base = { 3603a19052d4SPascal van Leeuwen .cra_name = "rfc4106(gcm(aes))", 3604a19052d4SPascal van Leeuwen .cra_driver_name = "safexcel-rfc4106-gcm-aes", 3605a19052d4SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3606a19052d4SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3607b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 3608a19052d4SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3609a19052d4SPascal van Leeuwen .cra_blocksize = 1, 3610a19052d4SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3611a19052d4SPascal van Leeuwen .cra_alignmask = 0, 3612a19052d4SPascal van Leeuwen .cra_init = safexcel_rfc4106_gcm_cra_init, 3613a19052d4SPascal van Leeuwen .cra_exit = safexcel_aead_gcm_cra_exit, 3614a19052d4SPascal van Leeuwen }, 3615a19052d4SPascal van Leeuwen }, 3616a19052d4SPascal van Leeuwen }; 361792c60cefSPascal van Leeuwen 361892c60cefSPascal van Leeuwen static int safexcel_rfc4543_gcm_setauthsize(struct crypto_aead *tfm, 361992c60cefSPascal van Leeuwen unsigned int authsize) 362092c60cefSPascal van Leeuwen { 362192c60cefSPascal van Leeuwen if (authsize != GHASH_DIGEST_SIZE) 362292c60cefSPascal van Leeuwen return -EINVAL; 362392c60cefSPascal van Leeuwen 362492c60cefSPascal van Leeuwen return 0; 362592c60cefSPascal van Leeuwen } 362692c60cefSPascal van Leeuwen 362792c60cefSPascal van Leeuwen static int safexcel_rfc4543_gcm_cra_init(struct crypto_tfm *tfm) 362892c60cefSPascal van Leeuwen { 362992c60cefSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 363092c60cefSPascal van Leeuwen int ret; 363192c60cefSPascal van Leeuwen 363292c60cefSPascal van Leeuwen ret = safexcel_aead_gcm_cra_init(tfm); 363392c60cefSPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP_GMAC; 363492c60cefSPascal van Leeuwen return ret; 363592c60cefSPascal van Leeuwen } 363692c60cefSPascal van Leeuwen 363792c60cefSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4543_gcm = { 363892c60cefSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 363992c60cefSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 364092c60cefSPascal van Leeuwen .alg.aead = { 364192c60cefSPascal van Leeuwen .setkey = safexcel_rfc4106_gcm_setkey, 364292c60cefSPascal van Leeuwen .setauthsize = safexcel_rfc4543_gcm_setauthsize, 364392c60cefSPascal van Leeuwen .encrypt = safexcel_rfc4106_encrypt, 364492c60cefSPascal van Leeuwen .decrypt = safexcel_rfc4106_decrypt, 364592c60cefSPascal van Leeuwen .ivsize = GCM_RFC4543_IV_SIZE, 364692c60cefSPascal van Leeuwen .maxauthsize = GHASH_DIGEST_SIZE, 364792c60cefSPascal van Leeuwen .base = { 364892c60cefSPascal van Leeuwen .cra_name = "rfc4543(gcm(aes))", 364992c60cefSPascal van Leeuwen .cra_driver_name = "safexcel-rfc4543-gcm-aes", 365092c60cefSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 365192c60cefSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3652b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 365392c60cefSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 365492c60cefSPascal van Leeuwen .cra_blocksize = 1, 365592c60cefSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 365692c60cefSPascal van Leeuwen .cra_alignmask = 0, 365792c60cefSPascal van Leeuwen .cra_init = safexcel_rfc4543_gcm_cra_init, 365892c60cefSPascal van Leeuwen .cra_exit = safexcel_aead_gcm_cra_exit, 365992c60cefSPascal van Leeuwen }, 366092c60cefSPascal van Leeuwen }, 366192c60cefSPascal van Leeuwen }; 3662a9a89624SPascal van Leeuwen 3663a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, 3664a9a89624SPascal van Leeuwen unsigned int len) 3665a9a89624SPascal van Leeuwen { 3666a9a89624SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 3667a9a89624SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3668a9a89624SPascal van Leeuwen 3669a9a89624SPascal van Leeuwen /* First byte of the nonce = L = always 3 for RFC4309 (4 byte ctr) */ 3670a9a89624SPascal van Leeuwen *(u8 *)&ctx->nonce = EIP197_AEAD_IPSEC_COUNTER_SIZE - 1; 3671a9a89624SPascal van Leeuwen /* last 3 bytes of key are the nonce! */ 3672a9a89624SPascal van Leeuwen memcpy((u8 *)&ctx->nonce + 1, key + len - 3673a9a89624SPascal van Leeuwen EIP197_AEAD_IPSEC_CCM_NONCE_SIZE, 3674a9a89624SPascal van Leeuwen EIP197_AEAD_IPSEC_CCM_NONCE_SIZE); 3675a9a89624SPascal van Leeuwen 3676a9a89624SPascal van Leeuwen len -= EIP197_AEAD_IPSEC_CCM_NONCE_SIZE; 3677a9a89624SPascal van Leeuwen return safexcel_aead_ccm_setkey(ctfm, key, len); 3678a9a89624SPascal van Leeuwen } 3679a9a89624SPascal van Leeuwen 3680a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_setauthsize(struct crypto_aead *tfm, 3681a9a89624SPascal van Leeuwen unsigned int authsize) 3682a9a89624SPascal van Leeuwen { 3683a9a89624SPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 3684a9a89624SPascal van Leeuwen switch (authsize) { 3685a9a89624SPascal van Leeuwen case 8: 3686a9a89624SPascal van Leeuwen case 12: 3687a9a89624SPascal van Leeuwen case 16: 3688a9a89624SPascal van Leeuwen break; 3689a9a89624SPascal van Leeuwen default: 3690a9a89624SPascal van Leeuwen return -EINVAL; 3691a9a89624SPascal van Leeuwen } 3692a9a89624SPascal van Leeuwen 3693a9a89624SPascal van Leeuwen return 0; 3694a9a89624SPascal van Leeuwen } 3695a9a89624SPascal van Leeuwen 3696a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_encrypt(struct aead_request *req) 3697a9a89624SPascal van Leeuwen { 3698a9a89624SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 3699a9a89624SPascal van Leeuwen 3700a9a89624SPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 3701a9a89624SPascal van Leeuwen if (req->assoclen != 16 && req->assoclen != 20) 3702a9a89624SPascal van Leeuwen return -EINVAL; 3703a9a89624SPascal van Leeuwen 3704a9a89624SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 3705a9a89624SPascal van Leeuwen } 3706a9a89624SPascal van Leeuwen 3707a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_decrypt(struct aead_request *req) 3708a9a89624SPascal van Leeuwen { 3709a9a89624SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 3710a9a89624SPascal van Leeuwen 3711a9a89624SPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 3712a9a89624SPascal van Leeuwen if (req->assoclen != 16 && req->assoclen != 20) 3713a9a89624SPascal van Leeuwen return -EINVAL; 3714a9a89624SPascal van Leeuwen 3715a9a89624SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 3716a9a89624SPascal van Leeuwen } 3717a9a89624SPascal van Leeuwen 3718a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_cra_init(struct crypto_tfm *tfm) 3719a9a89624SPascal van Leeuwen { 3720a9a89624SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3721a9a89624SPascal van Leeuwen int ret; 3722a9a89624SPascal van Leeuwen 3723a9a89624SPascal van Leeuwen ret = safexcel_aead_ccm_cra_init(tfm); 3724a9a89624SPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 3725098e51e5SPascal van Leeuwen ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 3726a9a89624SPascal van Leeuwen return ret; 3727a9a89624SPascal van Leeuwen } 3728a9a89624SPascal van Leeuwen 3729a9a89624SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4309_ccm = { 3730a9a89624SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3731a9a89624SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, 3732a9a89624SPascal van Leeuwen .alg.aead = { 3733a9a89624SPascal van Leeuwen .setkey = safexcel_rfc4309_ccm_setkey, 3734a9a89624SPascal van Leeuwen .setauthsize = safexcel_rfc4309_ccm_setauthsize, 3735a9a89624SPascal van Leeuwen .encrypt = safexcel_rfc4309_ccm_encrypt, 3736a9a89624SPascal van Leeuwen .decrypt = safexcel_rfc4309_ccm_decrypt, 3737a9a89624SPascal van Leeuwen .ivsize = EIP197_AEAD_IPSEC_IV_SIZE, 3738a9a89624SPascal van Leeuwen .maxauthsize = AES_BLOCK_SIZE, 3739a9a89624SPascal van Leeuwen .base = { 3740a9a89624SPascal van Leeuwen .cra_name = "rfc4309(ccm(aes))", 3741a9a89624SPascal van Leeuwen .cra_driver_name = "safexcel-rfc4309-ccm-aes", 3742a9a89624SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3743a9a89624SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3744b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 3745a9a89624SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3746a9a89624SPascal van Leeuwen .cra_blocksize = 1, 3747a9a89624SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3748a9a89624SPascal van Leeuwen .cra_alignmask = 0, 3749a9a89624SPascal van Leeuwen .cra_init = safexcel_rfc4309_ccm_cra_init, 3750a9a89624SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 3751a9a89624SPascal van Leeuwen .cra_module = THIS_MODULE, 3752a9a89624SPascal van Leeuwen }, 3753a9a89624SPascal van Leeuwen }, 3754a9a89624SPascal van Leeuwen }; 3755