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; 6413a1bb93SPascal van Leeuwen __be32 ipad[SHA512_DIGEST_SIZE / sizeof(u32)]; 6513a1bb93SPascal van Leeuwen __be32 opad[SHA512_DIGEST_SIZE / sizeof(u32)]; 663e450886SPascal van Leeuwen 673e450886SPascal van Leeuwen struct crypto_cipher *hkaes; 68a6061921SPascal van Leeuwen struct crypto_aead *fback; 691b44c5a6SAntoine Ténart }; 701b44c5a6SAntoine Ténart 711eb7b403SOfer Heifetz struct safexcel_cipher_req { 72847ccfc5SOfer Heifetz enum safexcel_cipher_direction direction; 7389332590SAntoine Tenart /* Number of result descriptors associated to the request */ 7489332590SAntoine Tenart unsigned int rdescs; 751eb7b403SOfer Heifetz bool needs_inv; 7619b347b3SPascal van Leeuwen int nr_src, nr_dst; 771eb7b403SOfer Heifetz }; 781eb7b403SOfer Heifetz 79098e51e5SPascal van Leeuwen static int safexcel_skcipher_iv(struct safexcel_cipher_ctx *ctx, u8 *iv, 800e17e362SPascal van Leeuwen struct safexcel_command_desc *cdesc) 811b44c5a6SAntoine Ténart { 82098e51e5SPascal van Leeuwen if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { 83493e289cSPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 84493e289cSPascal van Leeuwen /* 32 bit nonce */ 85493e289cSPascal van Leeuwen cdesc->control_data.token[0] = ctx->nonce; 86493e289cSPascal van Leeuwen /* 64 bit IV part */ 87493e289cSPascal van Leeuwen memcpy(&cdesc->control_data.token[1], iv, 8); 88098e51e5SPascal van Leeuwen /* 32 bit counter, start at 0 or 1 (big endian!) */ 8913a1bb93SPascal van Leeuwen cdesc->control_data.token[3] = 90098e51e5SPascal van Leeuwen (__force u32)cpu_to_be32(ctx->ctrinit); 91098e51e5SPascal van Leeuwen return 4; 92a19052d4SPascal van Leeuwen } 93a19052d4SPascal van Leeuwen if (ctx->alg == SAFEXCEL_CHACHA20) { 944a593fb3SPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 954a593fb3SPascal van Leeuwen /* 96 bit nonce part */ 964a593fb3SPascal van Leeuwen memcpy(&cdesc->control_data.token[0], &iv[4], 12); 974a593fb3SPascal van Leeuwen /* 32 bit counter */ 984a593fb3SPascal van Leeuwen cdesc->control_data.token[3] = *(u32 *)iv; 99098e51e5SPascal van Leeuwen return 4; 100493e289cSPascal van Leeuwen } 101493e289cSPascal van Leeuwen 102098e51e5SPascal van Leeuwen cdesc->control_data.options |= ctx->ivmask; 103098e51e5SPascal van Leeuwen memcpy(cdesc->control_data.token, iv, ctx->blocksz); 104098e51e5SPascal van Leeuwen return ctx->blocksz / sizeof(u32); 10554f9e8faSPascal van Leeuwen } 1060e17e362SPascal van Leeuwen 1070e17e362SPascal van Leeuwen static void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 1080e17e362SPascal van Leeuwen struct safexcel_command_desc *cdesc, 109098e51e5SPascal van Leeuwen struct safexcel_token *atoken, 1100e17e362SPascal van Leeuwen u32 length) 1110e17e362SPascal van Leeuwen { 1120e17e362SPascal van Leeuwen struct safexcel_token *token; 113098e51e5SPascal van Leeuwen int ivlen; 1140e17e362SPascal van Leeuwen 115098e51e5SPascal van Leeuwen ivlen = safexcel_skcipher_iv(ctx, iv, cdesc); 116098e51e5SPascal van Leeuwen if (ivlen == 4) { 117098e51e5SPascal van Leeuwen /* No space in cdesc, instruction moves to atoken */ 118098e51e5SPascal van Leeuwen cdesc->additional_cdata_size = 1; 119098e51e5SPascal van Leeuwen token = atoken; 120098e51e5SPascal van Leeuwen } else { 121098e51e5SPascal van Leeuwen /* Everything fits in cdesc */ 122098e51e5SPascal van Leeuwen token = (struct safexcel_token *)(cdesc->control_data.token + 2); 123098e51e5SPascal van Leeuwen /* Need to pad with NOP */ 124098e51e5SPascal van Leeuwen eip197_noop_token(&token[1]); 125098e51e5SPascal van Leeuwen } 1261b44c5a6SAntoine Ténart 127098e51e5SPascal van Leeuwen token->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 128098e51e5SPascal van Leeuwen token->packet_length = length; 129098e51e5SPascal van Leeuwen token->stat = EIP197_TOKEN_STAT_LAST_PACKET | 13015f64ee0SAntoine Tenart EIP197_TOKEN_STAT_LAST_HASH; 131098e51e5SPascal van Leeuwen token->instructions = EIP197_TOKEN_INS_LAST | 132a74d850fSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_CRYPTO | 1331b44c5a6SAntoine Ténart EIP197_TOKEN_INS_TYPE_OUTPUT; 1341b44c5a6SAntoine Ténart } 1351b44c5a6SAntoine Ténart 136098e51e5SPascal van Leeuwen static void safexcel_aead_iv(struct safexcel_cipher_ctx *ctx, u8 *iv, 137098e51e5SPascal van Leeuwen struct safexcel_command_desc *cdesc) 138098e51e5SPascal van Leeuwen { 139098e51e5SPascal van Leeuwen if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD || 140098e51e5SPascal van Leeuwen ctx->aead & EIP197_AEAD_TYPE_IPSEC_ESP) { /* _ESP and _ESP_GMAC */ 141098e51e5SPascal van Leeuwen /* 32 bit nonce */ 142098e51e5SPascal van Leeuwen cdesc->control_data.token[0] = ctx->nonce; 143098e51e5SPascal van Leeuwen /* 64 bit IV part */ 144098e51e5SPascal van Leeuwen memcpy(&cdesc->control_data.token[1], iv, 8); 145098e51e5SPascal van Leeuwen /* 32 bit counter, start at 0 or 1 (big endian!) */ 146098e51e5SPascal van Leeuwen cdesc->control_data.token[3] = 147098e51e5SPascal van Leeuwen (__force u32)cpu_to_be32(ctx->ctrinit); 148098e51e5SPascal van Leeuwen return; 149098e51e5SPascal van Leeuwen } 150098e51e5SPascal van Leeuwen if (ctx->xcm == EIP197_XCM_MODE_GCM || ctx->alg == SAFEXCEL_CHACHA20) { 151098e51e5SPascal van Leeuwen /* 96 bit IV part */ 152098e51e5SPascal van Leeuwen memcpy(&cdesc->control_data.token[0], iv, 12); 153098e51e5SPascal van Leeuwen /* 32 bit counter, start at 0 or 1 (big endian!) */ 154098e51e5SPascal van Leeuwen cdesc->control_data.token[3] = 155098e51e5SPascal van Leeuwen (__force u32)cpu_to_be32(ctx->ctrinit); 156098e51e5SPascal van Leeuwen return; 157098e51e5SPascal van Leeuwen } 158098e51e5SPascal van Leeuwen /* CBC */ 159098e51e5SPascal van Leeuwen memcpy(cdesc->control_data.token, iv, ctx->blocksz); 160098e51e5SPascal van Leeuwen } 161098e51e5SPascal van Leeuwen 162f6beaea3SAntoine Tenart static void safexcel_aead_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 163f6beaea3SAntoine Tenart struct safexcel_command_desc *cdesc, 164098e51e5SPascal van Leeuwen struct safexcel_token *atoken, 165f6beaea3SAntoine Tenart enum safexcel_cipher_direction direction, 166f6beaea3SAntoine Tenart u32 cryptlen, u32 assoclen, u32 digestsize) 167f6beaea3SAntoine Tenart { 168098e51e5SPascal van Leeuwen struct safexcel_token *aadref; 169098e51e5SPascal van Leeuwen int atoksize = 2; /* Start with minimum size */ 170098e51e5SPascal van Leeuwen int assocadj = assoclen - ctx->aadskip, aadalign; 171f6beaea3SAntoine Tenart 172098e51e5SPascal van Leeuwen /* Always 4 dwords of embedded IV for AEAD modes */ 173098e51e5SPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 174f6beaea3SAntoine Tenart 175098e51e5SPascal van Leeuwen if (direction == SAFEXCEL_DECRYPT) 176d2d9e6fdSPascal van Leeuwen cryptlen -= digestsize; 177d2d9e6fdSPascal van Leeuwen 178098e51e5SPascal van Leeuwen if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM)) { 179098e51e5SPascal van Leeuwen /* Construct IV block B0 for the CBC-MAC */ 180098e51e5SPascal van Leeuwen u8 *final_iv = (u8 *)cdesc->control_data.token; 181098e51e5SPascal van Leeuwen u8 *cbcmaciv = (u8 *)&atoken[1]; 182098e51e5SPascal van Leeuwen __le32 *aadlen = (__le32 *)&atoken[5]; 18354f9e8faSPascal van Leeuwen 184098e51e5SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 185098e51e5SPascal van Leeuwen /* Length + nonce */ 186098e51e5SPascal van Leeuwen cdesc->control_data.token[0] = ctx->nonce; 187098e51e5SPascal van Leeuwen /* Fixup flags byte */ 188098e51e5SPascal van Leeuwen *(__le32 *)cbcmaciv = 189098e51e5SPascal van Leeuwen cpu_to_le32(ctx->nonce | 190098e51e5SPascal van Leeuwen ((assocadj > 0) << 6) | 191098e51e5SPascal van Leeuwen ((digestsize - 2) << 2)); 192098e51e5SPascal van Leeuwen /* 64 bit IV part */ 193098e51e5SPascal van Leeuwen memcpy(&cdesc->control_data.token[1], iv, 8); 194098e51e5SPascal van Leeuwen memcpy(cbcmaciv + 4, iv, 8); 195098e51e5SPascal van Leeuwen /* Start counter at 0 */ 196098e51e5SPascal van Leeuwen cdesc->control_data.token[3] = 0; 197098e51e5SPascal van Leeuwen /* Message length */ 198098e51e5SPascal van Leeuwen *(__be32 *)(cbcmaciv + 12) = cpu_to_be32(cryptlen); 199098e51e5SPascal van Leeuwen } else { 200098e51e5SPascal van Leeuwen /* Variable length IV part */ 201098e51e5SPascal van Leeuwen memcpy(final_iv, iv, 15 - iv[0]); 202098e51e5SPascal van Leeuwen memcpy(cbcmaciv, iv, 15 - iv[0]); 203098e51e5SPascal van Leeuwen /* Start variable length counter at 0 */ 204098e51e5SPascal van Leeuwen memset(final_iv + 15 - iv[0], 0, iv[0] + 1); 205098e51e5SPascal van Leeuwen memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1); 206098e51e5SPascal van Leeuwen /* fixup flags byte */ 207098e51e5SPascal van Leeuwen cbcmaciv[0] |= ((assocadj > 0) << 6) | 208098e51e5SPascal van Leeuwen ((digestsize - 2) << 2); 209098e51e5SPascal van Leeuwen /* insert lower 2 bytes of message length */ 210098e51e5SPascal van Leeuwen cbcmaciv[14] = cryptlen >> 8; 211098e51e5SPascal van Leeuwen cbcmaciv[15] = cryptlen & 255; 212f6beaea3SAntoine Tenart } 21354f9e8faSPascal van Leeuwen 214098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 215098e51e5SPascal van Leeuwen atoken->packet_length = AES_BLOCK_SIZE + 216098e51e5SPascal van Leeuwen ((assocadj > 0) << 1); 217098e51e5SPascal van Leeuwen atoken->stat = 0; 218098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN | 219098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH; 220098e51e5SPascal van Leeuwen 221098e51e5SPascal van Leeuwen if (likely(assocadj)) { 222098e51e5SPascal van Leeuwen *aadlen = cpu_to_le32((assocadj >> 8) | 223098e51e5SPascal van Leeuwen (assocadj & 255) << 8); 224098e51e5SPascal van Leeuwen atoken += 6; 225098e51e5SPascal van Leeuwen atoksize += 7; 226098e51e5SPascal van Leeuwen } else { 227098e51e5SPascal van Leeuwen atoken += 5; 228098e51e5SPascal van Leeuwen atoksize += 6; 229098e51e5SPascal van Leeuwen } 230098e51e5SPascal van Leeuwen 231098e51e5SPascal van Leeuwen /* Process AAD data */ 232098e51e5SPascal van Leeuwen aadref = atoken; 233098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 234098e51e5SPascal van Leeuwen atoken->packet_length = assocadj; 235098e51e5SPascal van Leeuwen atoken->stat = 0; 236098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 237098e51e5SPascal van Leeuwen atoken++; 238098e51e5SPascal van Leeuwen 239098e51e5SPascal van Leeuwen /* For CCM only, align AAD data towards hash engine */ 240098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 241098e51e5SPascal van Leeuwen aadalign = (assocadj + 2) & 15; 242098e51e5SPascal van Leeuwen atoken->packet_length = assocadj && aadalign ? 243098e51e5SPascal van Leeuwen 16 - aadalign : 244098e51e5SPascal van Leeuwen 0; 245098e51e5SPascal van Leeuwen if (likely(cryptlen)) { 246098e51e5SPascal van Leeuwen atoken->stat = 0; 247098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 248098e51e5SPascal van Leeuwen } else { 249098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 250098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_LAST | 251098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH; 252098e51e5SPascal van Leeuwen } 253098e51e5SPascal van Leeuwen } else { 254098e51e5SPascal van Leeuwen safexcel_aead_iv(ctx, iv, cdesc); 255098e51e5SPascal van Leeuwen 256098e51e5SPascal van Leeuwen /* Process AAD data */ 257098e51e5SPascal van Leeuwen aadref = atoken; 258098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 259098e51e5SPascal van Leeuwen atoken->packet_length = assocadj; 260098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 261098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_LAST | 262098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH; 263098e51e5SPascal van Leeuwen } 264098e51e5SPascal van Leeuwen atoken++; 265098e51e5SPascal van Leeuwen 266a6061921SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 26792c60cefSPascal van Leeuwen /* For ESP mode (and not GMAC), skip over the IV */ 268098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 269098e51e5SPascal van Leeuwen atoken->packet_length = EIP197_AEAD_IPSEC_IV_SIZE; 270098e51e5SPascal van Leeuwen atoken->stat = 0; 271098e51e5SPascal van Leeuwen atoken->instructions = 0; 272098e51e5SPascal van Leeuwen atoken++; 273098e51e5SPascal van Leeuwen atoksize++; 274098e51e5SPascal van Leeuwen } else if (unlikely(ctx->alg == SAFEXCEL_CHACHA20 && 275098e51e5SPascal van Leeuwen direction == SAFEXCEL_DECRYPT)) { 276098e51e5SPascal van Leeuwen /* Poly-chacha decryption needs a dummy NOP here ... */ 277098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 278098e51e5SPascal van Leeuwen atoken->packet_length = 16; /* According to Op Manual */ 279098e51e5SPascal van Leeuwen atoken->stat = 0; 280098e51e5SPascal van Leeuwen atoken->instructions = 0; 281098e51e5SPascal van Leeuwen atoken++; 282098e51e5SPascal van Leeuwen atoksize++; 283a6061921SPascal van Leeuwen } 284a6061921SPascal van Leeuwen 285098e51e5SPascal van Leeuwen if (ctx->xcm) { 286098e51e5SPascal van Leeuwen /* For GCM and CCM, obtain enc(Y0) */ 287098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES; 288098e51e5SPascal van Leeuwen atoken->packet_length = 0; 289098e51e5SPascal van Leeuwen atoken->stat = 0; 290098e51e5SPascal van Leeuwen atoken->instructions = AES_BLOCK_SIZE; 291098e51e5SPascal van Leeuwen atoken++; 292098e51e5SPascal van Leeuwen 293098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 294098e51e5SPascal van Leeuwen atoken->packet_length = AES_BLOCK_SIZE; 295098e51e5SPascal van Leeuwen atoken->stat = 0; 296098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | 297098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_CRYPTO; 298098e51e5SPascal van Leeuwen atoken++; 299098e51e5SPascal van Leeuwen atoksize += 2; 300098e51e5SPascal van Leeuwen } 30154f9e8faSPascal van Leeuwen 302a6061921SPascal van Leeuwen if (likely(cryptlen || ctx->alg == SAFEXCEL_CHACHA20)) { 303098e51e5SPascal van Leeuwen /* Fixup stat field for AAD direction instruction */ 304098e51e5SPascal van Leeuwen aadref->stat = 0; 305098e51e5SPascal van Leeuwen 306098e51e5SPascal van Leeuwen /* Process crypto data */ 307098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 308098e51e5SPascal van Leeuwen atoken->packet_length = cryptlen; 309098e51e5SPascal van Leeuwen 31092c60cefSPascal van Leeuwen if (unlikely(ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) { 311098e51e5SPascal van Leeuwen /* Fixup instruction field for AAD dir instruction */ 312098e51e5SPascal van Leeuwen aadref->instructions = EIP197_TOKEN_INS_TYPE_HASH; 313098e51e5SPascal van Leeuwen 31492c60cefSPascal van Leeuwen /* Do not send to crypt engine in case of GMAC */ 315098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_LAST | 31692c60cefSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH | 31792c60cefSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_OUTPUT; 31892c60cefSPascal van Leeuwen } else { 319098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_LAST | 32054f9e8faSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_CRYPTO | 32154f9e8faSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH | 32254f9e8faSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_OUTPUT; 32392c60cefSPascal van Leeuwen } 3243e450886SPascal van Leeuwen 3254eb76fafSPascal van Leeuwen cryptlen &= 15; 326098e51e5SPascal van Leeuwen if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM && cryptlen)) { 327098e51e5SPascal van Leeuwen atoken->stat = 0; 328098e51e5SPascal van Leeuwen /* For CCM only, pad crypto data to the hash engine */ 329098e51e5SPascal van Leeuwen atoken++; 330098e51e5SPascal van Leeuwen atoksize++; 331098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 332098e51e5SPascal van Leeuwen atoken->packet_length = 16 - cryptlen; 333098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 334098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 3354eb76fafSPascal van Leeuwen } else { 336098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 3374eb76fafSPascal van Leeuwen } 338098e51e5SPascal van Leeuwen atoken++; 339098e51e5SPascal van Leeuwen atoksize++; 3403e450886SPascal van Leeuwen } 341098e51e5SPascal van Leeuwen 342098e51e5SPascal van Leeuwen if (direction == SAFEXCEL_ENCRYPT) { 343098e51e5SPascal van Leeuwen /* Append ICV */ 344098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 345098e51e5SPascal van Leeuwen atoken->packet_length = digestsize; 346098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 347098e51e5SPascal van Leeuwen EIP197_TOKEN_STAT_LAST_PACKET; 348098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | 349098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_INSERT_HASH_DIGEST; 350098e51e5SPascal van Leeuwen } else { 351098e51e5SPascal van Leeuwen /* Extract ICV */ 352098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_RETRIEVE; 353098e51e5SPascal van Leeuwen atoken->packet_length = digestsize; 354098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 355098e51e5SPascal van Leeuwen EIP197_TOKEN_STAT_LAST_PACKET; 356098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST; 357098e51e5SPascal van Leeuwen atoken++; 358098e51e5SPascal van Leeuwen atoksize++; 359098e51e5SPascal van Leeuwen 360098e51e5SPascal van Leeuwen /* Verify ICV */ 361098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_VERIFY; 362098e51e5SPascal van Leeuwen atoken->packet_length = digestsize | 363098e51e5SPascal van Leeuwen EIP197_TOKEN_HASH_RESULT_VERIFY; 364098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 365098e51e5SPascal van Leeuwen EIP197_TOKEN_STAT_LAST_PACKET; 366098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT; 367098e51e5SPascal van Leeuwen } 368098e51e5SPascal van Leeuwen 369098e51e5SPascal van Leeuwen /* Fixup length of the token in the command descriptor */ 370098e51e5SPascal van Leeuwen cdesc->additional_cdata_size = atoksize; 371f6beaea3SAntoine Tenart } 372f6beaea3SAntoine Tenart 3738ac1283eSAntoine Tenart static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm, 3748ac1283eSAntoine Tenart const u8 *key, unsigned int len) 3751b44c5a6SAntoine Ténart { 3761b44c5a6SAntoine Ténart struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 3771b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 378871df319SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 3791b44c5a6SAntoine Ténart struct crypto_aes_ctx aes; 3801b44c5a6SAntoine Ténart int ret, i; 3811b44c5a6SAntoine Ténart 382363a90c2SArd Biesheuvel ret = aes_expandkey(&aes, key, len); 3831b44c5a6SAntoine Ténart if (ret) { 3841b44c5a6SAntoine Ténart crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 3851b44c5a6SAntoine Ténart return ret; 3861b44c5a6SAntoine Ténart } 3871b44c5a6SAntoine Ténart 38853c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 3891b44c5a6SAntoine Ténart for (i = 0; i < len / sizeof(u32); i++) { 39013a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 3911b44c5a6SAntoine Ténart ctx->base.needs_inv = true; 3921b44c5a6SAntoine Ténart break; 3931b44c5a6SAntoine Ténart } 3941b44c5a6SAntoine Ténart } 395c4daf4ccSOfer Heifetz } 3961b44c5a6SAntoine Ténart 3971b44c5a6SAntoine Ténart for (i = 0; i < len / sizeof(u32); i++) 3981b44c5a6SAntoine Ténart ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 3991b44c5a6SAntoine Ténart 4001b44c5a6SAntoine Ténart ctx->key_len = len; 4011b44c5a6SAntoine Ténart 4021b44c5a6SAntoine Ténart memzero_explicit(&aes, sizeof(aes)); 4031b44c5a6SAntoine Ténart return 0; 4041b44c5a6SAntoine Ténart } 4051b44c5a6SAntoine Ténart 40677cdd4efSPascal van Leeuwen static int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key, 407f6beaea3SAntoine Tenart unsigned int len) 408f6beaea3SAntoine Tenart { 409f6beaea3SAntoine Tenart struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 410f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 411f6beaea3SAntoine Tenart struct safexcel_ahash_export_state istate, ostate; 412f6beaea3SAntoine Tenart struct safexcel_crypto_priv *priv = ctx->priv; 413f6beaea3SAntoine Tenart struct crypto_authenc_keys keys; 4140e17e362SPascal van Leeuwen struct crypto_aes_ctx aes; 41513a1bb93SPascal van Leeuwen int err = -EINVAL, i; 416f6beaea3SAntoine Tenart 4171769f704SPascal van Leeuwen if (unlikely(crypto_authenc_extractkeys(&keys, key, len))) 418f6beaea3SAntoine Tenart goto badkey; 419f6beaea3SAntoine Tenart 4200e17e362SPascal van Leeuwen if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { 4211769f704SPascal van Leeuwen /* Must have at least space for the nonce here */ 4221769f704SPascal van Leeuwen if (unlikely(keys.enckeylen < CTR_RFC3686_NONCE_SIZE)) 423f6beaea3SAntoine Tenart goto badkey; 4240e17e362SPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 425f26882a3SPascal van Leeuwen ctx->nonce = *(u32 *)(keys.enckey + keys.enckeylen - 426f26882a3SPascal van Leeuwen CTR_RFC3686_NONCE_SIZE); 4270e17e362SPascal van Leeuwen /* exclude the nonce here */ 4281769f704SPascal van Leeuwen keys.enckeylen -= CTR_RFC3686_NONCE_SIZE; 4290e17e362SPascal van Leeuwen } 430f6beaea3SAntoine Tenart 431f6beaea3SAntoine Tenart /* Encryption key */ 4320e17e362SPascal van Leeuwen switch (ctx->alg) { 433bb7679b8SPascal van Leeuwen case SAFEXCEL_DES: 434bb7679b8SPascal van Leeuwen err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen); 435bb7679b8SPascal van Leeuwen if (unlikely(err)) 436bb7679b8SPascal van Leeuwen goto badkey_expflags; 437bb7679b8SPascal van Leeuwen break; 4380e17e362SPascal van Leeuwen case SAFEXCEL_3DES: 43921f5a15eSArd Biesheuvel err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen); 44077cdd4efSPascal van Leeuwen if (unlikely(err)) 4410e17e362SPascal van Leeuwen goto badkey_expflags; 4420e17e362SPascal van Leeuwen break; 4430e17e362SPascal van Leeuwen case SAFEXCEL_AES: 4440e17e362SPascal van Leeuwen err = aes_expandkey(&aes, keys.enckey, keys.enckeylen); 4450e17e362SPascal van Leeuwen if (unlikely(err)) 4460e17e362SPascal van Leeuwen goto badkey; 4470e17e362SPascal van Leeuwen break; 4481769f704SPascal van Leeuwen case SAFEXCEL_SM4: 4491769f704SPascal van Leeuwen if (unlikely(keys.enckeylen != SM4_KEY_SIZE)) 4501769f704SPascal van Leeuwen goto badkey; 4511769f704SPascal van Leeuwen break; 4520e17e362SPascal van Leeuwen default: 4530e17e362SPascal van Leeuwen dev_err(priv->dev, "aead: unsupported cipher algorithm\n"); 4540e17e362SPascal van Leeuwen goto badkey; 45577cdd4efSPascal van Leeuwen } 45677cdd4efSPascal van Leeuwen 45713a1bb93SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 45813a1bb93SPascal van Leeuwen for (i = 0; i < keys.enckeylen / sizeof(u32); i++) { 459b8151220SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != 460b8151220SPascal van Leeuwen ((u32 *)keys.enckey)[i]) { 461f6beaea3SAntoine Tenart ctx->base.needs_inv = true; 46213a1bb93SPascal van Leeuwen break; 46313a1bb93SPascal van Leeuwen } 46413a1bb93SPascal van Leeuwen } 46513a1bb93SPascal van Leeuwen } 466f6beaea3SAntoine Tenart 467f6beaea3SAntoine Tenart /* Auth key */ 468a7dea8c0SOfer Heifetz switch (ctx->hash_alg) { 46901ba061dSAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA1: 47001ba061dSAntoine Tenart if (safexcel_hmac_setkey("safexcel-sha1", keys.authkey, 47101ba061dSAntoine Tenart keys.authkeylen, &istate, &ostate)) 47201ba061dSAntoine Tenart goto badkey; 47301ba061dSAntoine Tenart break; 474678b2878SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA224: 475678b2878SAntoine Tenart if (safexcel_hmac_setkey("safexcel-sha224", keys.authkey, 476678b2878SAntoine Tenart keys.authkeylen, &istate, &ostate)) 477678b2878SAntoine Tenart goto badkey; 478678b2878SAntoine Tenart break; 479678b2878SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA256: 480f6beaea3SAntoine Tenart if (safexcel_hmac_setkey("safexcel-sha256", keys.authkey, 481f6beaea3SAntoine Tenart keys.authkeylen, &istate, &ostate)) 482f6beaea3SAntoine Tenart goto badkey; 483678b2878SAntoine Tenart break; 484ea23cb53SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA384: 485ea23cb53SAntoine Tenart if (safexcel_hmac_setkey("safexcel-sha384", keys.authkey, 486ea23cb53SAntoine Tenart keys.authkeylen, &istate, &ostate)) 487ea23cb53SAntoine Tenart goto badkey; 488ea23cb53SAntoine Tenart break; 48987eee125SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA512: 49087eee125SAntoine Tenart if (safexcel_hmac_setkey("safexcel-sha512", keys.authkey, 49187eee125SAntoine Tenart keys.authkeylen, &istate, &ostate)) 49287eee125SAntoine Tenart goto badkey; 49387eee125SAntoine Tenart break; 4941769f704SPascal van Leeuwen case CONTEXT_CONTROL_CRYPTO_ALG_SM3: 4951769f704SPascal van Leeuwen if (safexcel_hmac_setkey("safexcel-sm3", keys.authkey, 4961769f704SPascal van Leeuwen keys.authkeylen, &istate, &ostate)) 4971769f704SPascal van Leeuwen goto badkey; 4981769f704SPascal van Leeuwen break; 499678b2878SAntoine Tenart default: 5001a61af28SColin Ian King dev_err(priv->dev, "aead: unsupported hash algorithm\n"); 501678b2878SAntoine Tenart goto badkey; 502678b2878SAntoine Tenart } 503f6beaea3SAntoine Tenart 504f6beaea3SAntoine Tenart crypto_aead_set_flags(ctfm, crypto_aead_get_flags(ctfm) & 505f6beaea3SAntoine Tenart CRYPTO_TFM_RES_MASK); 506f6beaea3SAntoine Tenart 50753c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma && 508f6beaea3SAntoine Tenart (memcmp(ctx->ipad, istate.state, ctx->state_sz) || 509f6beaea3SAntoine Tenart memcmp(ctx->opad, ostate.state, ctx->state_sz))) 510f6beaea3SAntoine Tenart ctx->base.needs_inv = true; 511f6beaea3SAntoine Tenart 512f6beaea3SAntoine Tenart /* Now copy the keys into the context */ 51313a1bb93SPascal van Leeuwen for (i = 0; i < keys.enckeylen / sizeof(u32); i++) 514b8151220SPascal van Leeuwen ctx->key[i] = cpu_to_le32(((u32 *)keys.enckey)[i]); 515f6beaea3SAntoine Tenart ctx->key_len = keys.enckeylen; 516f6beaea3SAntoine Tenart 517f6beaea3SAntoine Tenart memcpy(ctx->ipad, &istate.state, ctx->state_sz); 518f6beaea3SAntoine Tenart memcpy(ctx->opad, &ostate.state, ctx->state_sz); 519f6beaea3SAntoine Tenart 520f6beaea3SAntoine Tenart memzero_explicit(&keys, sizeof(keys)); 521f6beaea3SAntoine Tenart return 0; 522f6beaea3SAntoine Tenart 523f6beaea3SAntoine Tenart badkey: 524f6beaea3SAntoine Tenart crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 5250e17e362SPascal van Leeuwen badkey_expflags: 526f6beaea3SAntoine Tenart memzero_explicit(&keys, sizeof(keys)); 5270e17e362SPascal van Leeuwen return err; 528f6beaea3SAntoine Tenart } 529f6beaea3SAntoine Tenart 5301b44c5a6SAntoine Ténart static int safexcel_context_control(struct safexcel_cipher_ctx *ctx, 531847ccfc5SOfer Heifetz struct crypto_async_request *async, 5328ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 5331b44c5a6SAntoine Ténart struct safexcel_command_desc *cdesc) 5341b44c5a6SAntoine Ténart { 5351b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 536d2d9e6fdSPascal van Leeuwen int ctrl_size = ctx->key_len / sizeof(u32); 537d2d9e6fdSPascal van Leeuwen 538d2d9e6fdSPascal van Leeuwen cdesc->control_data.control1 = ctx->mode; 5391b44c5a6SAntoine Ténart 540f6beaea3SAntoine Tenart if (ctx->aead) { 541d2d9e6fdSPascal van Leeuwen /* Take in account the ipad+opad digests */ 5423e450886SPascal van Leeuwen if (ctx->xcm) { 5433e450886SPascal van Leeuwen ctrl_size += ctx->state_sz / sizeof(u32); 5443e450886SPascal van Leeuwen cdesc->control_data.control0 = 5453e450886SPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 5463e450886SPascal van Leeuwen CONTEXT_CONTROL_DIGEST_XCM | 5473e450886SPascal van Leeuwen ctx->hash_alg | 5483e450886SPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 549a6061921SPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_CHACHA20) { 550a6061921SPascal van Leeuwen /* Chacha20-Poly1305 */ 551a6061921SPascal van Leeuwen cdesc->control_data.control0 = 552a6061921SPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 553a6061921SPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 | 554a6061921SPascal van Leeuwen (sreq->direction == SAFEXCEL_ENCRYPT ? 555a6061921SPascal van Leeuwen CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT : 556a6061921SPascal van Leeuwen CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN) | 557a6061921SPascal van Leeuwen ctx->hash_alg | 558a6061921SPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 559a6061921SPascal van Leeuwen return 0; 5603e450886SPascal van Leeuwen } else { 561d2d9e6fdSPascal van Leeuwen ctrl_size += ctx->state_sz / sizeof(u32) * 2; 5623e450886SPascal van Leeuwen cdesc->control_data.control0 = 5633e450886SPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 5643e450886SPascal van Leeuwen CONTEXT_CONTROL_DIGEST_HMAC | 5653e450886SPascal van Leeuwen ctx->hash_alg | 5663e450886SPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 5673e450886SPascal van Leeuwen } 5684eb76fafSPascal van Leeuwen 56992c60cefSPascal van Leeuwen if (sreq->direction == SAFEXCEL_ENCRYPT && 57092c60cefSPascal van Leeuwen (ctx->xcm == EIP197_XCM_MODE_CCM || 57192c60cefSPascal van Leeuwen ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) 57292c60cefSPascal van Leeuwen cdesc->control_data.control0 |= 57392c60cefSPascal van Leeuwen CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT; 57492c60cefSPascal van Leeuwen else if (sreq->direction == SAFEXCEL_ENCRYPT) 57592c60cefSPascal van Leeuwen cdesc->control_data.control0 |= 57692c60cefSPascal van Leeuwen CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT; 57792c60cefSPascal van Leeuwen else if (ctx->xcm == EIP197_XCM_MODE_CCM) 57892c60cefSPascal van Leeuwen cdesc->control_data.control0 |= 57992c60cefSPascal van Leeuwen CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN; 580d2d9e6fdSPascal van Leeuwen else 5813e450886SPascal van Leeuwen cdesc->control_data.control0 |= 5823e450886SPascal van Leeuwen CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN; 583d2d9e6fdSPascal van Leeuwen } else { 584d2d9e6fdSPascal van Leeuwen if (sreq->direction == SAFEXCEL_ENCRYPT) 585d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 = 586d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_TYPE_CRYPTO_OUT | 587d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 588d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 589d2d9e6fdSPascal van Leeuwen else 590d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 = 591d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_TYPE_CRYPTO_IN | 592d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 593d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 594f6beaea3SAntoine Tenart } 5951b44c5a6SAntoine Ténart 596a7dea8c0SOfer Heifetz if (ctx->alg == SAFEXCEL_DES) { 597d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 598d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_DES; 59962469879SOfer Heifetz } else if (ctx->alg == SAFEXCEL_3DES) { 600d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 601d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_3DES; 602a7dea8c0SOfer Heifetz } else if (ctx->alg == SAFEXCEL_AES) { 603c7da38a7SPascal van Leeuwen switch (ctx->key_len >> ctx->xts) { 6041b44c5a6SAntoine Ténart case AES_KEYSIZE_128: 605d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 606d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_AES128; 6071b44c5a6SAntoine Ténart break; 6081b44c5a6SAntoine Ténart case AES_KEYSIZE_192: 609d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 610d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_AES192; 6111b44c5a6SAntoine Ténart break; 6121b44c5a6SAntoine Ténart case AES_KEYSIZE_256: 613d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 614d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_AES256; 6151b44c5a6SAntoine Ténart break; 6161b44c5a6SAntoine Ténart default: 6171b44c5a6SAntoine Ténart dev_err(priv->dev, "aes keysize not supported: %u\n", 618c7da38a7SPascal van Leeuwen ctx->key_len >> ctx->xts); 6191b44c5a6SAntoine Ténart return -EINVAL; 6201b44c5a6SAntoine Ténart } 6214a593fb3SPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_CHACHA20) { 6224a593fb3SPascal van Leeuwen cdesc->control_data.control0 |= 6234a593fb3SPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20; 624fcca797dSPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_SM4) { 625fcca797dSPascal van Leeuwen cdesc->control_data.control0 |= 626fcca797dSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_SM4; 627a7dea8c0SOfer Heifetz } 628fef0cfe5SAntoine Tenart 6291b44c5a6SAntoine Ténart return 0; 6301b44c5a6SAntoine Ténart } 6311b44c5a6SAntoine Ténart 6321eb7b403SOfer Heifetz static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring, 6331b44c5a6SAntoine Ténart struct crypto_async_request *async, 6348ac1283eSAntoine Tenart struct scatterlist *src, 6358ac1283eSAntoine Tenart struct scatterlist *dst, 6368ac1283eSAntoine Tenart unsigned int cryptlen, 6378ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 6381b44c5a6SAntoine Ténart bool *should_complete, int *ret) 6391b44c5a6SAntoine Ténart { 6405bdb6e6aSPascal van Leeuwen struct skcipher_request *areq = skcipher_request_cast(async); 6415bdb6e6aSPascal van Leeuwen struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq); 6425bdb6e6aSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(skcipher); 6431b44c5a6SAntoine Ténart struct safexcel_result_desc *rdesc; 6441b44c5a6SAntoine Ténart int ndesc = 0; 6451b44c5a6SAntoine Ténart 6461b44c5a6SAntoine Ténart *ret = 0; 6471b44c5a6SAntoine Ténart 64889332590SAntoine Tenart if (unlikely(!sreq->rdescs)) 64989332590SAntoine Tenart return 0; 65089332590SAntoine Tenart 65189332590SAntoine Tenart while (sreq->rdescs--) { 6521b44c5a6SAntoine Ténart rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr); 6531b44c5a6SAntoine Ténart if (IS_ERR(rdesc)) { 6541b44c5a6SAntoine Ténart dev_err(priv->dev, 6551b44c5a6SAntoine Ténart "cipher: result: could not retrieve the result descriptor\n"); 6561b44c5a6SAntoine Ténart *ret = PTR_ERR(rdesc); 6571b44c5a6SAntoine Ténart break; 6581b44c5a6SAntoine Ténart } 6591b44c5a6SAntoine Ténart 660bdfd1909SAntoine Tenart if (likely(!*ret)) 661bdfd1909SAntoine Tenart *ret = safexcel_rdesc_check_errors(priv, rdesc); 6621b44c5a6SAntoine Ténart 6631b44c5a6SAntoine Ténart ndesc++; 66489332590SAntoine Tenart } 6651b44c5a6SAntoine Ténart 6661b44c5a6SAntoine Ténart safexcel_complete(priv, ring); 6671b44c5a6SAntoine Ténart 6688ac1283eSAntoine Tenart if (src == dst) { 66919b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL); 6701b44c5a6SAntoine Ténart } else { 67119b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 67219b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE); 6731b44c5a6SAntoine Ténart } 6741b44c5a6SAntoine Ténart 6755bdb6e6aSPascal van Leeuwen /* 6765bdb6e6aSPascal van Leeuwen * Update IV in req from last crypto output word for CBC modes 6775bdb6e6aSPascal van Leeuwen */ 6785bdb6e6aSPascal van Leeuwen if ((!ctx->aead) && (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) && 6795bdb6e6aSPascal van Leeuwen (sreq->direction == SAFEXCEL_ENCRYPT)) { 6805bdb6e6aSPascal van Leeuwen /* For encrypt take the last output word */ 68119b347b3SPascal van Leeuwen sg_pcopy_to_buffer(dst, sreq->nr_dst, areq->iv, 6825bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher), 6835bdb6e6aSPascal van Leeuwen (cryptlen - 6845bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher))); 6855bdb6e6aSPascal van Leeuwen } 6865bdb6e6aSPascal van Leeuwen 6871b44c5a6SAntoine Ténart *should_complete = true; 6881b44c5a6SAntoine Ténart 6891b44c5a6SAntoine Ténart return ndesc; 6901b44c5a6SAntoine Ténart } 6911b44c5a6SAntoine Ténart 692a7dea8c0SOfer Heifetz static int safexcel_send_req(struct crypto_async_request *base, int ring, 6938ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 6948ac1283eSAntoine Tenart struct scatterlist *src, struct scatterlist *dst, 695f6beaea3SAntoine Tenart unsigned int cryptlen, unsigned int assoclen, 696f6beaea3SAntoine Tenart unsigned int digestsize, u8 *iv, int *commands, 6978ac1283eSAntoine Tenart int *results) 6981b44c5a6SAntoine Ténart { 6995bdb6e6aSPascal van Leeuwen struct skcipher_request *areq = skcipher_request_cast(base); 7005bdb6e6aSPascal van Leeuwen struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq); 7018ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 7021b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 7031b44c5a6SAntoine Ténart struct safexcel_command_desc *cdesc; 70419b347b3SPascal van Leeuwen struct safexcel_command_desc *first_cdesc = NULL; 705e5c8ee1fSAntoine Tenart struct safexcel_result_desc *rdesc, *first_rdesc = NULL; 7061b44c5a6SAntoine Ténart struct scatterlist *sg; 70719b347b3SPascal van Leeuwen unsigned int totlen; 70819b347b3SPascal van Leeuwen unsigned int totlen_src = cryptlen + assoclen; 70919b347b3SPascal van Leeuwen unsigned int totlen_dst = totlen_src; 710098e51e5SPascal van Leeuwen struct safexcel_token *atoken; 71119b347b3SPascal van Leeuwen int n_cdesc = 0, n_rdesc = 0; 71219b347b3SPascal van Leeuwen int queued, i, ret = 0; 71319b347b3SPascal van Leeuwen bool first = true; 7141b44c5a6SAntoine Ténart 71519b347b3SPascal van Leeuwen sreq->nr_src = sg_nents_for_len(src, totlen_src); 71619b347b3SPascal van Leeuwen 71719b347b3SPascal van Leeuwen if (ctx->aead) { 71819b347b3SPascal van Leeuwen /* 71919b347b3SPascal van Leeuwen * AEAD has auth tag appended to output for encrypt and 72019b347b3SPascal van Leeuwen * removed from the output for decrypt! 72119b347b3SPascal van Leeuwen */ 72219b347b3SPascal van Leeuwen if (sreq->direction == SAFEXCEL_DECRYPT) 72319b347b3SPascal van Leeuwen totlen_dst -= digestsize; 72419b347b3SPascal van Leeuwen else 72519b347b3SPascal van Leeuwen totlen_dst += digestsize; 72619b347b3SPascal van Leeuwen 72719b347b3SPascal van Leeuwen memcpy(ctx->base.ctxr->data + ctx->key_len / sizeof(u32), 72819b347b3SPascal van Leeuwen ctx->ipad, ctx->state_sz); 7293e450886SPascal van Leeuwen if (!ctx->xcm) 7303e450886SPascal van Leeuwen memcpy(ctx->base.ctxr->data + (ctx->key_len + 7313e450886SPascal van Leeuwen ctx->state_sz) / sizeof(u32), ctx->opad, 7323e450886SPascal van Leeuwen ctx->state_sz); 73319b347b3SPascal van Leeuwen } else if ((ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) && 7345bdb6e6aSPascal van Leeuwen (sreq->direction == SAFEXCEL_DECRYPT)) { 7355bdb6e6aSPascal van Leeuwen /* 7365bdb6e6aSPascal van Leeuwen * Save IV from last crypto input word for CBC modes in decrypt 7375bdb6e6aSPascal van Leeuwen * direction. Need to do this first in case of inplace operation 7385bdb6e6aSPascal van Leeuwen * as it will be overwritten. 7395bdb6e6aSPascal van Leeuwen */ 74019b347b3SPascal van Leeuwen sg_pcopy_to_buffer(src, sreq->nr_src, areq->iv, 7415bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher), 74219b347b3SPascal van Leeuwen (totlen_src - 7435bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher))); 7445bdb6e6aSPascal van Leeuwen } 7455bdb6e6aSPascal van Leeuwen 74619b347b3SPascal van Leeuwen sreq->nr_dst = sg_nents_for_len(dst, totlen_dst); 7471b44c5a6SAntoine Ténart 74819b347b3SPascal van Leeuwen /* 74919b347b3SPascal van Leeuwen * Remember actual input length, source buffer length may be 75019b347b3SPascal van Leeuwen * updated in case of inline operation below. 75119b347b3SPascal van Leeuwen */ 75219b347b3SPascal van Leeuwen totlen = totlen_src; 75319b347b3SPascal van Leeuwen queued = totlen_src; 75419b347b3SPascal van Leeuwen 75519b347b3SPascal van Leeuwen if (src == dst) { 75619b347b3SPascal van Leeuwen sreq->nr_src = max(sreq->nr_src, sreq->nr_dst); 75719b347b3SPascal van Leeuwen sreq->nr_dst = sreq->nr_src; 75819b347b3SPascal van Leeuwen if (unlikely((totlen_src || totlen_dst) && 75919b347b3SPascal van Leeuwen (sreq->nr_src <= 0))) { 76019b347b3SPascal van Leeuwen dev_err(priv->dev, "In-place buffer not large enough (need %d bytes)!", 76119b347b3SPascal van Leeuwen max(totlen_src, totlen_dst)); 7621b44c5a6SAntoine Ténart return -EINVAL; 7631b44c5a6SAntoine Ténart } 76419b347b3SPascal van Leeuwen dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL); 76519b347b3SPascal van Leeuwen } else { 76619b347b3SPascal van Leeuwen if (unlikely(totlen_src && (sreq->nr_src <= 0))) { 76719b347b3SPascal van Leeuwen dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!", 76819b347b3SPascal van Leeuwen totlen_src); 76919b347b3SPascal van Leeuwen return -EINVAL; 77019b347b3SPascal van Leeuwen } 77119b347b3SPascal van Leeuwen dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 77219b347b3SPascal van Leeuwen 77319b347b3SPascal van Leeuwen if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) { 77419b347b3SPascal van Leeuwen dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!", 77519b347b3SPascal van Leeuwen totlen_dst); 77619b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, 77719b347b3SPascal van Leeuwen DMA_TO_DEVICE); 77819b347b3SPascal van Leeuwen return -EINVAL; 77919b347b3SPascal van Leeuwen } 78019b347b3SPascal van Leeuwen dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE); 7811b44c5a6SAntoine Ténart } 7821b44c5a6SAntoine Ténart 7831b44c5a6SAntoine Ténart memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len); 7841b44c5a6SAntoine Ténart 785cb97aa94SPascal van Leeuwen if (!totlen) { 786cb97aa94SPascal van Leeuwen /* 787cb97aa94SPascal van Leeuwen * The EIP97 cannot deal with zero length input packets! 788cb97aa94SPascal van Leeuwen * So stuff a dummy command descriptor indicating a 1 byte 789cb97aa94SPascal van Leeuwen * (dummy) input packet, using the context record as source. 790cb97aa94SPascal van Leeuwen */ 791cb97aa94SPascal van Leeuwen first_cdesc = safexcel_add_cdesc(priv, ring, 792cb97aa94SPascal van Leeuwen 1, 1, ctx->base.ctxr_dma, 793cb97aa94SPascal van Leeuwen 1, 1, ctx->base.ctxr_dma, 794cb97aa94SPascal van Leeuwen &atoken); 795cb97aa94SPascal van Leeuwen if (IS_ERR(first_cdesc)) { 796cb97aa94SPascal van Leeuwen /* No space left in the command descriptor ring */ 797cb97aa94SPascal van Leeuwen ret = PTR_ERR(first_cdesc); 798cb97aa94SPascal van Leeuwen goto cdesc_rollback; 799cb97aa94SPascal van Leeuwen } 800cb97aa94SPascal van Leeuwen n_cdesc = 1; 801cb97aa94SPascal van Leeuwen goto skip_cdesc; 802cb97aa94SPascal van Leeuwen } 803f6beaea3SAntoine Tenart 8041b44c5a6SAntoine Ténart /* command descriptors */ 80519b347b3SPascal van Leeuwen for_each_sg(src, sg, sreq->nr_src, i) { 8061b44c5a6SAntoine Ténart int len = sg_dma_len(sg); 8071b44c5a6SAntoine Ténart 8081b44c5a6SAntoine Ténart /* Do not overflow the request */ 809cb97aa94SPascal van Leeuwen if (queued < len) 8101b44c5a6SAntoine Ténart len = queued; 8111b44c5a6SAntoine Ténart 81219b347b3SPascal van Leeuwen cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc, 81319b347b3SPascal van Leeuwen !(queued - len), 814f6beaea3SAntoine Tenart sg_dma_address(sg), len, totlen, 815098e51e5SPascal van Leeuwen ctx->base.ctxr_dma, &atoken); 8161b44c5a6SAntoine Ténart if (IS_ERR(cdesc)) { 8171b44c5a6SAntoine Ténart /* No space left in the command descriptor ring */ 8181b44c5a6SAntoine Ténart ret = PTR_ERR(cdesc); 8191b44c5a6SAntoine Ténart goto cdesc_rollback; 8201b44c5a6SAntoine Ténart } 8211b44c5a6SAntoine Ténart 822cb97aa94SPascal van Leeuwen if (!n_cdesc) 82319b347b3SPascal van Leeuwen first_cdesc = cdesc; 8241b44c5a6SAntoine Ténart 825cb97aa94SPascal van Leeuwen n_cdesc++; 8261b44c5a6SAntoine Ténart queued -= len; 8271b44c5a6SAntoine Ténart if (!queued) 8281b44c5a6SAntoine Ténart break; 8291b44c5a6SAntoine Ténart } 830cb97aa94SPascal van Leeuwen skip_cdesc: 83119b347b3SPascal van Leeuwen /* Add context control words and token to first command descriptor */ 83219b347b3SPascal van Leeuwen safexcel_context_control(ctx, base, sreq, first_cdesc); 83319b347b3SPascal van Leeuwen if (ctx->aead) 834098e51e5SPascal van Leeuwen safexcel_aead_token(ctx, iv, first_cdesc, atoken, 83519b347b3SPascal van Leeuwen sreq->direction, cryptlen, 83619b347b3SPascal van Leeuwen assoclen, digestsize); 83719b347b3SPascal van Leeuwen else 838098e51e5SPascal van Leeuwen safexcel_skcipher_token(ctx, iv, first_cdesc, atoken, 83919b347b3SPascal van Leeuwen cryptlen); 84019b347b3SPascal van Leeuwen 8411b44c5a6SAntoine Ténart /* result descriptors */ 84219b347b3SPascal van Leeuwen for_each_sg(dst, sg, sreq->nr_dst, i) { 84319b347b3SPascal van Leeuwen bool last = (i == sreq->nr_dst - 1); 8441b44c5a6SAntoine Ténart u32 len = sg_dma_len(sg); 8451b44c5a6SAntoine Ténart 84619b347b3SPascal van Leeuwen /* only allow the part of the buffer we know we need */ 84719b347b3SPascal van Leeuwen if (len > totlen_dst) 84819b347b3SPascal van Leeuwen len = totlen_dst; 84919b347b3SPascal van Leeuwen if (unlikely(!len)) 85019b347b3SPascal van Leeuwen break; 85119b347b3SPascal van Leeuwen totlen_dst -= len; 85219b347b3SPascal van Leeuwen 85319b347b3SPascal van Leeuwen /* skip over AAD space in buffer - not written */ 85419b347b3SPascal van Leeuwen if (assoclen) { 85519b347b3SPascal van Leeuwen if (assoclen >= len) { 85619b347b3SPascal van Leeuwen assoclen -= len; 85719b347b3SPascal van Leeuwen continue; 85819b347b3SPascal van Leeuwen } 8591b44c5a6SAntoine Ténart rdesc = safexcel_add_rdesc(priv, ring, first, last, 86019b347b3SPascal van Leeuwen sg_dma_address(sg) + 86119b347b3SPascal van Leeuwen assoclen, 86219b347b3SPascal van Leeuwen len - assoclen); 86319b347b3SPascal van Leeuwen assoclen = 0; 86419b347b3SPascal van Leeuwen } else { 86519b347b3SPascal van Leeuwen rdesc = safexcel_add_rdesc(priv, ring, first, last, 86619b347b3SPascal van Leeuwen sg_dma_address(sg), 86719b347b3SPascal van Leeuwen len); 86819b347b3SPascal van Leeuwen } 8691b44c5a6SAntoine Ténart if (IS_ERR(rdesc)) { 8701b44c5a6SAntoine Ténart /* No space left in the result descriptor ring */ 8711b44c5a6SAntoine Ténart ret = PTR_ERR(rdesc); 8721b44c5a6SAntoine Ténart goto rdesc_rollback; 8731b44c5a6SAntoine Ténart } 87419b347b3SPascal van Leeuwen if (first) { 8759744fec9SOfer Heifetz first_rdesc = rdesc; 87619b347b3SPascal van Leeuwen first = false; 87719b347b3SPascal van Leeuwen } 8781b44c5a6SAntoine Ténart n_rdesc++; 8791b44c5a6SAntoine Ténart } 8801b44c5a6SAntoine Ténart 88119b347b3SPascal van Leeuwen if (unlikely(first)) { 88219b347b3SPascal van Leeuwen /* 88319b347b3SPascal van Leeuwen * Special case: AEAD decrypt with only AAD data. 88419b347b3SPascal van Leeuwen * In this case there is NO output data from the engine, 88519b347b3SPascal van Leeuwen * but the engine still needs a result descriptor! 88619b347b3SPascal van Leeuwen * Create a dummy one just for catching the result token. 88719b347b3SPascal van Leeuwen */ 88819b347b3SPascal van Leeuwen rdesc = safexcel_add_rdesc(priv, ring, true, true, 0, 0); 88919b347b3SPascal van Leeuwen if (IS_ERR(rdesc)) { 89019b347b3SPascal van Leeuwen /* No space left in the result descriptor ring */ 89119b347b3SPascal van Leeuwen ret = PTR_ERR(rdesc); 89219b347b3SPascal van Leeuwen goto rdesc_rollback; 89319b347b3SPascal van Leeuwen } 89419b347b3SPascal van Leeuwen first_rdesc = rdesc; 89519b347b3SPascal van Leeuwen n_rdesc = 1; 89619b347b3SPascal van Leeuwen } 89719b347b3SPascal van Leeuwen 8989744fec9SOfer Heifetz safexcel_rdr_req_set(priv, ring, first_rdesc, base); 89997858434SAntoine Ténart 9001b44c5a6SAntoine Ténart *commands = n_cdesc; 901152bdf4cSOfer Heifetz *results = n_rdesc; 9021b44c5a6SAntoine Ténart return 0; 9031b44c5a6SAntoine Ténart 9041b44c5a6SAntoine Ténart rdesc_rollback: 9051b44c5a6SAntoine Ténart for (i = 0; i < n_rdesc; i++) 9061b44c5a6SAntoine Ténart safexcel_ring_rollback_wptr(priv, &priv->ring[ring].rdr); 9071b44c5a6SAntoine Ténart cdesc_rollback: 9081b44c5a6SAntoine Ténart for (i = 0; i < n_cdesc; i++) 9091b44c5a6SAntoine Ténart safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr); 9101b44c5a6SAntoine Ténart 9118ac1283eSAntoine Tenart if (src == dst) { 91219b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL); 9131b44c5a6SAntoine Ténart } else { 91419b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 91519b347b3SPascal van Leeuwen dma_unmap_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE); 9161b44c5a6SAntoine Ténart } 9171b44c5a6SAntoine Ténart 9181b44c5a6SAntoine Ténart return ret; 9191b44c5a6SAntoine Ténart } 9201b44c5a6SAntoine Ténart 9211b44c5a6SAntoine Ténart static int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv, 9221b44c5a6SAntoine Ténart int ring, 9238ac1283eSAntoine Tenart struct crypto_async_request *base, 92489332590SAntoine Tenart struct safexcel_cipher_req *sreq, 9251b44c5a6SAntoine Ténart bool *should_complete, int *ret) 9261b44c5a6SAntoine Ténart { 9278ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 9281b44c5a6SAntoine Ténart struct safexcel_result_desc *rdesc; 9291b44c5a6SAntoine Ténart int ndesc = 0, enq_ret; 9301b44c5a6SAntoine Ténart 9311b44c5a6SAntoine Ténart *ret = 0; 9321b44c5a6SAntoine Ténart 93389332590SAntoine Tenart if (unlikely(!sreq->rdescs)) 93489332590SAntoine Tenart return 0; 93589332590SAntoine Tenart 93689332590SAntoine Tenart while (sreq->rdescs--) { 9371b44c5a6SAntoine Ténart rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr); 9381b44c5a6SAntoine Ténart if (IS_ERR(rdesc)) { 9391b44c5a6SAntoine Ténart dev_err(priv->dev, 9401b44c5a6SAntoine Ténart "cipher: invalidate: could not retrieve the result descriptor\n"); 9411b44c5a6SAntoine Ténart *ret = PTR_ERR(rdesc); 9421b44c5a6SAntoine Ténart break; 9431b44c5a6SAntoine Ténart } 9441b44c5a6SAntoine Ténart 945cda3e73aSAntoine Tenart if (likely(!*ret)) 946cda3e73aSAntoine Tenart *ret = safexcel_rdesc_check_errors(priv, rdesc); 9471b44c5a6SAntoine Ténart 9481b44c5a6SAntoine Ténart ndesc++; 94989332590SAntoine Tenart } 9501b44c5a6SAntoine Ténart 9511b44c5a6SAntoine Ténart safexcel_complete(priv, ring); 9521b44c5a6SAntoine Ténart 9531b44c5a6SAntoine Ténart if (ctx->base.exit_inv) { 9541b44c5a6SAntoine Ténart dma_pool_free(priv->context_pool, ctx->base.ctxr, 9551b44c5a6SAntoine Ténart ctx->base.ctxr_dma); 9561b44c5a6SAntoine Ténart 9571b44c5a6SAntoine Ténart *should_complete = true; 9581b44c5a6SAntoine Ténart 9591b44c5a6SAntoine Ténart return ndesc; 9601b44c5a6SAntoine Ténart } 9611b44c5a6SAntoine Ténart 96286671abbSAntoine Ténart ring = safexcel_select_ring(priv); 96386671abbSAntoine Ténart ctx->base.ring = ring; 9641b44c5a6SAntoine Ténart 96586671abbSAntoine Ténart spin_lock_bh(&priv->ring[ring].queue_lock); 9668ac1283eSAntoine Tenart enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, base); 96786671abbSAntoine Ténart spin_unlock_bh(&priv->ring[ring].queue_lock); 9681b44c5a6SAntoine Ténart 9691b44c5a6SAntoine Ténart if (enq_ret != -EINPROGRESS) 9701b44c5a6SAntoine Ténart *ret = enq_ret; 9711b44c5a6SAntoine Ténart 9728472e778SAntoine Ténart queue_work(priv->ring[ring].workqueue, 9738472e778SAntoine Ténart &priv->ring[ring].work_data.work); 97486671abbSAntoine Ténart 9751b44c5a6SAntoine Ténart *should_complete = false; 9761b44c5a6SAntoine Ténart 9771b44c5a6SAntoine Ténart return ndesc; 9781b44c5a6SAntoine Ténart } 9791b44c5a6SAntoine Ténart 9808ac1283eSAntoine Tenart static int safexcel_skcipher_handle_result(struct safexcel_crypto_priv *priv, 9818ac1283eSAntoine Tenart int ring, 9821eb7b403SOfer Heifetz struct crypto_async_request *async, 9831eb7b403SOfer Heifetz bool *should_complete, int *ret) 9841eb7b403SOfer Heifetz { 9851eb7b403SOfer Heifetz struct skcipher_request *req = skcipher_request_cast(async); 9861eb7b403SOfer Heifetz struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 9871eb7b403SOfer Heifetz int err; 9881eb7b403SOfer Heifetz 9891eb7b403SOfer Heifetz if (sreq->needs_inv) { 9901eb7b403SOfer Heifetz sreq->needs_inv = false; 99189332590SAntoine Tenart err = safexcel_handle_inv_result(priv, ring, async, sreq, 9921eb7b403SOfer Heifetz should_complete, ret); 9931eb7b403SOfer Heifetz } else { 9948ac1283eSAntoine Tenart err = safexcel_handle_req_result(priv, ring, async, req->src, 9958ac1283eSAntoine Tenart req->dst, req->cryptlen, sreq, 9961eb7b403SOfer Heifetz should_complete, ret); 9971eb7b403SOfer Heifetz } 9981eb7b403SOfer Heifetz 9991eb7b403SOfer Heifetz return err; 10001eb7b403SOfer Heifetz } 10011eb7b403SOfer Heifetz 1002f6beaea3SAntoine Tenart static int safexcel_aead_handle_result(struct safexcel_crypto_priv *priv, 1003f6beaea3SAntoine Tenart int ring, 1004f6beaea3SAntoine Tenart struct crypto_async_request *async, 1005f6beaea3SAntoine Tenart bool *should_complete, int *ret) 1006f6beaea3SAntoine Tenart { 1007f6beaea3SAntoine Tenart struct aead_request *req = aead_request_cast(async); 1008f6beaea3SAntoine Tenart struct crypto_aead *tfm = crypto_aead_reqtfm(req); 1009f6beaea3SAntoine Tenart struct safexcel_cipher_req *sreq = aead_request_ctx(req); 1010f6beaea3SAntoine Tenart int err; 1011f6beaea3SAntoine Tenart 1012f6beaea3SAntoine Tenart if (sreq->needs_inv) { 1013f6beaea3SAntoine Tenart sreq->needs_inv = false; 101489332590SAntoine Tenart err = safexcel_handle_inv_result(priv, ring, async, sreq, 1015f6beaea3SAntoine Tenart should_complete, ret); 1016f6beaea3SAntoine Tenart } else { 1017f6beaea3SAntoine Tenart err = safexcel_handle_req_result(priv, ring, async, req->src, 1018f6beaea3SAntoine Tenart req->dst, 1019f6beaea3SAntoine Tenart req->cryptlen + crypto_aead_authsize(tfm), 1020f6beaea3SAntoine Tenart sreq, should_complete, ret); 1021f6beaea3SAntoine Tenart } 1022f6beaea3SAntoine Tenart 1023f6beaea3SAntoine Tenart return err; 1024f6beaea3SAntoine Tenart } 1025f6beaea3SAntoine Tenart 10268ac1283eSAntoine Tenart static int safexcel_cipher_send_inv(struct crypto_async_request *base, 10279744fec9SOfer Heifetz int ring, int *commands, int *results) 10281b44c5a6SAntoine Ténart { 10298ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 10301b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 10311b44c5a6SAntoine Ténart int ret; 10321b44c5a6SAntoine Ténart 10339744fec9SOfer Heifetz ret = safexcel_invalidate_cache(base, priv, ctx->base.ctxr_dma, ring); 10341b44c5a6SAntoine Ténart if (unlikely(ret)) 10351b44c5a6SAntoine Ténart return ret; 10361b44c5a6SAntoine Ténart 10371b44c5a6SAntoine Ténart *commands = 1; 10381b44c5a6SAntoine Ténart *results = 1; 10391b44c5a6SAntoine Ténart 10401b44c5a6SAntoine Ténart return 0; 10411b44c5a6SAntoine Ténart } 10421b44c5a6SAntoine Ténart 10438ac1283eSAntoine Tenart static int safexcel_skcipher_send(struct crypto_async_request *async, int ring, 10441eb7b403SOfer Heifetz int *commands, int *results) 10451eb7b403SOfer Heifetz { 10461eb7b403SOfer Heifetz struct skcipher_request *req = skcipher_request_cast(async); 1047871df319SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 10481eb7b403SOfer Heifetz struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 1049871df319SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 10501eb7b403SOfer Heifetz int ret; 10511eb7b403SOfer Heifetz 105253c83e91SAntoine Tenart BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv); 1053871df319SAntoine Ténart 10545bdb6e6aSPascal van Leeuwen if (sreq->needs_inv) { 10559744fec9SOfer Heifetz ret = safexcel_cipher_send_inv(async, ring, commands, results); 10565bdb6e6aSPascal van Leeuwen } else { 10575bdb6e6aSPascal van Leeuwen struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 10585bdb6e6aSPascal van Leeuwen u8 input_iv[AES_BLOCK_SIZE]; 10595bdb6e6aSPascal van Leeuwen 10605bdb6e6aSPascal van Leeuwen /* 10615bdb6e6aSPascal van Leeuwen * Save input IV in case of CBC decrypt mode 10625bdb6e6aSPascal van Leeuwen * Will be overwritten with output IV prior to use! 10635bdb6e6aSPascal van Leeuwen */ 10645bdb6e6aSPascal van Leeuwen memcpy(input_iv, req->iv, crypto_skcipher_ivsize(skcipher)); 10655bdb6e6aSPascal van Leeuwen 10669744fec9SOfer Heifetz ret = safexcel_send_req(async, ring, sreq, req->src, 10675bdb6e6aSPascal van Leeuwen req->dst, req->cryptlen, 0, 0, input_iv, 1068f6beaea3SAntoine Tenart commands, results); 10695bdb6e6aSPascal van Leeuwen } 107089332590SAntoine Tenart 107189332590SAntoine Tenart sreq->rdescs = *results; 1072f6beaea3SAntoine Tenart return ret; 1073f6beaea3SAntoine Tenart } 1074f6beaea3SAntoine Tenart 1075f6beaea3SAntoine Tenart static int safexcel_aead_send(struct crypto_async_request *async, int ring, 10769744fec9SOfer Heifetz int *commands, int *results) 1077f6beaea3SAntoine Tenart { 1078f6beaea3SAntoine Tenart struct aead_request *req = aead_request_cast(async); 1079f6beaea3SAntoine Tenart struct crypto_aead *tfm = crypto_aead_reqtfm(req); 1080f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 1081f6beaea3SAntoine Tenart struct safexcel_cipher_req *sreq = aead_request_ctx(req); 1082f6beaea3SAntoine Tenart struct safexcel_crypto_priv *priv = ctx->priv; 1083f6beaea3SAntoine Tenart int ret; 1084f6beaea3SAntoine Tenart 108553c83e91SAntoine Tenart BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv); 1086f6beaea3SAntoine Tenart 1087f6beaea3SAntoine Tenart if (sreq->needs_inv) 10889744fec9SOfer Heifetz ret = safexcel_cipher_send_inv(async, ring, commands, results); 1089f6beaea3SAntoine Tenart else 10909744fec9SOfer Heifetz ret = safexcel_send_req(async, ring, sreq, req->src, req->dst, 10919744fec9SOfer Heifetz req->cryptlen, req->assoclen, 1092f6beaea3SAntoine Tenart crypto_aead_authsize(tfm), req->iv, 10931eb7b403SOfer Heifetz commands, results); 109489332590SAntoine Tenart sreq->rdescs = *results; 10951eb7b403SOfer Heifetz return ret; 10961eb7b403SOfer Heifetz } 10971eb7b403SOfer Heifetz 10988ac1283eSAntoine Tenart static int safexcel_cipher_exit_inv(struct crypto_tfm *tfm, 10998ac1283eSAntoine Tenart struct crypto_async_request *base, 11008ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 11018ac1283eSAntoine Tenart struct safexcel_inv_result *result) 11021b44c5a6SAntoine Ténart { 11031b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 11041b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 110586671abbSAntoine Ténart int ring = ctx->base.ring; 11061b44c5a6SAntoine Ténart 11078ac1283eSAntoine Tenart init_completion(&result->completion); 11081b44c5a6SAntoine Ténart 11098ac1283eSAntoine Tenart ctx = crypto_tfm_ctx(base->tfm); 11101b44c5a6SAntoine Ténart ctx->base.exit_inv = true; 11111eb7b403SOfer Heifetz sreq->needs_inv = true; 11121b44c5a6SAntoine Ténart 111386671abbSAntoine Ténart spin_lock_bh(&priv->ring[ring].queue_lock); 11148ac1283eSAntoine Tenart crypto_enqueue_request(&priv->ring[ring].queue, base); 111586671abbSAntoine Ténart spin_unlock_bh(&priv->ring[ring].queue_lock); 11161b44c5a6SAntoine Ténart 11178472e778SAntoine Ténart queue_work(priv->ring[ring].workqueue, 11188472e778SAntoine Ténart &priv->ring[ring].work_data.work); 11191b44c5a6SAntoine Ténart 11208ac1283eSAntoine Tenart wait_for_completion(&result->completion); 11211b44c5a6SAntoine Ténart 11228ac1283eSAntoine Tenart if (result->error) { 11231b44c5a6SAntoine Ténart dev_warn(priv->dev, 11241b44c5a6SAntoine Ténart "cipher: sync: invalidate: completion error %d\n", 11258ac1283eSAntoine Tenart result->error); 11268ac1283eSAntoine Tenart return result->error; 11271b44c5a6SAntoine Ténart } 11281b44c5a6SAntoine Ténart 11291b44c5a6SAntoine Ténart return 0; 11301b44c5a6SAntoine Ténart } 11311b44c5a6SAntoine Ténart 11328ac1283eSAntoine Tenart static int safexcel_skcipher_exit_inv(struct crypto_tfm *tfm) 11338ac1283eSAntoine Tenart { 11348ac1283eSAntoine Tenart EIP197_REQUEST_ON_STACK(req, skcipher, EIP197_SKCIPHER_REQ_SIZE); 11358ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 11368ac1283eSAntoine Tenart struct safexcel_inv_result result = {}; 11378ac1283eSAntoine Tenart 11388ac1283eSAntoine Tenart memset(req, 0, sizeof(struct skcipher_request)); 11398ac1283eSAntoine Tenart 11408ac1283eSAntoine Tenart skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 11418ac1283eSAntoine Tenart safexcel_inv_complete, &result); 11428ac1283eSAntoine Tenart skcipher_request_set_tfm(req, __crypto_skcipher_cast(tfm)); 11438ac1283eSAntoine Tenart 11448ac1283eSAntoine Tenart return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result); 11458ac1283eSAntoine Tenart } 11468ac1283eSAntoine Tenart 1147f6beaea3SAntoine Tenart static int safexcel_aead_exit_inv(struct crypto_tfm *tfm) 1148f6beaea3SAntoine Tenart { 1149f6beaea3SAntoine Tenart EIP197_REQUEST_ON_STACK(req, aead, EIP197_AEAD_REQ_SIZE); 1150f6beaea3SAntoine Tenart struct safexcel_cipher_req *sreq = aead_request_ctx(req); 1151f6beaea3SAntoine Tenart struct safexcel_inv_result result = {}; 1152f6beaea3SAntoine Tenart 1153f6beaea3SAntoine Tenart memset(req, 0, sizeof(struct aead_request)); 1154f6beaea3SAntoine Tenart 1155f6beaea3SAntoine Tenart aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 1156f6beaea3SAntoine Tenart safexcel_inv_complete, &result); 1157f6beaea3SAntoine Tenart aead_request_set_tfm(req, __crypto_aead_cast(tfm)); 1158f6beaea3SAntoine Tenart 1159f6beaea3SAntoine Tenart return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result); 1160f6beaea3SAntoine Tenart } 1161f6beaea3SAntoine Tenart 1162a7dea8c0SOfer Heifetz static int safexcel_queue_req(struct crypto_async_request *base, 11638ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 116493369b5dSPascal van Leeuwen enum safexcel_cipher_direction dir) 11651b44c5a6SAntoine Ténart { 11668ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 11671b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 116886671abbSAntoine Ténart int ret, ring; 11691b44c5a6SAntoine Ténart 11701eb7b403SOfer Heifetz sreq->needs_inv = false; 1171847ccfc5SOfer Heifetz sreq->direction = dir; 11721b44c5a6SAntoine Ténart 11731b44c5a6SAntoine Ténart if (ctx->base.ctxr) { 117453c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE && ctx->base.needs_inv) { 11751eb7b403SOfer Heifetz sreq->needs_inv = true; 11761eb7b403SOfer Heifetz ctx->base.needs_inv = false; 11771eb7b403SOfer Heifetz } 11781b44c5a6SAntoine Ténart } else { 11791b44c5a6SAntoine Ténart ctx->base.ring = safexcel_select_ring(priv); 11801b44c5a6SAntoine Ténart ctx->base.ctxr = dma_pool_zalloc(priv->context_pool, 11818ac1283eSAntoine Tenart EIP197_GFP_FLAGS(*base), 11821b44c5a6SAntoine Ténart &ctx->base.ctxr_dma); 11831b44c5a6SAntoine Ténart if (!ctx->base.ctxr) 11841b44c5a6SAntoine Ténart return -ENOMEM; 11851b44c5a6SAntoine Ténart } 11861b44c5a6SAntoine Ténart 118786671abbSAntoine Ténart ring = ctx->base.ring; 11881b44c5a6SAntoine Ténart 118986671abbSAntoine Ténart spin_lock_bh(&priv->ring[ring].queue_lock); 11908ac1283eSAntoine Tenart ret = crypto_enqueue_request(&priv->ring[ring].queue, base); 119186671abbSAntoine Ténart spin_unlock_bh(&priv->ring[ring].queue_lock); 119286671abbSAntoine Ténart 11938472e778SAntoine Ténart queue_work(priv->ring[ring].workqueue, 11948472e778SAntoine Ténart &priv->ring[ring].work_data.work); 11951b44c5a6SAntoine Ténart 11961b44c5a6SAntoine Ténart return ret; 11971b44c5a6SAntoine Ténart } 11981b44c5a6SAntoine Ténart 119993369b5dSPascal van Leeuwen static int safexcel_encrypt(struct skcipher_request *req) 12001b44c5a6SAntoine Ténart { 1201a7dea8c0SOfer Heifetz return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 120293369b5dSPascal van Leeuwen SAFEXCEL_ENCRYPT); 12031b44c5a6SAntoine Ténart } 12041b44c5a6SAntoine Ténart 120593369b5dSPascal van Leeuwen static int safexcel_decrypt(struct skcipher_request *req) 12061b44c5a6SAntoine Ténart { 1207a7dea8c0SOfer Heifetz return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 120893369b5dSPascal van Leeuwen SAFEXCEL_DECRYPT); 12091b44c5a6SAntoine Ténart } 12101b44c5a6SAntoine Ténart 12111b44c5a6SAntoine Ténart static int safexcel_skcipher_cra_init(struct crypto_tfm *tfm) 12121b44c5a6SAntoine Ténart { 12131b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 12141b44c5a6SAntoine Ténart struct safexcel_alg_template *tmpl = 12151b44c5a6SAntoine Ténart container_of(tfm->__crt_alg, struct safexcel_alg_template, 12161b44c5a6SAntoine Ténart alg.skcipher.base); 12171b44c5a6SAntoine Ténart 12181eb7b403SOfer Heifetz crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), 12191eb7b403SOfer Heifetz sizeof(struct safexcel_cipher_req)); 12201b44c5a6SAntoine Ténart 12218ac1283eSAntoine Tenart ctx->priv = tmpl->priv; 12228ac1283eSAntoine Tenart 12238ac1283eSAntoine Tenart ctx->base.send = safexcel_skcipher_send; 12248ac1283eSAntoine Tenart ctx->base.handle_result = safexcel_skcipher_handle_result; 1225098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD; 1226098e51e5SPascal van Leeuwen ctx->ctrinit = 1; 12278ac1283eSAntoine Tenart return 0; 12288ac1283eSAntoine Tenart } 12298ac1283eSAntoine Tenart 12308ac1283eSAntoine Tenart static int safexcel_cipher_cra_exit(struct crypto_tfm *tfm) 12318ac1283eSAntoine Tenart { 12328ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 12338ac1283eSAntoine Tenart 1234ce679559SAntoine Tenart memzero_explicit(ctx->key, sizeof(ctx->key)); 12358ac1283eSAntoine Tenart 12368ac1283eSAntoine Tenart /* context not allocated, skip invalidation */ 12378ac1283eSAntoine Tenart if (!ctx->base.ctxr) 12388ac1283eSAntoine Tenart return -ENOMEM; 12398ac1283eSAntoine Tenart 1240ce679559SAntoine Tenart memzero_explicit(ctx->base.ctxr->data, sizeof(ctx->base.ctxr->data)); 12411b44c5a6SAntoine Ténart return 0; 12421b44c5a6SAntoine Ténart } 12431b44c5a6SAntoine Ténart 12441b44c5a6SAntoine Ténart static void safexcel_skcipher_cra_exit(struct crypto_tfm *tfm) 12451b44c5a6SAntoine Ténart { 12461b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 12471b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv = ctx->priv; 12481b44c5a6SAntoine Ténart int ret; 12491b44c5a6SAntoine Ténart 12508ac1283eSAntoine Tenart if (safexcel_cipher_cra_exit(tfm)) 12511b44c5a6SAntoine Ténart return; 12521b44c5a6SAntoine Ténart 125353c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE) { 12548ac1283eSAntoine Tenart ret = safexcel_skcipher_exit_inv(tfm); 12551b44c5a6SAntoine Ténart if (ret) 12568ac1283eSAntoine Tenart dev_warn(priv->dev, "skcipher: invalidation error %d\n", 12578ac1283eSAntoine Tenart ret); 1258871df319SAntoine Ténart } else { 1259871df319SAntoine Ténart dma_pool_free(priv->context_pool, ctx->base.ctxr, 1260871df319SAntoine Ténart ctx->base.ctxr_dma); 1261871df319SAntoine Ténart } 12621b44c5a6SAntoine Ténart } 12631b44c5a6SAntoine Ténart 1264f6beaea3SAntoine Tenart static void safexcel_aead_cra_exit(struct crypto_tfm *tfm) 1265f6beaea3SAntoine Tenart { 1266f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1267f6beaea3SAntoine Tenart struct safexcel_crypto_priv *priv = ctx->priv; 1268f6beaea3SAntoine Tenart int ret; 1269f6beaea3SAntoine Tenart 1270f6beaea3SAntoine Tenart if (safexcel_cipher_cra_exit(tfm)) 1271f6beaea3SAntoine Tenart return; 1272f6beaea3SAntoine Tenart 127353c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE) { 1274f6beaea3SAntoine Tenart ret = safexcel_aead_exit_inv(tfm); 1275f6beaea3SAntoine Tenart if (ret) 1276f6beaea3SAntoine Tenart dev_warn(priv->dev, "aead: invalidation error %d\n", 1277f6beaea3SAntoine Tenart ret); 1278f6beaea3SAntoine Tenart } else { 1279f6beaea3SAntoine Tenart dma_pool_free(priv->context_pool, ctx->base.ctxr, 1280f6beaea3SAntoine Tenart ctx->base.ctxr_dma); 1281f6beaea3SAntoine Tenart } 1282f6beaea3SAntoine Tenart } 1283f6beaea3SAntoine Tenart 128493369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_ecb_cra_init(struct crypto_tfm *tfm) 128593369b5dSPascal van Leeuwen { 128693369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 128793369b5dSPascal van Leeuwen 128893369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 128993369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 129093369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 1291098e51e5SPascal van Leeuwen ctx->blocksz = 0; 1292098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 129393369b5dSPascal van Leeuwen return 0; 129493369b5dSPascal van Leeuwen } 129593369b5dSPascal van Leeuwen 12961b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_ecb_aes = { 12971b44c5a6SAntoine Ténart .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1298062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES, 12991b44c5a6SAntoine Ténart .alg.skcipher = { 13008ac1283eSAntoine Tenart .setkey = safexcel_skcipher_aes_setkey, 130193369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 130293369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 13031b44c5a6SAntoine Ténart .min_keysize = AES_MIN_KEY_SIZE, 13041b44c5a6SAntoine Ténart .max_keysize = AES_MAX_KEY_SIZE, 13051b44c5a6SAntoine Ténart .base = { 13061b44c5a6SAntoine Ténart .cra_name = "ecb(aes)", 13071b44c5a6SAntoine Ténart .cra_driver_name = "safexcel-ecb-aes", 1308aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 13092c95e6d9SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 13101b44c5a6SAntoine Ténart CRYPTO_ALG_KERN_DRIVER_ONLY, 13111b44c5a6SAntoine Ténart .cra_blocksize = AES_BLOCK_SIZE, 13121b44c5a6SAntoine Ténart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 13131b44c5a6SAntoine Ténart .cra_alignmask = 0, 131493369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_ecb_cra_init, 13151b44c5a6SAntoine Ténart .cra_exit = safexcel_skcipher_cra_exit, 13161b44c5a6SAntoine Ténart .cra_module = THIS_MODULE, 13171b44c5a6SAntoine Ténart }, 13181b44c5a6SAntoine Ténart }, 13191b44c5a6SAntoine Ténart }; 13201b44c5a6SAntoine Ténart 132193369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_cbc_cra_init(struct crypto_tfm *tfm) 13221b44c5a6SAntoine Ténart { 132393369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 13241b44c5a6SAntoine Ténart 132593369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 132693369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 1327098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 132893369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 132993369b5dSPascal van Leeuwen return 0; 13301b44c5a6SAntoine Ténart } 13311b44c5a6SAntoine Ténart 13321b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_cbc_aes = { 13331b44c5a6SAntoine Ténart .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1334062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES, 13351b44c5a6SAntoine Ténart .alg.skcipher = { 13368ac1283eSAntoine Tenart .setkey = safexcel_skcipher_aes_setkey, 133793369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 133893369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 13391b44c5a6SAntoine Ténart .min_keysize = AES_MIN_KEY_SIZE, 13401b44c5a6SAntoine Ténart .max_keysize = AES_MAX_KEY_SIZE, 13411b44c5a6SAntoine Ténart .ivsize = AES_BLOCK_SIZE, 13421b44c5a6SAntoine Ténart .base = { 13431b44c5a6SAntoine Ténart .cra_name = "cbc(aes)", 13441b44c5a6SAntoine Ténart .cra_driver_name = "safexcel-cbc-aes", 1345aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 13462c95e6d9SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 13471b44c5a6SAntoine Ténart CRYPTO_ALG_KERN_DRIVER_ONLY, 13481b44c5a6SAntoine Ténart .cra_blocksize = AES_BLOCK_SIZE, 13491b44c5a6SAntoine Ténart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 13501b44c5a6SAntoine Ténart .cra_alignmask = 0, 135193369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_cbc_cra_init, 13521b44c5a6SAntoine Ténart .cra_exit = safexcel_skcipher_cra_exit, 13531b44c5a6SAntoine Ténart .cra_module = THIS_MODULE, 13541b44c5a6SAntoine Ténart }, 13551b44c5a6SAntoine Ténart }, 13561b44c5a6SAntoine Ténart }; 1357f6beaea3SAntoine Tenart 135848e97afaSPascal van Leeuwen static int safexcel_skcipher_aes_cfb_cra_init(struct crypto_tfm *tfm) 135948e97afaSPascal van Leeuwen { 136048e97afaSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 136148e97afaSPascal van Leeuwen 136248e97afaSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 136348e97afaSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 1364098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 136548e97afaSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; 136648e97afaSPascal van Leeuwen return 0; 136748e97afaSPascal van Leeuwen } 136848e97afaSPascal van Leeuwen 136948e97afaSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cfb_aes = { 137048e97afaSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 137148e97afaSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB, 137248e97afaSPascal van Leeuwen .alg.skcipher = { 137348e97afaSPascal van Leeuwen .setkey = safexcel_skcipher_aes_setkey, 137448e97afaSPascal van Leeuwen .encrypt = safexcel_encrypt, 137548e97afaSPascal van Leeuwen .decrypt = safexcel_decrypt, 137648e97afaSPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE, 137748e97afaSPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE, 137848e97afaSPascal van Leeuwen .ivsize = AES_BLOCK_SIZE, 137948e97afaSPascal van Leeuwen .base = { 138048e97afaSPascal van Leeuwen .cra_name = "cfb(aes)", 138148e97afaSPascal van Leeuwen .cra_driver_name = "safexcel-cfb-aes", 138248e97afaSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 138348e97afaSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 138448e97afaSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 138548e97afaSPascal van Leeuwen .cra_blocksize = 1, 138648e97afaSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 138748e97afaSPascal van Leeuwen .cra_alignmask = 0, 138848e97afaSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_cfb_cra_init, 138948e97afaSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 139048e97afaSPascal van Leeuwen .cra_module = THIS_MODULE, 139148e97afaSPascal van Leeuwen }, 139248e97afaSPascal van Leeuwen }, 139348e97afaSPascal van Leeuwen }; 139448e97afaSPascal van Leeuwen 139550485dfbSPascal van Leeuwen static int safexcel_skcipher_aes_ofb_cra_init(struct crypto_tfm *tfm) 139650485dfbSPascal van Leeuwen { 139750485dfbSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 139850485dfbSPascal van Leeuwen 139950485dfbSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 140050485dfbSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 1401098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 140250485dfbSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; 140350485dfbSPascal van Leeuwen return 0; 140450485dfbSPascal van Leeuwen } 140550485dfbSPascal van Leeuwen 140650485dfbSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ofb_aes = { 140750485dfbSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 140850485dfbSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB, 140950485dfbSPascal van Leeuwen .alg.skcipher = { 141050485dfbSPascal van Leeuwen .setkey = safexcel_skcipher_aes_setkey, 141150485dfbSPascal van Leeuwen .encrypt = safexcel_encrypt, 141250485dfbSPascal van Leeuwen .decrypt = safexcel_decrypt, 141350485dfbSPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE, 141450485dfbSPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE, 141550485dfbSPascal van Leeuwen .ivsize = AES_BLOCK_SIZE, 141650485dfbSPascal van Leeuwen .base = { 141750485dfbSPascal van Leeuwen .cra_name = "ofb(aes)", 141850485dfbSPascal van Leeuwen .cra_driver_name = "safexcel-ofb-aes", 141950485dfbSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 142050485dfbSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 142150485dfbSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 142250485dfbSPascal van Leeuwen .cra_blocksize = 1, 142350485dfbSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 142450485dfbSPascal van Leeuwen .cra_alignmask = 0, 142550485dfbSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_ofb_cra_init, 142650485dfbSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 142750485dfbSPascal van Leeuwen .cra_module = THIS_MODULE, 142850485dfbSPascal van Leeuwen }, 142950485dfbSPascal van Leeuwen }, 143050485dfbSPascal van Leeuwen }; 143150485dfbSPascal van Leeuwen 143254f9e8faSPascal van Leeuwen static int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm, 143354f9e8faSPascal van Leeuwen const u8 *key, unsigned int len) 143454f9e8faSPascal van Leeuwen { 143554f9e8faSPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 143654f9e8faSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 143754f9e8faSPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 143854f9e8faSPascal van Leeuwen struct crypto_aes_ctx aes; 143954f9e8faSPascal van Leeuwen int ret, i; 144054f9e8faSPascal van Leeuwen unsigned int keylen; 144154f9e8faSPascal van Leeuwen 144254f9e8faSPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 1443f26882a3SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 144454f9e8faSPascal van Leeuwen /* exclude the nonce here */ 1445f26882a3SPascal van Leeuwen keylen = len - CTR_RFC3686_NONCE_SIZE; 144654f9e8faSPascal van Leeuwen ret = aes_expandkey(&aes, key, keylen); 144754f9e8faSPascal van Leeuwen if (ret) { 144854f9e8faSPascal van Leeuwen crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 144954f9e8faSPascal van Leeuwen return ret; 145054f9e8faSPascal van Leeuwen } 145154f9e8faSPascal van Leeuwen 145254f9e8faSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 145354f9e8faSPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) { 145413a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 145554f9e8faSPascal van Leeuwen ctx->base.needs_inv = true; 145654f9e8faSPascal van Leeuwen break; 145754f9e8faSPascal van Leeuwen } 145854f9e8faSPascal van Leeuwen } 145954f9e8faSPascal van Leeuwen } 146054f9e8faSPascal van Leeuwen 146154f9e8faSPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) 146254f9e8faSPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 146354f9e8faSPascal van Leeuwen 146454f9e8faSPascal van Leeuwen ctx->key_len = keylen; 146554f9e8faSPascal van Leeuwen 146654f9e8faSPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 146754f9e8faSPascal van Leeuwen return 0; 146854f9e8faSPascal van Leeuwen } 146954f9e8faSPascal van Leeuwen 147093369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_ctr_cra_init(struct crypto_tfm *tfm) 147193369b5dSPascal van Leeuwen { 147293369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 147393369b5dSPascal van Leeuwen 147493369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 147593369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 1476098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 147793369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 147893369b5dSPascal van Leeuwen return 0; 147993369b5dSPascal van Leeuwen } 148093369b5dSPascal van Leeuwen 148154f9e8faSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ctr_aes = { 148254f9e8faSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1483062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES, 148454f9e8faSPascal van Leeuwen .alg.skcipher = { 148554f9e8faSPascal van Leeuwen .setkey = safexcel_skcipher_aesctr_setkey, 148693369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 148793369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 1488f26882a3SPascal van Leeuwen /* Add nonce size */ 1489f26882a3SPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 1490f26882a3SPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 1491f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 149254f9e8faSPascal van Leeuwen .base = { 149354f9e8faSPascal van Leeuwen .cra_name = "rfc3686(ctr(aes))", 149454f9e8faSPascal van Leeuwen .cra_driver_name = "safexcel-ctr-aes", 1495aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 149654f9e8faSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 149754f9e8faSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 149854f9e8faSPascal van Leeuwen .cra_blocksize = 1, 149954f9e8faSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 150054f9e8faSPascal van Leeuwen .cra_alignmask = 0, 150193369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_ctr_cra_init, 150254f9e8faSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 150354f9e8faSPascal van Leeuwen .cra_module = THIS_MODULE, 150454f9e8faSPascal van Leeuwen }, 150554f9e8faSPascal van Leeuwen }, 150654f9e8faSPascal van Leeuwen }; 150754f9e8faSPascal van Leeuwen 1508a7dea8c0SOfer Heifetz static int safexcel_des_setkey(struct crypto_skcipher *ctfm, const u8 *key, 1509a7dea8c0SOfer Heifetz unsigned int len) 1510a7dea8c0SOfer Heifetz { 151121f5a15eSArd Biesheuvel struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 1512177e358cSPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 1513a7dea8c0SOfer Heifetz int ret; 1514a7dea8c0SOfer Heifetz 151521f5a15eSArd Biesheuvel ret = verify_skcipher_des_key(ctfm, key); 151621f5a15eSArd Biesheuvel if (ret) 151721f5a15eSArd Biesheuvel return ret; 1518a7dea8c0SOfer Heifetz 1519a7dea8c0SOfer Heifetz /* if context exits and key changed, need to invalidate it */ 1520177e358cSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 1521a7dea8c0SOfer Heifetz if (memcmp(ctx->key, key, len)) 1522a7dea8c0SOfer Heifetz ctx->base.needs_inv = true; 1523a7dea8c0SOfer Heifetz 1524a7dea8c0SOfer Heifetz memcpy(ctx->key, key, len); 1525a7dea8c0SOfer Heifetz ctx->key_len = len; 1526a7dea8c0SOfer Heifetz 1527a7dea8c0SOfer Heifetz return 0; 1528a7dea8c0SOfer Heifetz } 1529a7dea8c0SOfer Heifetz 153093369b5dSPascal van Leeuwen static int safexcel_skcipher_des_cbc_cra_init(struct crypto_tfm *tfm) 153193369b5dSPascal van Leeuwen { 153293369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 153393369b5dSPascal van Leeuwen 153493369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 153593369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; 1536098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 1537098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 153893369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 153993369b5dSPascal van Leeuwen return 0; 154093369b5dSPascal van Leeuwen } 154193369b5dSPascal van Leeuwen 1542a7dea8c0SOfer Heifetz struct safexcel_alg_template safexcel_alg_cbc_des = { 1543a7dea8c0SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1544062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 1545a7dea8c0SOfer Heifetz .alg.skcipher = { 1546a7dea8c0SOfer Heifetz .setkey = safexcel_des_setkey, 154793369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 154893369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 1549a7dea8c0SOfer Heifetz .min_keysize = DES_KEY_SIZE, 1550a7dea8c0SOfer Heifetz .max_keysize = DES_KEY_SIZE, 1551a7dea8c0SOfer Heifetz .ivsize = DES_BLOCK_SIZE, 1552a7dea8c0SOfer Heifetz .base = { 1553a7dea8c0SOfer Heifetz .cra_name = "cbc(des)", 1554a7dea8c0SOfer Heifetz .cra_driver_name = "safexcel-cbc-des", 1555aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 15562b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1557a7dea8c0SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 1558a7dea8c0SOfer Heifetz .cra_blocksize = DES_BLOCK_SIZE, 1559a7dea8c0SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1560a7dea8c0SOfer Heifetz .cra_alignmask = 0, 156193369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des_cbc_cra_init, 1562a7dea8c0SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 1563a7dea8c0SOfer Heifetz .cra_module = THIS_MODULE, 1564a7dea8c0SOfer Heifetz }, 1565a7dea8c0SOfer Heifetz }, 1566a7dea8c0SOfer Heifetz }; 1567a7dea8c0SOfer Heifetz 156893369b5dSPascal van Leeuwen static int safexcel_skcipher_des_ecb_cra_init(struct crypto_tfm *tfm) 1569a7dea8c0SOfer Heifetz { 157093369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1571a7dea8c0SOfer Heifetz 157293369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 157393369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; 157493369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 1575098e51e5SPascal van Leeuwen ctx->blocksz = 0; 1576098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 157793369b5dSPascal van Leeuwen return 0; 1578a7dea8c0SOfer Heifetz } 1579a7dea8c0SOfer Heifetz 1580a7dea8c0SOfer Heifetz struct safexcel_alg_template safexcel_alg_ecb_des = { 1581a7dea8c0SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1582062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 1583a7dea8c0SOfer Heifetz .alg.skcipher = { 1584a7dea8c0SOfer Heifetz .setkey = safexcel_des_setkey, 158593369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 158693369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 1587a7dea8c0SOfer Heifetz .min_keysize = DES_KEY_SIZE, 1588a7dea8c0SOfer Heifetz .max_keysize = DES_KEY_SIZE, 1589a7dea8c0SOfer Heifetz .base = { 1590a7dea8c0SOfer Heifetz .cra_name = "ecb(des)", 1591a7dea8c0SOfer Heifetz .cra_driver_name = "safexcel-ecb-des", 1592aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 15932b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1594a7dea8c0SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 1595a7dea8c0SOfer Heifetz .cra_blocksize = DES_BLOCK_SIZE, 1596a7dea8c0SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1597a7dea8c0SOfer Heifetz .cra_alignmask = 0, 159893369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des_ecb_cra_init, 1599a7dea8c0SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 1600a7dea8c0SOfer Heifetz .cra_module = THIS_MODULE, 1601a7dea8c0SOfer Heifetz }, 1602a7dea8c0SOfer Heifetz }, 1603a7dea8c0SOfer Heifetz }; 160462469879SOfer Heifetz 160562469879SOfer Heifetz static int safexcel_des3_ede_setkey(struct crypto_skcipher *ctfm, 160662469879SOfer Heifetz const u8 *key, unsigned int len) 160762469879SOfer Heifetz { 160867ac62bfSHerbert Xu struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 1609177e358cSPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 161067ac62bfSHerbert Xu int err; 161162469879SOfer Heifetz 161221f5a15eSArd Biesheuvel err = verify_skcipher_des3_key(ctfm, key); 161321f5a15eSArd Biesheuvel if (err) 161467ac62bfSHerbert Xu return err; 161562469879SOfer Heifetz 161662469879SOfer Heifetz /* if context exits and key changed, need to invalidate it */ 1617177e358cSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 161862469879SOfer Heifetz if (memcmp(ctx->key, key, len)) 161962469879SOfer Heifetz ctx->base.needs_inv = true; 162062469879SOfer Heifetz 162162469879SOfer Heifetz memcpy(ctx->key, key, len); 162262469879SOfer Heifetz ctx->key_len = len; 162362469879SOfer Heifetz 162462469879SOfer Heifetz return 0; 162562469879SOfer Heifetz } 162662469879SOfer Heifetz 162793369b5dSPascal van Leeuwen static int safexcel_skcipher_des3_cbc_cra_init(struct crypto_tfm *tfm) 162893369b5dSPascal van Leeuwen { 162993369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 163093369b5dSPascal van Leeuwen 163193369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 163293369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; 1633098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 1634098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 163593369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 163693369b5dSPascal van Leeuwen return 0; 163793369b5dSPascal van Leeuwen } 163893369b5dSPascal van Leeuwen 163962469879SOfer Heifetz struct safexcel_alg_template safexcel_alg_cbc_des3_ede = { 164062469879SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1641062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 164262469879SOfer Heifetz .alg.skcipher = { 164362469879SOfer Heifetz .setkey = safexcel_des3_ede_setkey, 164493369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 164593369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 164662469879SOfer Heifetz .min_keysize = DES3_EDE_KEY_SIZE, 164762469879SOfer Heifetz .max_keysize = DES3_EDE_KEY_SIZE, 164862469879SOfer Heifetz .ivsize = DES3_EDE_BLOCK_SIZE, 164962469879SOfer Heifetz .base = { 165062469879SOfer Heifetz .cra_name = "cbc(des3_ede)", 165162469879SOfer Heifetz .cra_driver_name = "safexcel-cbc-des3_ede", 1652aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 16532b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 165462469879SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 165562469879SOfer Heifetz .cra_blocksize = DES3_EDE_BLOCK_SIZE, 165662469879SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 165762469879SOfer Heifetz .cra_alignmask = 0, 165893369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des3_cbc_cra_init, 165962469879SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 166062469879SOfer Heifetz .cra_module = THIS_MODULE, 166162469879SOfer Heifetz }, 166262469879SOfer Heifetz }, 166362469879SOfer Heifetz }; 166462469879SOfer Heifetz 166593369b5dSPascal van Leeuwen static int safexcel_skcipher_des3_ecb_cra_init(struct crypto_tfm *tfm) 166662469879SOfer Heifetz { 166793369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 166862469879SOfer Heifetz 166993369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 167093369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; 167193369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 1672098e51e5SPascal van Leeuwen ctx->blocksz = 0; 1673098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 167493369b5dSPascal van Leeuwen return 0; 167562469879SOfer Heifetz } 167662469879SOfer Heifetz 167762469879SOfer Heifetz struct safexcel_alg_template safexcel_alg_ecb_des3_ede = { 167862469879SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1679062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 168062469879SOfer Heifetz .alg.skcipher = { 168162469879SOfer Heifetz .setkey = safexcel_des3_ede_setkey, 168293369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 168393369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 168462469879SOfer Heifetz .min_keysize = DES3_EDE_KEY_SIZE, 168562469879SOfer Heifetz .max_keysize = DES3_EDE_KEY_SIZE, 168662469879SOfer Heifetz .base = { 168762469879SOfer Heifetz .cra_name = "ecb(des3_ede)", 168862469879SOfer Heifetz .cra_driver_name = "safexcel-ecb-des3_ede", 1689aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 16902b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 169162469879SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 169262469879SOfer Heifetz .cra_blocksize = DES3_EDE_BLOCK_SIZE, 169362469879SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 169462469879SOfer Heifetz .cra_alignmask = 0, 169593369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des3_ecb_cra_init, 169662469879SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 169762469879SOfer Heifetz .cra_module = THIS_MODULE, 169862469879SOfer Heifetz }, 169962469879SOfer Heifetz }, 170062469879SOfer Heifetz }; 170162469879SOfer Heifetz 170293369b5dSPascal van Leeuwen static int safexcel_aead_encrypt(struct aead_request *req) 1703f6beaea3SAntoine Tenart { 1704f6beaea3SAntoine Tenart struct safexcel_cipher_req *creq = aead_request_ctx(req); 1705f6beaea3SAntoine Tenart 170693369b5dSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 1707f6beaea3SAntoine Tenart } 1708f6beaea3SAntoine Tenart 170993369b5dSPascal van Leeuwen static int safexcel_aead_decrypt(struct aead_request *req) 1710f6beaea3SAntoine Tenart { 1711f6beaea3SAntoine Tenart struct safexcel_cipher_req *creq = aead_request_ctx(req); 1712f6beaea3SAntoine Tenart 171393369b5dSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 1714f6beaea3SAntoine Tenart } 1715f6beaea3SAntoine Tenart 1716f6beaea3SAntoine Tenart static int safexcel_aead_cra_init(struct crypto_tfm *tfm) 1717f6beaea3SAntoine Tenart { 1718f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1719f6beaea3SAntoine Tenart struct safexcel_alg_template *tmpl = 1720f6beaea3SAntoine Tenart container_of(tfm->__crt_alg, struct safexcel_alg_template, 1721f6beaea3SAntoine Tenart alg.aead.base); 1722f6beaea3SAntoine Tenart 1723f6beaea3SAntoine Tenart crypto_aead_set_reqsize(__crypto_aead_cast(tfm), 1724f6beaea3SAntoine Tenart sizeof(struct safexcel_cipher_req)); 1725f6beaea3SAntoine Tenart 1726f6beaea3SAntoine Tenart ctx->priv = tmpl->priv; 1727f6beaea3SAntoine Tenart 17280e17e362SPascal van Leeuwen ctx->alg = SAFEXCEL_AES; /* default */ 1729098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 1730098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD; 1731098e51e5SPascal van Leeuwen ctx->ctrinit = 1; 173293369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; /* default */ 1733f6beaea3SAntoine Tenart ctx->aead = true; 1734f6beaea3SAntoine Tenart ctx->base.send = safexcel_aead_send; 1735f6beaea3SAntoine Tenart ctx->base.handle_result = safexcel_aead_handle_result; 1736f6beaea3SAntoine Tenart return 0; 1737f6beaea3SAntoine Tenart } 1738f6beaea3SAntoine Tenart 173901ba061dSAntoine Tenart static int safexcel_aead_sha1_cra_init(struct crypto_tfm *tfm) 174001ba061dSAntoine Tenart { 174101ba061dSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 174201ba061dSAntoine Tenart 174301ba061dSAntoine Tenart safexcel_aead_cra_init(tfm); 1744a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; 174501ba061dSAntoine Tenart ctx->state_sz = SHA1_DIGEST_SIZE; 174601ba061dSAntoine Tenart return 0; 174701ba061dSAntoine Tenart } 174801ba061dSAntoine Tenart 174901ba061dSAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_aes = { 175001ba061dSAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1751062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1, 175201ba061dSAntoine Tenart .alg.aead = { 175377cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 175493369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 175593369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 175601ba061dSAntoine Tenart .ivsize = AES_BLOCK_SIZE, 175701ba061dSAntoine Tenart .maxauthsize = SHA1_DIGEST_SIZE, 175801ba061dSAntoine Tenart .base = { 175901ba061dSAntoine Tenart .cra_name = "authenc(hmac(sha1),cbc(aes))", 176001ba061dSAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-aes", 1761aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 17623f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 176301ba061dSAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 176401ba061dSAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 176501ba061dSAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 176601ba061dSAntoine Tenart .cra_alignmask = 0, 176701ba061dSAntoine Tenart .cra_init = safexcel_aead_sha1_cra_init, 176801ba061dSAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 176901ba061dSAntoine Tenart .cra_module = THIS_MODULE, 177001ba061dSAntoine Tenart }, 177101ba061dSAntoine Tenart }, 177201ba061dSAntoine Tenart }; 177301ba061dSAntoine Tenart 1774f6beaea3SAntoine Tenart static int safexcel_aead_sha256_cra_init(struct crypto_tfm *tfm) 1775f6beaea3SAntoine Tenart { 1776f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1777f6beaea3SAntoine Tenart 1778f6beaea3SAntoine Tenart safexcel_aead_cra_init(tfm); 1779a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256; 1780f6beaea3SAntoine Tenart ctx->state_sz = SHA256_DIGEST_SIZE; 1781f6beaea3SAntoine Tenart return 0; 1782f6beaea3SAntoine Tenart } 1783f6beaea3SAntoine Tenart 1784f6beaea3SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_aes = { 1785f6beaea3SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1786062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 1787f6beaea3SAntoine Tenart .alg.aead = { 178877cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 178993369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 179093369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1791f6beaea3SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 1792f6beaea3SAntoine Tenart .maxauthsize = SHA256_DIGEST_SIZE, 1793f6beaea3SAntoine Tenart .base = { 1794f6beaea3SAntoine Tenart .cra_name = "authenc(hmac(sha256),cbc(aes))", 1795f6beaea3SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-aes", 1796aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 17973f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1798f6beaea3SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 1799f6beaea3SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 1800f6beaea3SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1801f6beaea3SAntoine Tenart .cra_alignmask = 0, 1802f6beaea3SAntoine Tenart .cra_init = safexcel_aead_sha256_cra_init, 1803f6beaea3SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 1804f6beaea3SAntoine Tenart .cra_module = THIS_MODULE, 1805f6beaea3SAntoine Tenart }, 1806f6beaea3SAntoine Tenart }, 1807f6beaea3SAntoine Tenart }; 1808678b2878SAntoine Tenart 1809678b2878SAntoine Tenart static int safexcel_aead_sha224_cra_init(struct crypto_tfm *tfm) 1810678b2878SAntoine Tenart { 1811678b2878SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1812678b2878SAntoine Tenart 1813678b2878SAntoine Tenart safexcel_aead_cra_init(tfm); 1814a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224; 1815678b2878SAntoine Tenart ctx->state_sz = SHA256_DIGEST_SIZE; 1816678b2878SAntoine Tenart return 0; 1817678b2878SAntoine Tenart } 1818678b2878SAntoine Tenart 1819678b2878SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_aes = { 1820678b2878SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1821062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 1822678b2878SAntoine Tenart .alg.aead = { 182377cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 182493369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 182593369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1826678b2878SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 1827678b2878SAntoine Tenart .maxauthsize = SHA224_DIGEST_SIZE, 1828678b2878SAntoine Tenart .base = { 1829678b2878SAntoine Tenart .cra_name = "authenc(hmac(sha224),cbc(aes))", 1830678b2878SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-aes", 1831aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 18323f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1833678b2878SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 1834678b2878SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 1835678b2878SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1836678b2878SAntoine Tenart .cra_alignmask = 0, 1837678b2878SAntoine Tenart .cra_init = safexcel_aead_sha224_cra_init, 1838678b2878SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 1839678b2878SAntoine Tenart .cra_module = THIS_MODULE, 1840678b2878SAntoine Tenart }, 1841678b2878SAntoine Tenart }, 1842678b2878SAntoine Tenart }; 184387eee125SAntoine Tenart 184487eee125SAntoine Tenart static int safexcel_aead_sha512_cra_init(struct crypto_tfm *tfm) 184587eee125SAntoine Tenart { 184687eee125SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 184787eee125SAntoine Tenart 184887eee125SAntoine Tenart safexcel_aead_cra_init(tfm); 1849a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512; 185087eee125SAntoine Tenart ctx->state_sz = SHA512_DIGEST_SIZE; 185187eee125SAntoine Tenart return 0; 185287eee125SAntoine Tenart } 185387eee125SAntoine Tenart 185487eee125SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_aes = { 185587eee125SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1856062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 185787eee125SAntoine Tenart .alg.aead = { 185877cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 185993369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 186093369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 186187eee125SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 186287eee125SAntoine Tenart .maxauthsize = SHA512_DIGEST_SIZE, 186387eee125SAntoine Tenart .base = { 186487eee125SAntoine Tenart .cra_name = "authenc(hmac(sha512),cbc(aes))", 186587eee125SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-aes", 1866aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 18673f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 186887eee125SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 186987eee125SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 187087eee125SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 187187eee125SAntoine Tenart .cra_alignmask = 0, 187287eee125SAntoine Tenart .cra_init = safexcel_aead_sha512_cra_init, 187387eee125SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 187487eee125SAntoine Tenart .cra_module = THIS_MODULE, 187587eee125SAntoine Tenart }, 187687eee125SAntoine Tenart }, 187787eee125SAntoine Tenart }; 1878ea23cb53SAntoine Tenart 1879ea23cb53SAntoine Tenart static int safexcel_aead_sha384_cra_init(struct crypto_tfm *tfm) 1880ea23cb53SAntoine Tenart { 1881ea23cb53SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1882ea23cb53SAntoine Tenart 1883ea23cb53SAntoine Tenart safexcel_aead_cra_init(tfm); 1884a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384; 1885ea23cb53SAntoine Tenart ctx->state_sz = SHA512_DIGEST_SIZE; 1886ea23cb53SAntoine Tenart return 0; 1887ea23cb53SAntoine Tenart } 1888ea23cb53SAntoine Tenart 1889ea23cb53SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_aes = { 1890ea23cb53SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1891062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 1892ea23cb53SAntoine Tenart .alg.aead = { 189377cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 189493369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 189593369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1896ea23cb53SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 1897ea23cb53SAntoine Tenart .maxauthsize = SHA384_DIGEST_SIZE, 1898ea23cb53SAntoine Tenart .base = { 1899ea23cb53SAntoine Tenart .cra_name = "authenc(hmac(sha384),cbc(aes))", 1900ea23cb53SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-aes", 1901aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 19023f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1903ea23cb53SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 1904ea23cb53SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 1905ea23cb53SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1906ea23cb53SAntoine Tenart .cra_alignmask = 0, 1907ea23cb53SAntoine Tenart .cra_init = safexcel_aead_sha384_cra_init, 1908ea23cb53SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 1909ea23cb53SAntoine Tenart .cra_module = THIS_MODULE, 1910ea23cb53SAntoine Tenart }, 1911ea23cb53SAntoine Tenart }, 1912ea23cb53SAntoine Tenart }; 191377cdd4efSPascal van Leeuwen 19140e17e362SPascal van Leeuwen static int safexcel_aead_sha1_des3_cra_init(struct crypto_tfm *tfm) 19150e17e362SPascal van Leeuwen { 19160e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 19170e17e362SPascal van Leeuwen 19180e17e362SPascal van Leeuwen safexcel_aead_sha1_cra_init(tfm); 19190e17e362SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1920098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 1921098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 19220e17e362SPascal van Leeuwen return 0; 19230e17e362SPascal van Leeuwen } 19240e17e362SPascal van Leeuwen 192577cdd4efSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des3_ede = { 192677cdd4efSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1927062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, 192877cdd4efSPascal van Leeuwen .alg.aead = { 192977cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 193093369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 193193369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 193277cdd4efSPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 193377cdd4efSPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 193477cdd4efSPascal van Leeuwen .base = { 193577cdd4efSPascal van Leeuwen .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", 193677cdd4efSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des3_ede", 1937aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 193877cdd4efSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 193977cdd4efSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 194077cdd4efSPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 194177cdd4efSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 194277cdd4efSPascal van Leeuwen .cra_alignmask = 0, 19430e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha1_des3_cra_init, 19440e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 19450e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 19460e17e362SPascal van Leeuwen }, 19470e17e362SPascal van Leeuwen }, 19480e17e362SPascal van Leeuwen }; 19490e17e362SPascal van Leeuwen 1950f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha256_des3_cra_init(struct crypto_tfm *tfm) 1951f0a8bdf0SPascal van Leeuwen { 1952f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1953f0a8bdf0SPascal van Leeuwen 1954f0a8bdf0SPascal van Leeuwen safexcel_aead_sha256_cra_init(tfm); 1955f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1956098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 1957098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 1958f0a8bdf0SPascal van Leeuwen return 0; 1959f0a8bdf0SPascal van Leeuwen } 1960f0a8bdf0SPascal van Leeuwen 1961f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede = { 1962f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1963f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 1964f0a8bdf0SPascal van Leeuwen .alg.aead = { 1965f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 1966f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 1967f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1968f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 1969f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA256_DIGEST_SIZE, 1970f0a8bdf0SPascal van Leeuwen .base = { 1971f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", 1972f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des3_ede", 1973f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 1974f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1975f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 1976f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 1977f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1978f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 1979f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha256_des3_cra_init, 1980f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 1981f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 1982f0a8bdf0SPascal van Leeuwen }, 1983f0a8bdf0SPascal van Leeuwen }, 1984f0a8bdf0SPascal van Leeuwen }; 1985f0a8bdf0SPascal van Leeuwen 1986f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha224_des3_cra_init(struct crypto_tfm *tfm) 1987f0a8bdf0SPascal van Leeuwen { 1988f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1989f0a8bdf0SPascal van Leeuwen 1990f0a8bdf0SPascal van Leeuwen safexcel_aead_sha224_cra_init(tfm); 1991f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1992098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 1993098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 1994f0a8bdf0SPascal van Leeuwen return 0; 1995f0a8bdf0SPascal van Leeuwen } 1996f0a8bdf0SPascal van Leeuwen 1997f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede = { 1998f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1999f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 2000f0a8bdf0SPascal van Leeuwen .alg.aead = { 2001f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 2002f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2003f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2004f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 2005f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA224_DIGEST_SIZE, 2006f0a8bdf0SPascal van Leeuwen .base = { 2007f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha224),cbc(des3_ede))", 2008f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des3_ede", 2009f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2010f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2011f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2012f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2013f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2014f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 2015f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha224_des3_cra_init, 2016f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2017f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 2018f0a8bdf0SPascal van Leeuwen }, 2019f0a8bdf0SPascal van Leeuwen }, 2020f0a8bdf0SPascal van Leeuwen }; 2021f0a8bdf0SPascal van Leeuwen 2022f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha512_des3_cra_init(struct crypto_tfm *tfm) 2023f0a8bdf0SPascal van Leeuwen { 2024f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2025f0a8bdf0SPascal van Leeuwen 2026f0a8bdf0SPascal van Leeuwen safexcel_aead_sha512_cra_init(tfm); 2027f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 2028098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 2029098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2030f0a8bdf0SPascal van Leeuwen return 0; 2031f0a8bdf0SPascal van Leeuwen } 2032f0a8bdf0SPascal van Leeuwen 2033f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede = { 2034f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2035f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2036f0a8bdf0SPascal van Leeuwen .alg.aead = { 2037f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 2038f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2039f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2040f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 2041f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA512_DIGEST_SIZE, 2042f0a8bdf0SPascal van Leeuwen .base = { 2043f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha512),cbc(des3_ede))", 2044f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des3_ede", 2045f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2046f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2047f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2048f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2049f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2050f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 2051f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha512_des3_cra_init, 2052f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2053f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 2054f0a8bdf0SPascal van Leeuwen }, 2055f0a8bdf0SPascal van Leeuwen }, 2056f0a8bdf0SPascal van Leeuwen }; 2057f0a8bdf0SPascal van Leeuwen 2058f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha384_des3_cra_init(struct crypto_tfm *tfm) 2059f0a8bdf0SPascal van Leeuwen { 2060f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2061f0a8bdf0SPascal van Leeuwen 2062f0a8bdf0SPascal van Leeuwen safexcel_aead_sha384_cra_init(tfm); 2063f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 2064098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 2065098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2066f0a8bdf0SPascal van Leeuwen return 0; 2067f0a8bdf0SPascal van Leeuwen } 2068f0a8bdf0SPascal van Leeuwen 2069f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede = { 2070f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2071f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2072f0a8bdf0SPascal van Leeuwen .alg.aead = { 2073f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 2074f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2075f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2076f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 2077f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA384_DIGEST_SIZE, 2078f0a8bdf0SPascal van Leeuwen .base = { 2079f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha384),cbc(des3_ede))", 2080f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des3_ede", 2081f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2082f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2083f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2084f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2085f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2086f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 2087f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha384_des3_cra_init, 2088f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2089f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 2090f0a8bdf0SPascal van Leeuwen }, 2091f0a8bdf0SPascal van Leeuwen }, 2092f0a8bdf0SPascal van Leeuwen }; 2093f0a8bdf0SPascal van Leeuwen 2094bb7679b8SPascal van Leeuwen static int safexcel_aead_sha1_des_cra_init(struct crypto_tfm *tfm) 2095bb7679b8SPascal van Leeuwen { 2096bb7679b8SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2097bb7679b8SPascal van Leeuwen 2098bb7679b8SPascal van Leeuwen safexcel_aead_sha1_cra_init(tfm); 2099bb7679b8SPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2100098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2101098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2102bb7679b8SPascal van Leeuwen return 0; 2103bb7679b8SPascal van Leeuwen } 2104bb7679b8SPascal van Leeuwen 2105bb7679b8SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des = { 2106bb7679b8SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2107bb7679b8SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, 2108bb7679b8SPascal van Leeuwen .alg.aead = { 2109bb7679b8SPascal van Leeuwen .setkey = safexcel_aead_setkey, 2110bb7679b8SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2111bb7679b8SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2112bb7679b8SPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2113bb7679b8SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 2114bb7679b8SPascal van Leeuwen .base = { 2115bb7679b8SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),cbc(des))", 2116bb7679b8SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des", 2117bb7679b8SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2118bb7679b8SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2119bb7679b8SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2120bb7679b8SPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2121bb7679b8SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2122bb7679b8SPascal van Leeuwen .cra_alignmask = 0, 2123bb7679b8SPascal van Leeuwen .cra_init = safexcel_aead_sha1_des_cra_init, 2124bb7679b8SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2125bb7679b8SPascal van Leeuwen .cra_module = THIS_MODULE, 2126bb7679b8SPascal van Leeuwen }, 2127bb7679b8SPascal van Leeuwen }, 2128bb7679b8SPascal van Leeuwen }; 2129bb7679b8SPascal van Leeuwen 2130457a6fdfSPascal van Leeuwen static int safexcel_aead_sha256_des_cra_init(struct crypto_tfm *tfm) 2131457a6fdfSPascal van Leeuwen { 2132457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2133457a6fdfSPascal van Leeuwen 2134457a6fdfSPascal van Leeuwen safexcel_aead_sha256_cra_init(tfm); 2135457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2136098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2137098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2138457a6fdfSPascal van Leeuwen return 0; 2139457a6fdfSPascal van Leeuwen } 2140457a6fdfSPascal van Leeuwen 2141457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des = { 2142457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2143457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 2144457a6fdfSPascal van Leeuwen .alg.aead = { 2145457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2146457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2147457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2148457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2149457a6fdfSPascal van Leeuwen .maxauthsize = SHA256_DIGEST_SIZE, 2150457a6fdfSPascal van Leeuwen .base = { 2151457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha256),cbc(des))", 2152457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des", 2153457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2154457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2155457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2156457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2157457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2158457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2159457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha256_des_cra_init, 2160457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2161457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2162457a6fdfSPascal van Leeuwen }, 2163457a6fdfSPascal van Leeuwen }, 2164457a6fdfSPascal van Leeuwen }; 2165457a6fdfSPascal van Leeuwen 2166457a6fdfSPascal van Leeuwen static int safexcel_aead_sha224_des_cra_init(struct crypto_tfm *tfm) 2167457a6fdfSPascal van Leeuwen { 2168457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2169457a6fdfSPascal van Leeuwen 2170457a6fdfSPascal van Leeuwen safexcel_aead_sha224_cra_init(tfm); 2171457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2172098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2173098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2174457a6fdfSPascal van Leeuwen return 0; 2175457a6fdfSPascal van Leeuwen } 2176457a6fdfSPascal van Leeuwen 2177457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des = { 2178457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2179457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 2180457a6fdfSPascal van Leeuwen .alg.aead = { 2181457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2182457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2183457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2184457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2185457a6fdfSPascal van Leeuwen .maxauthsize = SHA224_DIGEST_SIZE, 2186457a6fdfSPascal van Leeuwen .base = { 2187457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha224),cbc(des))", 2188457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des", 2189457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2190457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2191457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2192457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2193457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2194457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2195457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha224_des_cra_init, 2196457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2197457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2198457a6fdfSPascal van Leeuwen }, 2199457a6fdfSPascal van Leeuwen }, 2200457a6fdfSPascal van Leeuwen }; 2201457a6fdfSPascal van Leeuwen 2202457a6fdfSPascal van Leeuwen static int safexcel_aead_sha512_des_cra_init(struct crypto_tfm *tfm) 2203457a6fdfSPascal van Leeuwen { 2204457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2205457a6fdfSPascal van Leeuwen 2206457a6fdfSPascal van Leeuwen safexcel_aead_sha512_cra_init(tfm); 2207457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2208098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2209098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2210457a6fdfSPascal van Leeuwen return 0; 2211457a6fdfSPascal van Leeuwen } 2212457a6fdfSPascal van Leeuwen 2213457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des = { 2214457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2215457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2216457a6fdfSPascal van Leeuwen .alg.aead = { 2217457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2218457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2219457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2220457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2221457a6fdfSPascal van Leeuwen .maxauthsize = SHA512_DIGEST_SIZE, 2222457a6fdfSPascal van Leeuwen .base = { 2223457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha512),cbc(des))", 2224457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des", 2225457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2226457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2227457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2228457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2229457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2230457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2231457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha512_des_cra_init, 2232457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2233457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2234457a6fdfSPascal van Leeuwen }, 2235457a6fdfSPascal van Leeuwen }, 2236457a6fdfSPascal van Leeuwen }; 2237457a6fdfSPascal van Leeuwen 2238457a6fdfSPascal van Leeuwen static int safexcel_aead_sha384_des_cra_init(struct crypto_tfm *tfm) 2239457a6fdfSPascal van Leeuwen { 2240457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2241457a6fdfSPascal van Leeuwen 2242457a6fdfSPascal van Leeuwen safexcel_aead_sha384_cra_init(tfm); 2243457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2244098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2245098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2246457a6fdfSPascal van Leeuwen return 0; 2247457a6fdfSPascal van Leeuwen } 2248457a6fdfSPascal van Leeuwen 2249457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des = { 2250457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2251457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2252457a6fdfSPascal van Leeuwen .alg.aead = { 2253457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2254457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2255457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2256457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2257457a6fdfSPascal van Leeuwen .maxauthsize = SHA384_DIGEST_SIZE, 2258457a6fdfSPascal van Leeuwen .base = { 2259457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha384),cbc(des))", 2260457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des", 2261457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2262457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2263457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2264457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2265457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2266457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2267457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha384_des_cra_init, 2268457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2269457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2270457a6fdfSPascal van Leeuwen }, 2271457a6fdfSPascal van Leeuwen }, 2272457a6fdfSPascal van Leeuwen }; 2273457a6fdfSPascal van Leeuwen 22740e17e362SPascal van Leeuwen static int safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm *tfm) 22750e17e362SPascal van Leeuwen { 22760e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 22770e17e362SPascal van Leeuwen 22780e17e362SPascal van Leeuwen safexcel_aead_sha1_cra_init(tfm); 22790e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 22800e17e362SPascal van Leeuwen return 0; 22810e17e362SPascal van Leeuwen } 22820e17e362SPascal van Leeuwen 22830e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_aes = { 22840e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2285062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1, 22860e17e362SPascal van Leeuwen .alg.aead = { 22870e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 228893369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 228993369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2290f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 22910e17e362SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 22920e17e362SPascal van Leeuwen .base = { 22930e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))", 22940e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-aes", 2295aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 22960e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 22970e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 22980e17e362SPascal van Leeuwen .cra_blocksize = 1, 22990e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 23000e17e362SPascal van Leeuwen .cra_alignmask = 0, 23010e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha1_ctr_cra_init, 23020e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 23030e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 23040e17e362SPascal van Leeuwen }, 23050e17e362SPascal van Leeuwen }, 23060e17e362SPascal van Leeuwen }; 23070e17e362SPascal van Leeuwen 23080e17e362SPascal van Leeuwen static int safexcel_aead_sha256_ctr_cra_init(struct crypto_tfm *tfm) 23090e17e362SPascal van Leeuwen { 23100e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 23110e17e362SPascal van Leeuwen 23120e17e362SPascal van Leeuwen safexcel_aead_sha256_cra_init(tfm); 23130e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 23140e17e362SPascal van Leeuwen return 0; 23150e17e362SPascal van Leeuwen } 23160e17e362SPascal van Leeuwen 23170e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes = { 23180e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2319062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 23200e17e362SPascal van Leeuwen .alg.aead = { 23210e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 232293369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 232393369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2324f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 23250e17e362SPascal van Leeuwen .maxauthsize = SHA256_DIGEST_SIZE, 23260e17e362SPascal van Leeuwen .base = { 23270e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))", 23280e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha256-ctr-aes", 2329aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 23300e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 23310e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 23320e17e362SPascal van Leeuwen .cra_blocksize = 1, 23330e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 23340e17e362SPascal van Leeuwen .cra_alignmask = 0, 23350e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha256_ctr_cra_init, 23360e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 23370e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 23380e17e362SPascal van Leeuwen }, 23390e17e362SPascal van Leeuwen }, 23400e17e362SPascal van Leeuwen }; 23410e17e362SPascal van Leeuwen 23420e17e362SPascal van Leeuwen static int safexcel_aead_sha224_ctr_cra_init(struct crypto_tfm *tfm) 23430e17e362SPascal van Leeuwen { 23440e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 23450e17e362SPascal van Leeuwen 23460e17e362SPascal van Leeuwen safexcel_aead_sha224_cra_init(tfm); 23470e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 23480e17e362SPascal van Leeuwen return 0; 23490e17e362SPascal van Leeuwen } 23500e17e362SPascal van Leeuwen 23510e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_ctr_aes = { 23520e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2353062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 23540e17e362SPascal van Leeuwen .alg.aead = { 23550e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 235693369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 235793369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2358f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 23590e17e362SPascal van Leeuwen .maxauthsize = SHA224_DIGEST_SIZE, 23600e17e362SPascal van Leeuwen .base = { 23610e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))", 23620e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha224-ctr-aes", 2363aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 23640e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 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 | 23990e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 24000e17e362SPascal van Leeuwen .cra_blocksize = 1, 24010e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 24020e17e362SPascal van Leeuwen .cra_alignmask = 0, 24030e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha512_ctr_cra_init, 24040e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 24050e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 24060e17e362SPascal van Leeuwen }, 24070e17e362SPascal van Leeuwen }, 24080e17e362SPascal van Leeuwen }; 24090e17e362SPascal van Leeuwen 24100e17e362SPascal van Leeuwen static int safexcel_aead_sha384_ctr_cra_init(struct crypto_tfm *tfm) 24110e17e362SPascal van Leeuwen { 24120e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 24130e17e362SPascal van Leeuwen 24140e17e362SPascal van Leeuwen safexcel_aead_sha384_cra_init(tfm); 24150e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 24160e17e362SPascal van Leeuwen return 0; 24170e17e362SPascal van Leeuwen } 24180e17e362SPascal van Leeuwen 24190e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes = { 24200e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2421062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 24220e17e362SPascal van Leeuwen .alg.aead = { 24230e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 242493369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 242593369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2426f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 24270e17e362SPascal van Leeuwen .maxauthsize = SHA384_DIGEST_SIZE, 24280e17e362SPascal van Leeuwen .base = { 24290e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha384),rfc3686(ctr(aes)))", 24300e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha384-ctr-aes", 2431aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 24320e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 24330e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 24340e17e362SPascal van Leeuwen .cra_blocksize = 1, 24350e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 24360e17e362SPascal van Leeuwen .cra_alignmask = 0, 24370e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha384_ctr_cra_init, 243877cdd4efSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 243977cdd4efSPascal van Leeuwen .cra_module = THIS_MODULE, 244077cdd4efSPascal van Leeuwen }, 244177cdd4efSPascal van Leeuwen }, 244277cdd4efSPascal van Leeuwen }; 2443c7da38a7SPascal van Leeuwen 2444c7da38a7SPascal van Leeuwen static int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm, 2445c7da38a7SPascal van Leeuwen const u8 *key, unsigned int len) 2446c7da38a7SPascal van Leeuwen { 2447c7da38a7SPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 2448c7da38a7SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2449c7da38a7SPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 2450c7da38a7SPascal van Leeuwen struct crypto_aes_ctx aes; 2451c7da38a7SPascal van Leeuwen int ret, i; 2452c7da38a7SPascal van Leeuwen unsigned int keylen; 2453c7da38a7SPascal van Leeuwen 2454c7da38a7SPascal van Leeuwen /* Check for illegal XTS keys */ 2455c7da38a7SPascal van Leeuwen ret = xts_verify_key(ctfm, key, len); 2456c7da38a7SPascal van Leeuwen if (ret) 2457c7da38a7SPascal van Leeuwen return ret; 2458c7da38a7SPascal van Leeuwen 2459c7da38a7SPascal van Leeuwen /* Only half of the key data is cipher key */ 2460c7da38a7SPascal van Leeuwen keylen = (len >> 1); 2461c7da38a7SPascal van Leeuwen ret = aes_expandkey(&aes, key, keylen); 2462c7da38a7SPascal van Leeuwen if (ret) { 2463c7da38a7SPascal van Leeuwen crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 2464c7da38a7SPascal van Leeuwen return ret; 2465c7da38a7SPascal van Leeuwen } 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); 2481c7da38a7SPascal van Leeuwen if (ret) { 2482c7da38a7SPascal van Leeuwen crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 2483c7da38a7SPascal van Leeuwen return ret; 2484c7da38a7SPascal van Leeuwen } 2485c7da38a7SPascal van Leeuwen 2486c7da38a7SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 2487c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) { 248813a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i + keylen / sizeof(u32)]) != 248913a1bb93SPascal van Leeuwen aes.key_enc[i]) { 2490c7da38a7SPascal van Leeuwen ctx->base.needs_inv = true; 2491c7da38a7SPascal van Leeuwen break; 2492c7da38a7SPascal van Leeuwen } 2493c7da38a7SPascal van Leeuwen } 2494c7da38a7SPascal van Leeuwen } 2495c7da38a7SPascal van Leeuwen 2496c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) 2497c7da38a7SPascal van Leeuwen ctx->key[i + keylen / sizeof(u32)] = 2498c7da38a7SPascal van Leeuwen cpu_to_le32(aes.key_enc[i]); 2499c7da38a7SPascal van Leeuwen 2500c7da38a7SPascal van Leeuwen ctx->key_len = keylen << 1; 2501c7da38a7SPascal van Leeuwen 2502c7da38a7SPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 2503c7da38a7SPascal van Leeuwen return 0; 2504c7da38a7SPascal van Leeuwen } 2505c7da38a7SPascal van Leeuwen 2506c7da38a7SPascal van Leeuwen static int safexcel_skcipher_aes_xts_cra_init(struct crypto_tfm *tfm) 2507c7da38a7SPascal van Leeuwen { 2508c7da38a7SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2509c7da38a7SPascal van Leeuwen 2510c7da38a7SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 2511c7da38a7SPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 2512098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 2513c7da38a7SPascal van Leeuwen ctx->xts = 1; 2514c7da38a7SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS; 2515c7da38a7SPascal van Leeuwen return 0; 2516c7da38a7SPascal van Leeuwen } 2517c7da38a7SPascal van Leeuwen 2518c7da38a7SPascal van Leeuwen static int safexcel_encrypt_xts(struct skcipher_request *req) 2519c7da38a7SPascal van Leeuwen { 2520c7da38a7SPascal van Leeuwen if (req->cryptlen < XTS_BLOCK_SIZE) 2521c7da38a7SPascal van Leeuwen return -EINVAL; 2522c7da38a7SPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 2523c7da38a7SPascal van Leeuwen SAFEXCEL_ENCRYPT); 2524c7da38a7SPascal van Leeuwen } 2525c7da38a7SPascal van Leeuwen 2526c7da38a7SPascal van Leeuwen static int safexcel_decrypt_xts(struct skcipher_request *req) 2527c7da38a7SPascal van Leeuwen { 2528c7da38a7SPascal van Leeuwen if (req->cryptlen < XTS_BLOCK_SIZE) 2529c7da38a7SPascal van Leeuwen return -EINVAL; 2530c7da38a7SPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 2531c7da38a7SPascal van Leeuwen SAFEXCEL_DECRYPT); 2532c7da38a7SPascal van Leeuwen } 2533c7da38a7SPascal van Leeuwen 2534c7da38a7SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_xts_aes = { 2535c7da38a7SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 2536062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XTS, 2537c7da38a7SPascal van Leeuwen .alg.skcipher = { 2538c7da38a7SPascal van Leeuwen .setkey = safexcel_skcipher_aesxts_setkey, 2539c7da38a7SPascal van Leeuwen .encrypt = safexcel_encrypt_xts, 2540c7da38a7SPascal van Leeuwen .decrypt = safexcel_decrypt_xts, 2541c7da38a7SPascal van Leeuwen /* XTS actually uses 2 AES keys glued together */ 2542c7da38a7SPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE * 2, 2543c7da38a7SPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE * 2, 2544c7da38a7SPascal van Leeuwen .ivsize = XTS_BLOCK_SIZE, 2545c7da38a7SPascal van Leeuwen .base = { 2546c7da38a7SPascal van Leeuwen .cra_name = "xts(aes)", 2547c7da38a7SPascal van Leeuwen .cra_driver_name = "safexcel-xts-aes", 2548aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2549c7da38a7SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2550c7da38a7SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2551c7da38a7SPascal van Leeuwen .cra_blocksize = XTS_BLOCK_SIZE, 2552c7da38a7SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2553c7da38a7SPascal van Leeuwen .cra_alignmask = 0, 2554c7da38a7SPascal van Leeuwen .cra_init = safexcel_skcipher_aes_xts_cra_init, 2555c7da38a7SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 2556c7da38a7SPascal van Leeuwen .cra_module = THIS_MODULE, 2557c7da38a7SPascal van Leeuwen }, 2558c7da38a7SPascal van Leeuwen }, 2559c7da38a7SPascal van Leeuwen }; 25603e450886SPascal van Leeuwen 25613e450886SPascal van Leeuwen static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, 25623e450886SPascal van Leeuwen unsigned int len) 25633e450886SPascal van Leeuwen { 25643e450886SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 25653e450886SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 25663e450886SPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 25673e450886SPascal van Leeuwen struct crypto_aes_ctx aes; 25683e450886SPascal van Leeuwen u32 hashkey[AES_BLOCK_SIZE >> 2]; 25693e450886SPascal van Leeuwen int ret, i; 25703e450886SPascal van Leeuwen 25713e450886SPascal van Leeuwen ret = aes_expandkey(&aes, key, len); 25723e450886SPascal van Leeuwen if (ret) { 25733e450886SPascal van Leeuwen crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 25743e450886SPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 25753e450886SPascal van Leeuwen return ret; 25763e450886SPascal van Leeuwen } 25773e450886SPascal van Leeuwen 25783e450886SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 25793e450886SPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) { 258013a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 25813e450886SPascal van Leeuwen ctx->base.needs_inv = true; 25823e450886SPascal van Leeuwen break; 25833e450886SPascal van Leeuwen } 25843e450886SPascal van Leeuwen } 25853e450886SPascal van Leeuwen } 25863e450886SPascal van Leeuwen 25873e450886SPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) 25883e450886SPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 25893e450886SPascal van Leeuwen 25903e450886SPascal van Leeuwen ctx->key_len = len; 25913e450886SPascal van Leeuwen 25923e450886SPascal van Leeuwen /* Compute hash key by encrypting zeroes with cipher key */ 25933e450886SPascal van Leeuwen crypto_cipher_clear_flags(ctx->hkaes, CRYPTO_TFM_REQ_MASK); 25943e450886SPascal van Leeuwen crypto_cipher_set_flags(ctx->hkaes, crypto_aead_get_flags(ctfm) & 25953e450886SPascal van Leeuwen CRYPTO_TFM_REQ_MASK); 25963e450886SPascal van Leeuwen ret = crypto_cipher_setkey(ctx->hkaes, key, len); 25973e450886SPascal van Leeuwen crypto_aead_set_flags(ctfm, crypto_cipher_get_flags(ctx->hkaes) & 25983e450886SPascal van Leeuwen CRYPTO_TFM_RES_MASK); 25993e450886SPascal van Leeuwen if (ret) 26003e450886SPascal van Leeuwen return ret; 26013e450886SPascal van Leeuwen 26023e450886SPascal van Leeuwen memset(hashkey, 0, AES_BLOCK_SIZE); 26033e450886SPascal van Leeuwen crypto_cipher_encrypt_one(ctx->hkaes, (u8 *)hashkey, (u8 *)hashkey); 26043e450886SPascal van Leeuwen 26053e450886SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 26063e450886SPascal van Leeuwen for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) { 260713a1bb93SPascal van Leeuwen if (be32_to_cpu(ctx->ipad[i]) != hashkey[i]) { 26083e450886SPascal van Leeuwen ctx->base.needs_inv = true; 26093e450886SPascal van Leeuwen break; 26103e450886SPascal van Leeuwen } 26113e450886SPascal van Leeuwen } 26123e450886SPascal van Leeuwen } 26133e450886SPascal van Leeuwen 26143e450886SPascal van Leeuwen for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) 26153e450886SPascal van Leeuwen ctx->ipad[i] = cpu_to_be32(hashkey[i]); 26163e450886SPascal van Leeuwen 26173e450886SPascal van Leeuwen memzero_explicit(hashkey, AES_BLOCK_SIZE); 26183e450886SPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 26193e450886SPascal van Leeuwen return 0; 26203e450886SPascal van Leeuwen } 26213e450886SPascal van Leeuwen 26223e450886SPascal van Leeuwen static int safexcel_aead_gcm_cra_init(struct crypto_tfm *tfm) 26233e450886SPascal van Leeuwen { 26243e450886SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 26253e450886SPascal van Leeuwen 26263e450886SPascal van Leeuwen safexcel_aead_cra_init(tfm); 26273e450886SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_GHASH; 26283e450886SPascal van Leeuwen ctx->state_sz = GHASH_BLOCK_SIZE; 26294eb76fafSPascal van Leeuwen ctx->xcm = EIP197_XCM_MODE_GCM; 26303e450886SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ 26313e450886SPascal van Leeuwen 26323e450886SPascal van Leeuwen ctx->hkaes = crypto_alloc_cipher("aes", 0, 0); 26333f61b052Szhengbin return PTR_ERR_OR_ZERO(ctx->hkaes); 26343e450886SPascal van Leeuwen } 26353e450886SPascal van Leeuwen 26363e450886SPascal van Leeuwen static void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm) 26373e450886SPascal van Leeuwen { 26383e450886SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 26393e450886SPascal van Leeuwen 26403e450886SPascal van Leeuwen crypto_free_cipher(ctx->hkaes); 26413e450886SPascal van Leeuwen safexcel_aead_cra_exit(tfm); 26423e450886SPascal van Leeuwen } 26433e450886SPascal van Leeuwen 26443e450886SPascal van Leeuwen static int safexcel_aead_gcm_setauthsize(struct crypto_aead *tfm, 26453e450886SPascal van Leeuwen unsigned int authsize) 26463e450886SPascal van Leeuwen { 26473e450886SPascal van Leeuwen return crypto_gcm_check_authsize(authsize); 26483e450886SPascal van Leeuwen } 26493e450886SPascal van Leeuwen 26503e450886SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_gcm = { 26513e450886SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 26523e450886SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 26533e450886SPascal van Leeuwen .alg.aead = { 26543e450886SPascal van Leeuwen .setkey = safexcel_aead_gcm_setkey, 26553e450886SPascal van Leeuwen .setauthsize = safexcel_aead_gcm_setauthsize, 26563e450886SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 26573e450886SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 26583e450886SPascal van Leeuwen .ivsize = GCM_AES_IV_SIZE, 26593e450886SPascal van Leeuwen .maxauthsize = GHASH_DIGEST_SIZE, 26603e450886SPascal van Leeuwen .base = { 26613e450886SPascal van Leeuwen .cra_name = "gcm(aes)", 26623e450886SPascal van Leeuwen .cra_driver_name = "safexcel-gcm-aes", 26633e450886SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 26643e450886SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 26653e450886SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 26663e450886SPascal van Leeuwen .cra_blocksize = 1, 26673e450886SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 26683e450886SPascal van Leeuwen .cra_alignmask = 0, 26693e450886SPascal van Leeuwen .cra_init = safexcel_aead_gcm_cra_init, 26703e450886SPascal van Leeuwen .cra_exit = safexcel_aead_gcm_cra_exit, 26713e450886SPascal van Leeuwen .cra_module = THIS_MODULE, 26723e450886SPascal van Leeuwen }, 26733e450886SPascal van Leeuwen }, 26743e450886SPascal van Leeuwen }; 26754eb76fafSPascal van Leeuwen 26764eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, 26774eb76fafSPascal van Leeuwen unsigned int len) 26784eb76fafSPascal van Leeuwen { 26794eb76fafSPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 26804eb76fafSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 26814eb76fafSPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 26824eb76fafSPascal van Leeuwen struct crypto_aes_ctx aes; 26834eb76fafSPascal van Leeuwen int ret, i; 26844eb76fafSPascal van Leeuwen 26854eb76fafSPascal van Leeuwen ret = aes_expandkey(&aes, key, len); 26864eb76fafSPascal van Leeuwen if (ret) { 26874eb76fafSPascal van Leeuwen crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 26884eb76fafSPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 26894eb76fafSPascal van Leeuwen return ret; 26904eb76fafSPascal van Leeuwen } 26914eb76fafSPascal van Leeuwen 26924eb76fafSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 26934eb76fafSPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) { 269413a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 26954eb76fafSPascal van Leeuwen ctx->base.needs_inv = true; 26964eb76fafSPascal van Leeuwen break; 26974eb76fafSPascal van Leeuwen } 26984eb76fafSPascal van Leeuwen } 26994eb76fafSPascal van Leeuwen } 27004eb76fafSPascal van Leeuwen 27014eb76fafSPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) { 27024eb76fafSPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 27034eb76fafSPascal van Leeuwen ctx->ipad[i + 2 * AES_BLOCK_SIZE / sizeof(u32)] = 27044eb76fafSPascal van Leeuwen cpu_to_be32(aes.key_enc[i]); 27054eb76fafSPascal van Leeuwen } 27064eb76fafSPascal van Leeuwen 27074eb76fafSPascal van Leeuwen ctx->key_len = len; 27084eb76fafSPascal van Leeuwen ctx->state_sz = 2 * AES_BLOCK_SIZE + len; 27094eb76fafSPascal van Leeuwen 27104eb76fafSPascal van Leeuwen if (len == AES_KEYSIZE_192) 27114eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192; 27124eb76fafSPascal van Leeuwen else if (len == AES_KEYSIZE_256) 27134eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256; 27144eb76fafSPascal van Leeuwen else 27154eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; 27164eb76fafSPascal van Leeuwen 27174eb76fafSPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 27184eb76fafSPascal van Leeuwen return 0; 27194eb76fafSPascal van Leeuwen } 27204eb76fafSPascal van Leeuwen 27214eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_cra_init(struct crypto_tfm *tfm) 27224eb76fafSPascal van Leeuwen { 27234eb76fafSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 27244eb76fafSPascal van Leeuwen 27254eb76fafSPascal van Leeuwen safexcel_aead_cra_init(tfm); 27264eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; 27274eb76fafSPascal van Leeuwen ctx->state_sz = 3 * AES_BLOCK_SIZE; 27284eb76fafSPascal van Leeuwen ctx->xcm = EIP197_XCM_MODE_CCM; 27294eb76fafSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ 2730098e51e5SPascal van Leeuwen ctx->ctrinit = 0; 27314eb76fafSPascal van Leeuwen return 0; 27324eb76fafSPascal van Leeuwen } 27334eb76fafSPascal van Leeuwen 27344eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_setauthsize(struct crypto_aead *tfm, 27354eb76fafSPascal van Leeuwen unsigned int authsize) 27364eb76fafSPascal van Leeuwen { 27374eb76fafSPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 27384eb76fafSPascal van Leeuwen switch (authsize) { 27394eb76fafSPascal van Leeuwen case 4: 27404eb76fafSPascal van Leeuwen case 6: 27414eb76fafSPascal van Leeuwen case 8: 27424eb76fafSPascal van Leeuwen case 10: 27434eb76fafSPascal van Leeuwen case 12: 27444eb76fafSPascal van Leeuwen case 14: 27454eb76fafSPascal van Leeuwen case 16: 27464eb76fafSPascal van Leeuwen break; 27474eb76fafSPascal van Leeuwen default: 27484eb76fafSPascal van Leeuwen return -EINVAL; 27494eb76fafSPascal van Leeuwen } 27504eb76fafSPascal van Leeuwen 27514eb76fafSPascal van Leeuwen return 0; 27524eb76fafSPascal van Leeuwen } 27534eb76fafSPascal van Leeuwen 27544eb76fafSPascal van Leeuwen static int safexcel_ccm_encrypt(struct aead_request *req) 27554eb76fafSPascal van Leeuwen { 27564eb76fafSPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 27574eb76fafSPascal van Leeuwen 27584eb76fafSPascal van Leeuwen if (req->iv[0] < 1 || req->iv[0] > 7) 27594eb76fafSPascal van Leeuwen return -EINVAL; 27604eb76fafSPascal van Leeuwen 27614eb76fafSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 27624eb76fafSPascal van Leeuwen } 27634eb76fafSPascal van Leeuwen 27644eb76fafSPascal van Leeuwen static int safexcel_ccm_decrypt(struct aead_request *req) 27654eb76fafSPascal van Leeuwen { 27664eb76fafSPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 27674eb76fafSPascal van Leeuwen 27684eb76fafSPascal van Leeuwen if (req->iv[0] < 1 || req->iv[0] > 7) 27694eb76fafSPascal van Leeuwen return -EINVAL; 27704eb76fafSPascal van Leeuwen 27714eb76fafSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 27724eb76fafSPascal van Leeuwen } 27734eb76fafSPascal van Leeuwen 27744eb76fafSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ccm = { 27754eb76fafSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 27764eb76fafSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, 27774eb76fafSPascal van Leeuwen .alg.aead = { 27784eb76fafSPascal van Leeuwen .setkey = safexcel_aead_ccm_setkey, 27794eb76fafSPascal van Leeuwen .setauthsize = safexcel_aead_ccm_setauthsize, 27804eb76fafSPascal van Leeuwen .encrypt = safexcel_ccm_encrypt, 27814eb76fafSPascal van Leeuwen .decrypt = safexcel_ccm_decrypt, 27824eb76fafSPascal van Leeuwen .ivsize = AES_BLOCK_SIZE, 27834eb76fafSPascal van Leeuwen .maxauthsize = AES_BLOCK_SIZE, 27844eb76fafSPascal van Leeuwen .base = { 27854eb76fafSPascal van Leeuwen .cra_name = "ccm(aes)", 27864eb76fafSPascal van Leeuwen .cra_driver_name = "safexcel-ccm-aes", 27874eb76fafSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 27884eb76fafSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 27894eb76fafSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 27904eb76fafSPascal van Leeuwen .cra_blocksize = 1, 27914eb76fafSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 27924eb76fafSPascal van Leeuwen .cra_alignmask = 0, 27934eb76fafSPascal van Leeuwen .cra_init = safexcel_aead_ccm_cra_init, 27944eb76fafSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 27954eb76fafSPascal van Leeuwen .cra_module = THIS_MODULE, 27964eb76fafSPascal van Leeuwen }, 27974eb76fafSPascal van Leeuwen }, 27984eb76fafSPascal van Leeuwen }; 27994a593fb3SPascal van Leeuwen 2800a6061921SPascal van Leeuwen static void safexcel_chacha20_setkey(struct safexcel_cipher_ctx *ctx, 2801a6061921SPascal van Leeuwen const u8 *key) 28024a593fb3SPascal van Leeuwen { 28034a593fb3SPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 28044a593fb3SPascal van Leeuwen 280513a1bb93SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 280613a1bb93SPascal van Leeuwen if (memcmp(ctx->key, key, CHACHA_KEY_SIZE)) 28074a593fb3SPascal van Leeuwen ctx->base.needs_inv = true; 28084a593fb3SPascal van Leeuwen 280913a1bb93SPascal van Leeuwen memcpy(ctx->key, key, CHACHA_KEY_SIZE); 28104a593fb3SPascal van Leeuwen ctx->key_len = CHACHA_KEY_SIZE; 2811a6061921SPascal van Leeuwen } 2812a6061921SPascal van Leeuwen 2813a6061921SPascal van Leeuwen static int safexcel_skcipher_chacha20_setkey(struct crypto_skcipher *ctfm, 2814a6061921SPascal van Leeuwen const u8 *key, unsigned int len) 2815a6061921SPascal van Leeuwen { 2816a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 2817a6061921SPascal van Leeuwen 2818a6061921SPascal van Leeuwen if (len != CHACHA_KEY_SIZE) { 2819a6061921SPascal van Leeuwen crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 2820a6061921SPascal van Leeuwen return -EINVAL; 2821a6061921SPascal van Leeuwen } 2822a6061921SPascal van Leeuwen safexcel_chacha20_setkey(ctx, key); 28234a593fb3SPascal van Leeuwen 28244a593fb3SPascal van Leeuwen return 0; 28254a593fb3SPascal van Leeuwen } 28264a593fb3SPascal van Leeuwen 28274a593fb3SPascal van Leeuwen static int safexcel_skcipher_chacha20_cra_init(struct crypto_tfm *tfm) 28284a593fb3SPascal van Leeuwen { 28294a593fb3SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 28304a593fb3SPascal van Leeuwen 28314a593fb3SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 28324a593fb3SPascal van Leeuwen ctx->alg = SAFEXCEL_CHACHA20; 2833098e51e5SPascal van Leeuwen ctx->ctrinit = 0; 28344a593fb3SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32; 28354a593fb3SPascal van Leeuwen return 0; 28364a593fb3SPascal van Leeuwen } 28374a593fb3SPascal van Leeuwen 28384a593fb3SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chacha20 = { 28394a593fb3SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 28404a593fb3SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_CHACHA20, 28414a593fb3SPascal van Leeuwen .alg.skcipher = { 28424a593fb3SPascal van Leeuwen .setkey = safexcel_skcipher_chacha20_setkey, 28434a593fb3SPascal van Leeuwen .encrypt = safexcel_encrypt, 28444a593fb3SPascal van Leeuwen .decrypt = safexcel_decrypt, 28454a593fb3SPascal van Leeuwen .min_keysize = CHACHA_KEY_SIZE, 28464a593fb3SPascal van Leeuwen .max_keysize = CHACHA_KEY_SIZE, 28474a593fb3SPascal van Leeuwen .ivsize = CHACHA_IV_SIZE, 28484a593fb3SPascal van Leeuwen .base = { 28494a593fb3SPascal van Leeuwen .cra_name = "chacha20", 28504a593fb3SPascal van Leeuwen .cra_driver_name = "safexcel-chacha20", 28514a593fb3SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 28524a593fb3SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 28534a593fb3SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 28544a593fb3SPascal van Leeuwen .cra_blocksize = 1, 28554a593fb3SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 28564a593fb3SPascal van Leeuwen .cra_alignmask = 0, 28574a593fb3SPascal van Leeuwen .cra_init = safexcel_skcipher_chacha20_cra_init, 28584a593fb3SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 28594a593fb3SPascal van Leeuwen .cra_module = THIS_MODULE, 28604a593fb3SPascal van Leeuwen }, 28614a593fb3SPascal van Leeuwen }, 28624a593fb3SPascal van Leeuwen }; 2863a6061921SPascal van Leeuwen 2864a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_setkey(struct crypto_aead *ctfm, 2865a6061921SPascal van Leeuwen const u8 *key, unsigned int len) 2866a6061921SPascal van Leeuwen { 2867a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_aead_ctx(ctfm); 2868a6061921SPascal van Leeuwen 2869a6061921SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP && 2870a6061921SPascal van Leeuwen len > EIP197_AEAD_IPSEC_NONCE_SIZE) { 2871a6061921SPascal van Leeuwen /* ESP variant has nonce appended to key */ 2872a6061921SPascal van Leeuwen len -= EIP197_AEAD_IPSEC_NONCE_SIZE; 2873a6061921SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len); 2874a6061921SPascal van Leeuwen } 2875a6061921SPascal van Leeuwen if (len != CHACHA_KEY_SIZE) { 2876a6061921SPascal van Leeuwen crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 2877a6061921SPascal van Leeuwen return -EINVAL; 2878a6061921SPascal van Leeuwen } 2879a6061921SPascal van Leeuwen safexcel_chacha20_setkey(ctx, key); 2880a6061921SPascal van Leeuwen 2881a6061921SPascal van Leeuwen return 0; 2882a6061921SPascal van Leeuwen } 2883a6061921SPascal van Leeuwen 2884a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_setauthsize(struct crypto_aead *tfm, 2885a6061921SPascal van Leeuwen unsigned int authsize) 2886a6061921SPascal van Leeuwen { 2887a6061921SPascal van Leeuwen if (authsize != POLY1305_DIGEST_SIZE) 2888a6061921SPascal van Leeuwen return -EINVAL; 2889a6061921SPascal van Leeuwen return 0; 2890a6061921SPascal van Leeuwen } 2891a6061921SPascal van Leeuwen 2892a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_crypt(struct aead_request *req, 2893a6061921SPascal van Leeuwen enum safexcel_cipher_direction dir) 2894a6061921SPascal van Leeuwen { 2895a6061921SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 2896a6061921SPascal van Leeuwen struct crypto_aead *aead = crypto_aead_reqtfm(req); 2897a6061921SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(aead); 2898a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2899a6061921SPascal van Leeuwen struct aead_request *subreq = aead_request_ctx(req); 2900a6061921SPascal van Leeuwen u32 key[CHACHA_KEY_SIZE / sizeof(u32) + 1]; 290113a1bb93SPascal van Leeuwen int ret = 0; 2902a6061921SPascal van Leeuwen 2903a6061921SPascal van Leeuwen /* 2904a6061921SPascal van Leeuwen * Instead of wasting time detecting umpteen silly corner cases, 2905a6061921SPascal van Leeuwen * just dump all "small" requests to the fallback implementation. 2906a6061921SPascal van Leeuwen * HW would not be faster on such small requests anyway. 2907a6061921SPascal van Leeuwen */ 2908a6061921SPascal van Leeuwen if (likely((ctx->aead != EIP197_AEAD_TYPE_IPSEC_ESP || 2909a6061921SPascal van Leeuwen req->assoclen >= EIP197_AEAD_IPSEC_IV_SIZE) && 2910a6061921SPascal van Leeuwen req->cryptlen > POLY1305_DIGEST_SIZE)) { 2911a6061921SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, dir); 2912a6061921SPascal van Leeuwen } 2913a6061921SPascal van Leeuwen 2914a6061921SPascal van Leeuwen /* HW cannot do full (AAD+payload) zero length, use fallback */ 291513a1bb93SPascal van Leeuwen memcpy(key, ctx->key, CHACHA_KEY_SIZE); 2916a6061921SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 2917a6061921SPascal van Leeuwen /* ESP variant has nonce appended to the key */ 2918a6061921SPascal van Leeuwen key[CHACHA_KEY_SIZE / sizeof(u32)] = ctx->nonce; 2919a6061921SPascal van Leeuwen ret = crypto_aead_setkey(ctx->fback, (u8 *)key, 2920a6061921SPascal van Leeuwen CHACHA_KEY_SIZE + 2921a6061921SPascal van Leeuwen EIP197_AEAD_IPSEC_NONCE_SIZE); 2922a6061921SPascal van Leeuwen } else { 2923a6061921SPascal van Leeuwen ret = crypto_aead_setkey(ctx->fback, (u8 *)key, 2924a6061921SPascal van Leeuwen CHACHA_KEY_SIZE); 2925a6061921SPascal van Leeuwen } 2926a6061921SPascal van Leeuwen if (ret) { 2927a6061921SPascal van Leeuwen crypto_aead_clear_flags(aead, CRYPTO_TFM_REQ_MASK); 2928a6061921SPascal van Leeuwen crypto_aead_set_flags(aead, crypto_aead_get_flags(ctx->fback) & 2929a6061921SPascal van Leeuwen CRYPTO_TFM_REQ_MASK); 2930a6061921SPascal van Leeuwen return ret; 2931a6061921SPascal van Leeuwen } 2932a6061921SPascal van Leeuwen 2933a6061921SPascal van Leeuwen aead_request_set_tfm(subreq, ctx->fback); 2934a6061921SPascal van Leeuwen aead_request_set_callback(subreq, req->base.flags, req->base.complete, 2935a6061921SPascal van Leeuwen req->base.data); 2936a6061921SPascal van Leeuwen aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 2937a6061921SPascal van Leeuwen req->iv); 2938a6061921SPascal van Leeuwen aead_request_set_ad(subreq, req->assoclen); 2939a6061921SPascal van Leeuwen 2940a6061921SPascal van Leeuwen return (dir == SAFEXCEL_ENCRYPT) ? 2941a6061921SPascal van Leeuwen crypto_aead_encrypt(subreq) : 2942a6061921SPascal van Leeuwen crypto_aead_decrypt(subreq); 2943a6061921SPascal van Leeuwen } 2944a6061921SPascal van Leeuwen 2945a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_encrypt(struct aead_request *req) 2946a6061921SPascal van Leeuwen { 2947a6061921SPascal van Leeuwen return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_ENCRYPT); 2948a6061921SPascal van Leeuwen } 2949a6061921SPascal van Leeuwen 2950a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_decrypt(struct aead_request *req) 2951a6061921SPascal van Leeuwen { 2952a6061921SPascal van Leeuwen return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_DECRYPT); 2953a6061921SPascal van Leeuwen } 2954a6061921SPascal van Leeuwen 29551769f704SPascal van Leeuwen static int safexcel_aead_fallback_cra_init(struct crypto_tfm *tfm) 2956a6061921SPascal van Leeuwen { 2957a6061921SPascal van Leeuwen struct crypto_aead *aead = __crypto_aead_cast(tfm); 2958a6061921SPascal van Leeuwen struct aead_alg *alg = crypto_aead_alg(aead); 2959a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2960a6061921SPascal van Leeuwen 2961a6061921SPascal van Leeuwen safexcel_aead_cra_init(tfm); 2962a6061921SPascal van Leeuwen 2963a6061921SPascal van Leeuwen /* Allocate fallback implementation */ 2964a6061921SPascal van Leeuwen ctx->fback = crypto_alloc_aead(alg->base.cra_name, 0, 2965a6061921SPascal van Leeuwen CRYPTO_ALG_ASYNC | 2966a6061921SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK); 2967a6061921SPascal van Leeuwen if (IS_ERR(ctx->fback)) 2968a6061921SPascal van Leeuwen return PTR_ERR(ctx->fback); 2969a6061921SPascal van Leeuwen 2970a6061921SPascal van Leeuwen crypto_aead_set_reqsize(aead, max(sizeof(struct safexcel_cipher_req), 2971a6061921SPascal van Leeuwen sizeof(struct aead_request) + 2972a6061921SPascal van Leeuwen crypto_aead_reqsize(ctx->fback))); 2973a6061921SPascal van Leeuwen 2974a6061921SPascal van Leeuwen return 0; 2975a6061921SPascal van Leeuwen } 2976a6061921SPascal van Leeuwen 29771769f704SPascal van Leeuwen static int safexcel_aead_chachapoly_cra_init(struct crypto_tfm *tfm) 29781769f704SPascal van Leeuwen { 29791769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 29801769f704SPascal van Leeuwen 29811769f704SPascal van Leeuwen safexcel_aead_fallback_cra_init(tfm); 29821769f704SPascal van Leeuwen ctx->alg = SAFEXCEL_CHACHA20; 29831769f704SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32 | 29841769f704SPascal van Leeuwen CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK; 2985098e51e5SPascal van Leeuwen ctx->ctrinit = 0; 29861769f704SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_POLY1305; 29871769f704SPascal van Leeuwen ctx->state_sz = 0; /* Precomputed by HW */ 29881769f704SPascal van Leeuwen return 0; 29891769f704SPascal van Leeuwen } 29901769f704SPascal van Leeuwen 29911769f704SPascal van Leeuwen static void safexcel_aead_fallback_cra_exit(struct crypto_tfm *tfm) 2992a6061921SPascal van Leeuwen { 2993a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2994a6061921SPascal van Leeuwen 2995a6061921SPascal van Leeuwen crypto_free_aead(ctx->fback); 2996a6061921SPascal van Leeuwen safexcel_aead_cra_exit(tfm); 2997a6061921SPascal van Leeuwen } 2998a6061921SPascal van Leeuwen 2999a6061921SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chachapoly = { 3000a6061921SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3001a6061921SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, 3002a6061921SPascal van Leeuwen .alg.aead = { 3003a6061921SPascal van Leeuwen .setkey = safexcel_aead_chachapoly_setkey, 3004a6061921SPascal van Leeuwen .setauthsize = safexcel_aead_chachapoly_setauthsize, 3005a6061921SPascal van Leeuwen .encrypt = safexcel_aead_chachapoly_encrypt, 3006a6061921SPascal van Leeuwen .decrypt = safexcel_aead_chachapoly_decrypt, 3007a6061921SPascal van Leeuwen .ivsize = CHACHAPOLY_IV_SIZE, 3008a6061921SPascal van Leeuwen .maxauthsize = POLY1305_DIGEST_SIZE, 3009a6061921SPascal van Leeuwen .base = { 3010a6061921SPascal van Leeuwen .cra_name = "rfc7539(chacha20,poly1305)", 3011a6061921SPascal van Leeuwen .cra_driver_name = "safexcel-chacha20-poly1305", 3012a6061921SPascal van Leeuwen /* +1 to put it above HW chacha + SW poly */ 3013a6061921SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, 3014a6061921SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3015a6061921SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY | 3016a6061921SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK, 3017a6061921SPascal van Leeuwen .cra_blocksize = 1, 3018a6061921SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3019a6061921SPascal van Leeuwen .cra_alignmask = 0, 3020a6061921SPascal van Leeuwen .cra_init = safexcel_aead_chachapoly_cra_init, 30211769f704SPascal van Leeuwen .cra_exit = safexcel_aead_fallback_cra_exit, 3022a6061921SPascal van Leeuwen .cra_module = THIS_MODULE, 3023a6061921SPascal van Leeuwen }, 3024a6061921SPascal van Leeuwen }, 3025a6061921SPascal van Leeuwen }; 3026a6061921SPascal van Leeuwen 3027a6061921SPascal van Leeuwen static int safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm *tfm) 3028a6061921SPascal van Leeuwen { 3029a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3030a6061921SPascal van Leeuwen int ret; 3031a6061921SPascal van Leeuwen 3032a6061921SPascal van Leeuwen ret = safexcel_aead_chachapoly_cra_init(tfm); 3033a6061921SPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 3034098e51e5SPascal van Leeuwen ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 3035a6061921SPascal van Leeuwen return ret; 3036a6061921SPascal van Leeuwen } 3037a6061921SPascal van Leeuwen 3038a6061921SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chachapoly_esp = { 3039a6061921SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3040a6061921SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, 3041a6061921SPascal van Leeuwen .alg.aead = { 3042a6061921SPascal van Leeuwen .setkey = safexcel_aead_chachapoly_setkey, 3043a6061921SPascal van Leeuwen .setauthsize = safexcel_aead_chachapoly_setauthsize, 3044a6061921SPascal van Leeuwen .encrypt = safexcel_aead_chachapoly_encrypt, 3045a6061921SPascal van Leeuwen .decrypt = safexcel_aead_chachapoly_decrypt, 3046a6061921SPascal van Leeuwen .ivsize = CHACHAPOLY_IV_SIZE - EIP197_AEAD_IPSEC_NONCE_SIZE, 3047a6061921SPascal van Leeuwen .maxauthsize = POLY1305_DIGEST_SIZE, 3048a6061921SPascal van Leeuwen .base = { 3049a6061921SPascal van Leeuwen .cra_name = "rfc7539esp(chacha20,poly1305)", 3050a6061921SPascal van Leeuwen .cra_driver_name = "safexcel-chacha20-poly1305-esp", 3051a6061921SPascal van Leeuwen /* +1 to put it above HW chacha + SW poly */ 3052a6061921SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, 3053a6061921SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3054a6061921SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY | 3055a6061921SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK, 3056a6061921SPascal van Leeuwen .cra_blocksize = 1, 3057a6061921SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3058a6061921SPascal van Leeuwen .cra_alignmask = 0, 3059a6061921SPascal van Leeuwen .cra_init = safexcel_aead_chachapolyesp_cra_init, 30601769f704SPascal van Leeuwen .cra_exit = safexcel_aead_fallback_cra_exit, 3061a6061921SPascal van Leeuwen .cra_module = THIS_MODULE, 3062a6061921SPascal van Leeuwen }, 3063a6061921SPascal van Leeuwen }, 3064a6061921SPascal van Leeuwen }; 3065fcca797dSPascal van Leeuwen 3066fcca797dSPascal van Leeuwen static int safexcel_skcipher_sm4_setkey(struct crypto_skcipher *ctfm, 3067fcca797dSPascal van Leeuwen const u8 *key, unsigned int len) 3068fcca797dSPascal van Leeuwen { 3069fcca797dSPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 3070fcca797dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3071fcca797dSPascal van Leeuwen struct safexcel_crypto_priv *priv = ctx->priv; 3072fcca797dSPascal van Leeuwen 3073fcca797dSPascal van Leeuwen if (len != SM4_KEY_SIZE) { 3074fcca797dSPascal van Leeuwen crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 3075fcca797dSPascal van Leeuwen return -EINVAL; 3076fcca797dSPascal van Leeuwen } 3077fcca797dSPascal van Leeuwen 307813a1bb93SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 307913a1bb93SPascal van Leeuwen if (memcmp(ctx->key, key, SM4_KEY_SIZE)) 3080fcca797dSPascal van Leeuwen ctx->base.needs_inv = true; 3081fcca797dSPascal van Leeuwen 308213a1bb93SPascal van Leeuwen memcpy(ctx->key, key, SM4_KEY_SIZE); 3083fcca797dSPascal van Leeuwen ctx->key_len = SM4_KEY_SIZE; 3084fcca797dSPascal van Leeuwen 3085fcca797dSPascal van Leeuwen return 0; 3086fcca797dSPascal van Leeuwen } 3087fcca797dSPascal van Leeuwen 3088fcca797dSPascal van Leeuwen static int safexcel_sm4_blk_encrypt(struct skcipher_request *req) 3089fcca797dSPascal van Leeuwen { 3090fcca797dSPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 3091fcca797dSPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 3092fcca797dSPascal van Leeuwen return -EINVAL; 3093fcca797dSPascal van Leeuwen else 3094fcca797dSPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 3095fcca797dSPascal van Leeuwen SAFEXCEL_ENCRYPT); 3096fcca797dSPascal van Leeuwen } 3097fcca797dSPascal van Leeuwen 3098fcca797dSPascal van Leeuwen static int safexcel_sm4_blk_decrypt(struct skcipher_request *req) 3099fcca797dSPascal van Leeuwen { 3100fcca797dSPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 3101fcca797dSPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 3102fcca797dSPascal van Leeuwen return -EINVAL; 3103fcca797dSPascal van Leeuwen else 3104fcca797dSPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 3105fcca797dSPascal van Leeuwen SAFEXCEL_DECRYPT); 3106fcca797dSPascal van Leeuwen } 3107fcca797dSPascal van Leeuwen 3108fcca797dSPascal van Leeuwen static int safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm *tfm) 3109fcca797dSPascal van Leeuwen { 3110fcca797dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3111fcca797dSPascal van Leeuwen 3112fcca797dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 3113fcca797dSPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3114fcca797dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 3115098e51e5SPascal van Leeuwen ctx->blocksz = 0; 3116098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 3117fcca797dSPascal van Leeuwen return 0; 3118fcca797dSPascal van Leeuwen } 3119fcca797dSPascal van Leeuwen 3120fcca797dSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ecb_sm4 = { 3121fcca797dSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 3122fcca797dSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4, 3123fcca797dSPascal van Leeuwen .alg.skcipher = { 3124fcca797dSPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 3125fcca797dSPascal van Leeuwen .encrypt = safexcel_sm4_blk_encrypt, 3126fcca797dSPascal van Leeuwen .decrypt = safexcel_sm4_blk_decrypt, 3127fcca797dSPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 3128fcca797dSPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 3129fcca797dSPascal van Leeuwen .base = { 3130fcca797dSPascal van Leeuwen .cra_name = "ecb(sm4)", 3131fcca797dSPascal van Leeuwen .cra_driver_name = "safexcel-ecb-sm4", 3132fcca797dSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3133fcca797dSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3134fcca797dSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3135fcca797dSPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 3136fcca797dSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3137fcca797dSPascal van Leeuwen .cra_alignmask = 0, 3138fcca797dSPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_ecb_cra_init, 3139fcca797dSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 3140fcca797dSPascal van Leeuwen .cra_module = THIS_MODULE, 3141fcca797dSPascal van Leeuwen }, 3142fcca797dSPascal van Leeuwen }, 3143fcca797dSPascal van Leeuwen }; 31446f2d1428SPascal van Leeuwen 31456f2d1428SPascal van Leeuwen static int safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm *tfm) 31466f2d1428SPascal van Leeuwen { 31476f2d1428SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 31486f2d1428SPascal van Leeuwen 31496f2d1428SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 31506f2d1428SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3151098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 31526f2d1428SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 31536f2d1428SPascal van Leeuwen return 0; 31546f2d1428SPascal van Leeuwen } 31556f2d1428SPascal van Leeuwen 31566f2d1428SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cbc_sm4 = { 31576f2d1428SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 31586f2d1428SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4, 31596f2d1428SPascal van Leeuwen .alg.skcipher = { 31606f2d1428SPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 31616f2d1428SPascal van Leeuwen .encrypt = safexcel_sm4_blk_encrypt, 31626f2d1428SPascal van Leeuwen .decrypt = safexcel_sm4_blk_decrypt, 31636f2d1428SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 31646f2d1428SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 31656f2d1428SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 31666f2d1428SPascal van Leeuwen .base = { 31676f2d1428SPascal van Leeuwen .cra_name = "cbc(sm4)", 31686f2d1428SPascal van Leeuwen .cra_driver_name = "safexcel-cbc-sm4", 31696f2d1428SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 31706f2d1428SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 31716f2d1428SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 31726f2d1428SPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 31736f2d1428SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 31746f2d1428SPascal van Leeuwen .cra_alignmask = 0, 31756f2d1428SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_cbc_cra_init, 31766f2d1428SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 31776f2d1428SPascal van Leeuwen .cra_module = THIS_MODULE, 31786f2d1428SPascal van Leeuwen }, 31796f2d1428SPascal van Leeuwen }, 31806f2d1428SPascal van Leeuwen }; 318103a6cfb9SPascal van Leeuwen 318203a6cfb9SPascal van Leeuwen static int safexcel_skcipher_sm4_ofb_cra_init(struct crypto_tfm *tfm) 318303a6cfb9SPascal van Leeuwen { 318403a6cfb9SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 318503a6cfb9SPascal van Leeuwen 318603a6cfb9SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 318703a6cfb9SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3188098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 318903a6cfb9SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; 319003a6cfb9SPascal van Leeuwen return 0; 319103a6cfb9SPascal van Leeuwen } 319203a6cfb9SPascal van Leeuwen 319303a6cfb9SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ofb_sm4 = { 319403a6cfb9SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 319503a6cfb9SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, 319603a6cfb9SPascal van Leeuwen .alg.skcipher = { 319703a6cfb9SPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 319803a6cfb9SPascal van Leeuwen .encrypt = safexcel_encrypt, 319903a6cfb9SPascal van Leeuwen .decrypt = safexcel_decrypt, 320003a6cfb9SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 320103a6cfb9SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 320203a6cfb9SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 320303a6cfb9SPascal van Leeuwen .base = { 320403a6cfb9SPascal van Leeuwen .cra_name = "ofb(sm4)", 320503a6cfb9SPascal van Leeuwen .cra_driver_name = "safexcel-ofb-sm4", 320603a6cfb9SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 320703a6cfb9SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 320803a6cfb9SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 320903a6cfb9SPascal van Leeuwen .cra_blocksize = 1, 321003a6cfb9SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 321103a6cfb9SPascal van Leeuwen .cra_alignmask = 0, 321203a6cfb9SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_ofb_cra_init, 321303a6cfb9SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 321403a6cfb9SPascal van Leeuwen .cra_module = THIS_MODULE, 321503a6cfb9SPascal van Leeuwen }, 321603a6cfb9SPascal van Leeuwen }, 321703a6cfb9SPascal van Leeuwen }; 32187468ab22SPascal van Leeuwen 32197468ab22SPascal van Leeuwen static int safexcel_skcipher_sm4_cfb_cra_init(struct crypto_tfm *tfm) 32207468ab22SPascal van Leeuwen { 32217468ab22SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 32227468ab22SPascal van Leeuwen 32237468ab22SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 32247468ab22SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3225098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 32267468ab22SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; 32277468ab22SPascal van Leeuwen return 0; 32287468ab22SPascal van Leeuwen } 32297468ab22SPascal van Leeuwen 32307468ab22SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cfb_sm4 = { 32317468ab22SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 32327468ab22SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, 32337468ab22SPascal van Leeuwen .alg.skcipher = { 32347468ab22SPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 32357468ab22SPascal van Leeuwen .encrypt = safexcel_encrypt, 32367468ab22SPascal van Leeuwen .decrypt = safexcel_decrypt, 32377468ab22SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 32387468ab22SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 32397468ab22SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 32407468ab22SPascal van Leeuwen .base = { 32417468ab22SPascal van Leeuwen .cra_name = "cfb(sm4)", 32427468ab22SPascal van Leeuwen .cra_driver_name = "safexcel-cfb-sm4", 32437468ab22SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 32447468ab22SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 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 | 3297f77e5dc0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3298f77e5dc0SPascal van Leeuwen .cra_blocksize = 1, 3299f77e5dc0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3300f77e5dc0SPascal van Leeuwen .cra_alignmask = 0, 3301f77e5dc0SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_ctr_cra_init, 3302f77e5dc0SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 3303f77e5dc0SPascal van Leeuwen .cra_module = THIS_MODULE, 3304f77e5dc0SPascal van Leeuwen }, 3305f77e5dc0SPascal van Leeuwen }, 3306f77e5dc0SPascal van Leeuwen }; 33071769f704SPascal van Leeuwen 33081769f704SPascal van Leeuwen static int safexcel_aead_sm4_blk_encrypt(struct aead_request *req) 33091769f704SPascal van Leeuwen { 33101769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 33111769f704SPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 33121769f704SPascal van Leeuwen return -EINVAL; 33131769f704SPascal van Leeuwen 33141769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, aead_request_ctx(req), 33151769f704SPascal van Leeuwen SAFEXCEL_ENCRYPT); 33161769f704SPascal van Leeuwen } 33171769f704SPascal van Leeuwen 33181769f704SPascal van Leeuwen static int safexcel_aead_sm4_blk_decrypt(struct aead_request *req) 33191769f704SPascal van Leeuwen { 33201769f704SPascal van Leeuwen struct crypto_aead *tfm = crypto_aead_reqtfm(req); 33211769f704SPascal van Leeuwen 33221769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 33231769f704SPascal van Leeuwen if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) 33241769f704SPascal van Leeuwen return -EINVAL; 33251769f704SPascal van Leeuwen 33261769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, aead_request_ctx(req), 33271769f704SPascal van Leeuwen SAFEXCEL_DECRYPT); 33281769f704SPascal van Leeuwen } 33291769f704SPascal van Leeuwen 33301769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sha1_cra_init(struct crypto_tfm *tfm) 33311769f704SPascal van Leeuwen { 33321769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33331769f704SPascal van Leeuwen 33341769f704SPascal van Leeuwen safexcel_aead_cra_init(tfm); 33351769f704SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3336098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 33371769f704SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; 33381769f704SPascal van Leeuwen ctx->state_sz = SHA1_DIGEST_SIZE; 33391769f704SPascal van Leeuwen return 0; 33401769f704SPascal van Leeuwen } 33411769f704SPascal van Leeuwen 33421769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4 = { 33431769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 33441769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, 33451769f704SPascal van Leeuwen .alg.aead = { 33461769f704SPascal van Leeuwen .setkey = safexcel_aead_setkey, 33471769f704SPascal van Leeuwen .encrypt = safexcel_aead_sm4_blk_encrypt, 33481769f704SPascal van Leeuwen .decrypt = safexcel_aead_sm4_blk_decrypt, 33491769f704SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 33501769f704SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 33511769f704SPascal van Leeuwen .base = { 33521769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),cbc(sm4))", 33531769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-sm4", 33541769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 33551769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 33561769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 33571769f704SPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 33581769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 33591769f704SPascal van Leeuwen .cra_alignmask = 0, 33601769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4cbc_sha1_cra_init, 33611769f704SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 33621769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 33631769f704SPascal van Leeuwen }, 33641769f704SPascal van Leeuwen }, 33651769f704SPascal van Leeuwen }; 33661769f704SPascal van Leeuwen 33671769f704SPascal van Leeuwen static int safexcel_aead_fallback_setkey(struct crypto_aead *ctfm, 33681769f704SPascal van Leeuwen const u8 *key, unsigned int len) 33691769f704SPascal van Leeuwen { 33701769f704SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 33711769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33721769f704SPascal van Leeuwen 33731769f704SPascal van Leeuwen /* Keep fallback cipher synchronized */ 33741769f704SPascal van Leeuwen return crypto_aead_setkey(ctx->fback, (u8 *)key, len) ?: 33751769f704SPascal van Leeuwen safexcel_aead_setkey(ctfm, key, len); 33761769f704SPascal van Leeuwen } 33771769f704SPascal van Leeuwen 33781769f704SPascal van Leeuwen static int safexcel_aead_fallback_setauthsize(struct crypto_aead *ctfm, 33791769f704SPascal van Leeuwen unsigned int authsize) 33801769f704SPascal van Leeuwen { 33811769f704SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 33821769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33831769f704SPascal van Leeuwen 33841769f704SPascal van Leeuwen /* Keep fallback cipher synchronized */ 33851769f704SPascal van Leeuwen return crypto_aead_setauthsize(ctx->fback, authsize); 33861769f704SPascal van Leeuwen } 33871769f704SPascal van Leeuwen 33881769f704SPascal van Leeuwen static int safexcel_aead_fallback_crypt(struct aead_request *req, 33891769f704SPascal van Leeuwen enum safexcel_cipher_direction dir) 33901769f704SPascal van Leeuwen { 33911769f704SPascal van Leeuwen struct crypto_aead *aead = crypto_aead_reqtfm(req); 33921769f704SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(aead); 33931769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33941769f704SPascal van Leeuwen struct aead_request *subreq = aead_request_ctx(req); 33951769f704SPascal van Leeuwen 33961769f704SPascal van Leeuwen aead_request_set_tfm(subreq, ctx->fback); 33971769f704SPascal van Leeuwen aead_request_set_callback(subreq, req->base.flags, req->base.complete, 33981769f704SPascal van Leeuwen req->base.data); 33991769f704SPascal van Leeuwen aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 34001769f704SPascal van Leeuwen req->iv); 34011769f704SPascal van Leeuwen aead_request_set_ad(subreq, req->assoclen); 34021769f704SPascal van Leeuwen 34031769f704SPascal van Leeuwen return (dir == SAFEXCEL_ENCRYPT) ? 34041769f704SPascal van Leeuwen crypto_aead_encrypt(subreq) : 34051769f704SPascal van Leeuwen crypto_aead_decrypt(subreq); 34061769f704SPascal van Leeuwen } 34071769f704SPascal van Leeuwen 34081769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request *req) 34091769f704SPascal van Leeuwen { 34101769f704SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 34111769f704SPascal van Leeuwen 34121769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 34131769f704SPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 34141769f704SPascal van Leeuwen return -EINVAL; 34151769f704SPascal van Leeuwen else if (req->cryptlen || req->assoclen) /* If input length > 0 only */ 34161769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 34171769f704SPascal van Leeuwen 34181769f704SPascal van Leeuwen /* HW cannot do full (AAD+payload) zero length, use fallback */ 34191769f704SPascal van Leeuwen return safexcel_aead_fallback_crypt(req, SAFEXCEL_ENCRYPT); 34201769f704SPascal van Leeuwen } 34211769f704SPascal van Leeuwen 34221769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request *req) 34231769f704SPascal van Leeuwen { 34241769f704SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 34251769f704SPascal van Leeuwen struct crypto_aead *tfm = crypto_aead_reqtfm(req); 34261769f704SPascal van Leeuwen 34271769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 34281769f704SPascal van Leeuwen if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) 34291769f704SPascal van Leeuwen return -EINVAL; 34301769f704SPascal van Leeuwen else if (req->cryptlen > crypto_aead_authsize(tfm) || req->assoclen) 34311769f704SPascal van Leeuwen /* If input length > 0 only */ 34321769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 34331769f704SPascal van Leeuwen 34341769f704SPascal van Leeuwen /* HW cannot do full (AAD+payload) zero length, use fallback */ 34351769f704SPascal van Leeuwen return safexcel_aead_fallback_crypt(req, SAFEXCEL_DECRYPT); 34361769f704SPascal van Leeuwen } 34371769f704SPascal van Leeuwen 34381769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm *tfm) 34391769f704SPascal van Leeuwen { 34401769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 34411769f704SPascal van Leeuwen 34421769f704SPascal van Leeuwen safexcel_aead_fallback_cra_init(tfm); 34431769f704SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3444098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 34451769f704SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3; 34461769f704SPascal van Leeuwen ctx->state_sz = SM3_DIGEST_SIZE; 34471769f704SPascal van Leeuwen return 0; 34481769f704SPascal van Leeuwen } 34491769f704SPascal van Leeuwen 34501769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4 = { 34511769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 34521769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, 34531769f704SPascal van Leeuwen .alg.aead = { 34541769f704SPascal van Leeuwen .setkey = safexcel_aead_fallback_setkey, 34551769f704SPascal van Leeuwen .setauthsize = safexcel_aead_fallback_setauthsize, 34561769f704SPascal van Leeuwen .encrypt = safexcel_aead_sm4cbc_sm3_encrypt, 34571769f704SPascal van Leeuwen .decrypt = safexcel_aead_sm4cbc_sm3_decrypt, 34581769f704SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 34591769f704SPascal van Leeuwen .maxauthsize = SM3_DIGEST_SIZE, 34601769f704SPascal van Leeuwen .base = { 34611769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sm3),cbc(sm4))", 34621769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sm3-cbc-sm4", 34631769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 34641769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 34651769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY | 34661769f704SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK, 34671769f704SPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 34681769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 34691769f704SPascal van Leeuwen .cra_alignmask = 0, 34701769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4cbc_sm3_cra_init, 34711769f704SPascal van Leeuwen .cra_exit = safexcel_aead_fallback_cra_exit, 34721769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 34731769f704SPascal van Leeuwen }, 34741769f704SPascal van Leeuwen }, 34751769f704SPascal van Leeuwen }; 34761769f704SPascal van Leeuwen 34771769f704SPascal van Leeuwen static int safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm *tfm) 34781769f704SPascal van Leeuwen { 34791769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 34801769f704SPascal van Leeuwen 34811769f704SPascal van Leeuwen safexcel_aead_sm4cbc_sha1_cra_init(tfm); 34821769f704SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 34831769f704SPascal van Leeuwen return 0; 34841769f704SPascal van Leeuwen } 34851769f704SPascal van Leeuwen 34861769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4 = { 34871769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 34881769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, 34891769f704SPascal van Leeuwen .alg.aead = { 34901769f704SPascal van Leeuwen .setkey = safexcel_aead_setkey, 34911769f704SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 34921769f704SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 34931769f704SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 34941769f704SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 34951769f704SPascal van Leeuwen .base = { 34961769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),rfc3686(ctr(sm4)))", 34971769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-sm4", 34981769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 34991769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 35001769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 35011769f704SPascal van Leeuwen .cra_blocksize = 1, 35021769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 35031769f704SPascal van Leeuwen .cra_alignmask = 0, 35041769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4ctr_sha1_cra_init, 35051769f704SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 35061769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 35071769f704SPascal van Leeuwen }, 35081769f704SPascal van Leeuwen }, 35091769f704SPascal van Leeuwen }; 35101769f704SPascal van Leeuwen 35111769f704SPascal van Leeuwen static int safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm *tfm) 35121769f704SPascal van Leeuwen { 35131769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 35141769f704SPascal van Leeuwen 35151769f704SPascal van Leeuwen safexcel_aead_sm4cbc_sm3_cra_init(tfm); 35161769f704SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 35171769f704SPascal van Leeuwen return 0; 35181769f704SPascal van Leeuwen } 35191769f704SPascal van Leeuwen 35201769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4 = { 35211769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 35221769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, 35231769f704SPascal van Leeuwen .alg.aead = { 35241769f704SPascal van Leeuwen .setkey = safexcel_aead_setkey, 35251769f704SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 35261769f704SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 35271769f704SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 35281769f704SPascal van Leeuwen .maxauthsize = SM3_DIGEST_SIZE, 35291769f704SPascal van Leeuwen .base = { 35301769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sm3),rfc3686(ctr(sm4)))", 35311769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sm3-ctr-sm4", 35321769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 35331769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 35341769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 35351769f704SPascal van Leeuwen .cra_blocksize = 1, 35361769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 35371769f704SPascal van Leeuwen .cra_alignmask = 0, 35381769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4ctr_sm3_cra_init, 35391769f704SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 35401769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 35411769f704SPascal van Leeuwen }, 35421769f704SPascal van Leeuwen }, 35431769f704SPascal van Leeuwen }; 3544a19052d4SPascal van Leeuwen 3545a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, 3546a19052d4SPascal van Leeuwen unsigned int len) 3547a19052d4SPascal van Leeuwen { 3548a19052d4SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 3549a19052d4SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3550a19052d4SPascal van Leeuwen 3551a19052d4SPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 3552a19052d4SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 3553a19052d4SPascal van Leeuwen 3554a19052d4SPascal van Leeuwen len -= CTR_RFC3686_NONCE_SIZE; 3555a19052d4SPascal van Leeuwen return safexcel_aead_gcm_setkey(ctfm, key, len); 3556a19052d4SPascal van Leeuwen } 3557a19052d4SPascal van Leeuwen 3558a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_setauthsize(struct crypto_aead *tfm, 3559a19052d4SPascal van Leeuwen unsigned int authsize) 3560a19052d4SPascal van Leeuwen { 3561a19052d4SPascal van Leeuwen return crypto_rfc4106_check_authsize(authsize); 3562a19052d4SPascal van Leeuwen } 3563a19052d4SPascal van Leeuwen 3564a19052d4SPascal van Leeuwen static int safexcel_rfc4106_encrypt(struct aead_request *req) 3565a19052d4SPascal van Leeuwen { 3566a19052d4SPascal van Leeuwen return crypto_ipsec_check_assoclen(req->assoclen) ?: 3567a19052d4SPascal van Leeuwen safexcel_aead_encrypt(req); 3568a19052d4SPascal van Leeuwen } 3569a19052d4SPascal van Leeuwen 3570a19052d4SPascal van Leeuwen static int safexcel_rfc4106_decrypt(struct aead_request *req) 3571a19052d4SPascal van Leeuwen { 3572a19052d4SPascal van Leeuwen return crypto_ipsec_check_assoclen(req->assoclen) ?: 3573a19052d4SPascal van Leeuwen safexcel_aead_decrypt(req); 3574a19052d4SPascal van Leeuwen } 3575a19052d4SPascal van Leeuwen 3576a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_cra_init(struct crypto_tfm *tfm) 3577a19052d4SPascal van Leeuwen { 3578a19052d4SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3579a19052d4SPascal van Leeuwen int ret; 3580a19052d4SPascal van Leeuwen 3581a19052d4SPascal van Leeuwen ret = safexcel_aead_gcm_cra_init(tfm); 3582a19052d4SPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 3583098e51e5SPascal van Leeuwen ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 3584a19052d4SPascal van Leeuwen return ret; 3585a19052d4SPascal van Leeuwen } 3586a19052d4SPascal van Leeuwen 3587a19052d4SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4106_gcm = { 3588a19052d4SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3589a19052d4SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 3590a19052d4SPascal van Leeuwen .alg.aead = { 3591a19052d4SPascal van Leeuwen .setkey = safexcel_rfc4106_gcm_setkey, 3592a19052d4SPascal van Leeuwen .setauthsize = safexcel_rfc4106_gcm_setauthsize, 3593a19052d4SPascal van Leeuwen .encrypt = safexcel_rfc4106_encrypt, 3594a19052d4SPascal van Leeuwen .decrypt = safexcel_rfc4106_decrypt, 3595a19052d4SPascal van Leeuwen .ivsize = GCM_RFC4106_IV_SIZE, 3596a19052d4SPascal van Leeuwen .maxauthsize = GHASH_DIGEST_SIZE, 3597a19052d4SPascal van Leeuwen .base = { 3598a19052d4SPascal van Leeuwen .cra_name = "rfc4106(gcm(aes))", 3599a19052d4SPascal van Leeuwen .cra_driver_name = "safexcel-rfc4106-gcm-aes", 3600a19052d4SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3601a19052d4SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3602a19052d4SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3603a19052d4SPascal van Leeuwen .cra_blocksize = 1, 3604a19052d4SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3605a19052d4SPascal van Leeuwen .cra_alignmask = 0, 3606a19052d4SPascal van Leeuwen .cra_init = safexcel_rfc4106_gcm_cra_init, 3607a19052d4SPascal van Leeuwen .cra_exit = safexcel_aead_gcm_cra_exit, 3608a19052d4SPascal van Leeuwen }, 3609a19052d4SPascal van Leeuwen }, 3610a19052d4SPascal van Leeuwen }; 361192c60cefSPascal van Leeuwen 361292c60cefSPascal van Leeuwen static int safexcel_rfc4543_gcm_setauthsize(struct crypto_aead *tfm, 361392c60cefSPascal van Leeuwen unsigned int authsize) 361492c60cefSPascal van Leeuwen { 361592c60cefSPascal van Leeuwen if (authsize != GHASH_DIGEST_SIZE) 361692c60cefSPascal van Leeuwen return -EINVAL; 361792c60cefSPascal van Leeuwen 361892c60cefSPascal van Leeuwen return 0; 361992c60cefSPascal van Leeuwen } 362092c60cefSPascal van Leeuwen 362192c60cefSPascal van Leeuwen static int safexcel_rfc4543_gcm_cra_init(struct crypto_tfm *tfm) 362292c60cefSPascal van Leeuwen { 362392c60cefSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 362492c60cefSPascal van Leeuwen int ret; 362592c60cefSPascal van Leeuwen 362692c60cefSPascal van Leeuwen ret = safexcel_aead_gcm_cra_init(tfm); 362792c60cefSPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP_GMAC; 362892c60cefSPascal van Leeuwen return ret; 362992c60cefSPascal van Leeuwen } 363092c60cefSPascal van Leeuwen 363192c60cefSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4543_gcm = { 363292c60cefSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 363392c60cefSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 363492c60cefSPascal van Leeuwen .alg.aead = { 363592c60cefSPascal van Leeuwen .setkey = safexcel_rfc4106_gcm_setkey, 363692c60cefSPascal van Leeuwen .setauthsize = safexcel_rfc4543_gcm_setauthsize, 363792c60cefSPascal van Leeuwen .encrypt = safexcel_rfc4106_encrypt, 363892c60cefSPascal van Leeuwen .decrypt = safexcel_rfc4106_decrypt, 363992c60cefSPascal van Leeuwen .ivsize = GCM_RFC4543_IV_SIZE, 364092c60cefSPascal van Leeuwen .maxauthsize = GHASH_DIGEST_SIZE, 364192c60cefSPascal van Leeuwen .base = { 364292c60cefSPascal van Leeuwen .cra_name = "rfc4543(gcm(aes))", 364392c60cefSPascal van Leeuwen .cra_driver_name = "safexcel-rfc4543-gcm-aes", 364492c60cefSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 364592c60cefSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 364692c60cefSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 364792c60cefSPascal van Leeuwen .cra_blocksize = 1, 364892c60cefSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 364992c60cefSPascal van Leeuwen .cra_alignmask = 0, 365092c60cefSPascal van Leeuwen .cra_init = safexcel_rfc4543_gcm_cra_init, 365192c60cefSPascal van Leeuwen .cra_exit = safexcel_aead_gcm_cra_exit, 365292c60cefSPascal van Leeuwen }, 365392c60cefSPascal van Leeuwen }, 365492c60cefSPascal van Leeuwen }; 3655a9a89624SPascal van Leeuwen 3656a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, 3657a9a89624SPascal van Leeuwen unsigned int len) 3658a9a89624SPascal van Leeuwen { 3659a9a89624SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 3660a9a89624SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3661a9a89624SPascal van Leeuwen 3662a9a89624SPascal van Leeuwen /* First byte of the nonce = L = always 3 for RFC4309 (4 byte ctr) */ 3663a9a89624SPascal van Leeuwen *(u8 *)&ctx->nonce = EIP197_AEAD_IPSEC_COUNTER_SIZE - 1; 3664a9a89624SPascal van Leeuwen /* last 3 bytes of key are the nonce! */ 3665a9a89624SPascal van Leeuwen memcpy((u8 *)&ctx->nonce + 1, key + len - 3666a9a89624SPascal van Leeuwen EIP197_AEAD_IPSEC_CCM_NONCE_SIZE, 3667a9a89624SPascal van Leeuwen EIP197_AEAD_IPSEC_CCM_NONCE_SIZE); 3668a9a89624SPascal van Leeuwen 3669a9a89624SPascal van Leeuwen len -= EIP197_AEAD_IPSEC_CCM_NONCE_SIZE; 3670a9a89624SPascal van Leeuwen return safexcel_aead_ccm_setkey(ctfm, key, len); 3671a9a89624SPascal van Leeuwen } 3672a9a89624SPascal van Leeuwen 3673a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_setauthsize(struct crypto_aead *tfm, 3674a9a89624SPascal van Leeuwen unsigned int authsize) 3675a9a89624SPascal van Leeuwen { 3676a9a89624SPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 3677a9a89624SPascal van Leeuwen switch (authsize) { 3678a9a89624SPascal van Leeuwen case 8: 3679a9a89624SPascal van Leeuwen case 12: 3680a9a89624SPascal van Leeuwen case 16: 3681a9a89624SPascal van Leeuwen break; 3682a9a89624SPascal van Leeuwen default: 3683a9a89624SPascal van Leeuwen return -EINVAL; 3684a9a89624SPascal van Leeuwen } 3685a9a89624SPascal van Leeuwen 3686a9a89624SPascal van Leeuwen return 0; 3687a9a89624SPascal van Leeuwen } 3688a9a89624SPascal van Leeuwen 3689a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_encrypt(struct aead_request *req) 3690a9a89624SPascal van Leeuwen { 3691a9a89624SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 3692a9a89624SPascal van Leeuwen 3693a9a89624SPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 3694a9a89624SPascal van Leeuwen if (req->assoclen != 16 && req->assoclen != 20) 3695a9a89624SPascal van Leeuwen return -EINVAL; 3696a9a89624SPascal van Leeuwen 3697a9a89624SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 3698a9a89624SPascal van Leeuwen } 3699a9a89624SPascal van Leeuwen 3700a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_decrypt(struct aead_request *req) 3701a9a89624SPascal van Leeuwen { 3702a9a89624SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 3703a9a89624SPascal van Leeuwen 3704a9a89624SPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 3705a9a89624SPascal van Leeuwen if (req->assoclen != 16 && req->assoclen != 20) 3706a9a89624SPascal van Leeuwen return -EINVAL; 3707a9a89624SPascal van Leeuwen 3708a9a89624SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 3709a9a89624SPascal van Leeuwen } 3710a9a89624SPascal van Leeuwen 3711a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_cra_init(struct crypto_tfm *tfm) 3712a9a89624SPascal van Leeuwen { 3713a9a89624SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3714a9a89624SPascal van Leeuwen int ret; 3715a9a89624SPascal van Leeuwen 3716a9a89624SPascal van Leeuwen ret = safexcel_aead_ccm_cra_init(tfm); 3717a9a89624SPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 3718098e51e5SPascal van Leeuwen ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 3719a9a89624SPascal van Leeuwen return ret; 3720a9a89624SPascal van Leeuwen } 3721a9a89624SPascal van Leeuwen 3722a9a89624SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4309_ccm = { 3723a9a89624SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3724a9a89624SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, 3725a9a89624SPascal van Leeuwen .alg.aead = { 3726a9a89624SPascal van Leeuwen .setkey = safexcel_rfc4309_ccm_setkey, 3727a9a89624SPascal van Leeuwen .setauthsize = safexcel_rfc4309_ccm_setauthsize, 3728a9a89624SPascal van Leeuwen .encrypt = safexcel_rfc4309_ccm_encrypt, 3729a9a89624SPascal van Leeuwen .decrypt = safexcel_rfc4309_ccm_decrypt, 3730a9a89624SPascal van Leeuwen .ivsize = EIP197_AEAD_IPSEC_IV_SIZE, 3731a9a89624SPascal van Leeuwen .maxauthsize = AES_BLOCK_SIZE, 3732a9a89624SPascal van Leeuwen .base = { 3733a9a89624SPascal van Leeuwen .cra_name = "rfc4309(ccm(aes))", 3734a9a89624SPascal van Leeuwen .cra_driver_name = "safexcel-rfc4309-ccm-aes", 3735a9a89624SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3736a9a89624SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3737a9a89624SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3738a9a89624SPascal van Leeuwen .cra_blocksize = 1, 3739a9a89624SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3740a9a89624SPascal van Leeuwen .cra_alignmask = 0, 3741a9a89624SPascal van Leeuwen .cra_init = safexcel_rfc4309_ccm_cra_init, 3742a9a89624SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 3743a9a89624SPascal van Leeuwen .cra_module = THIS_MODULE, 3744a9a89624SPascal van Leeuwen }, 3745a9a89624SPascal van Leeuwen }, 3746a9a89624SPascal van Leeuwen }; 3747