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> 21a24d22b2SEric Biggers #include <crypto/sha1.h> 22a24d22b2SEric Biggers #include <crypto/sha2.h> 231769f704SPascal van Leeuwen #include <crypto/sm3.h> 24fcca797dSPascal van Leeuwen #include <crypto/sm4.h> 25c7da38a7SPascal van Leeuwen #include <crypto/xts.h> 261b44c5a6SAntoine Ténart #include <crypto/skcipher.h> 27f6beaea3SAntoine Tenart #include <crypto/internal/aead.h> 281eb7b403SOfer Heifetz #include <crypto/internal/skcipher.h> 291b44c5a6SAntoine Ténart 301b44c5a6SAntoine Ténart #include "safexcel.h" 311b44c5a6SAntoine Ténart 321b44c5a6SAntoine Ténart enum safexcel_cipher_direction { 331b44c5a6SAntoine Ténart SAFEXCEL_ENCRYPT, 341b44c5a6SAntoine Ténart SAFEXCEL_DECRYPT, 351b44c5a6SAntoine Ténart }; 361b44c5a6SAntoine Ténart 37a7dea8c0SOfer Heifetz enum safexcel_cipher_alg { 38a7dea8c0SOfer Heifetz SAFEXCEL_DES, 3962469879SOfer Heifetz SAFEXCEL_3DES, 40a7dea8c0SOfer Heifetz SAFEXCEL_AES, 414a593fb3SPascal van Leeuwen SAFEXCEL_CHACHA20, 42fcca797dSPascal van Leeuwen SAFEXCEL_SM4, 43a7dea8c0SOfer Heifetz }; 44a7dea8c0SOfer Heifetz 451b44c5a6SAntoine Ténart struct safexcel_cipher_ctx { 461b44c5a6SAntoine Ténart struct safexcel_context base; 471b44c5a6SAntoine Ténart struct safexcel_crypto_priv *priv; 481b44c5a6SAntoine Ténart 491b44c5a6SAntoine Ténart u32 mode; 50a7dea8c0SOfer Heifetz enum safexcel_cipher_alg alg; 51098e51e5SPascal van Leeuwen u8 aead; /* !=0=AEAD, 2=IPSec ESP AEAD, 3=IPsec ESP GMAC */ 52098e51e5SPascal van Leeuwen u8 xcm; /* 0=authenc, 1=GCM, 2 reserved for CCM */ 53098e51e5SPascal van Leeuwen u8 aadskip; 54098e51e5SPascal van Leeuwen u8 blocksz; 55098e51e5SPascal van Leeuwen u32 ivmask; 56098e51e5SPascal van Leeuwen u32 ctrinit; 571b44c5a6SAntoine Ténart 58c7da38a7SPascal van Leeuwen __le32 key[16]; 5954f9e8faSPascal van Leeuwen u32 nonce; 60c7da38a7SPascal van Leeuwen unsigned int key_len, xts; 61f6beaea3SAntoine Tenart 62f6beaea3SAntoine Tenart /* All the below is AEAD specific */ 63a7dea8c0SOfer Heifetz u32 hash_alg; 64f6beaea3SAntoine Tenart u32 state_sz; 653e450886SPascal van Leeuwen 66a6061921SPascal van Leeuwen struct crypto_aead *fback; 671b44c5a6SAntoine Ténart }; 681b44c5a6SAntoine Ténart 691eb7b403SOfer Heifetz struct safexcel_cipher_req { 70847ccfc5SOfer Heifetz enum safexcel_cipher_direction direction; 7189332590SAntoine Tenart /* Number of result descriptors associated to the request */ 7289332590SAntoine Tenart unsigned int rdescs; 731eb7b403SOfer Heifetz bool needs_inv; 7419b347b3SPascal van Leeuwen int nr_src, nr_dst; 751eb7b403SOfer Heifetz }; 761eb7b403SOfer Heifetz 77098e51e5SPascal van Leeuwen static int safexcel_skcipher_iv(struct safexcel_cipher_ctx *ctx, u8 *iv, 780e17e362SPascal van Leeuwen struct safexcel_command_desc *cdesc) 791b44c5a6SAntoine Ténart { 80098e51e5SPascal van Leeuwen if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { 81493e289cSPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 82493e289cSPascal van Leeuwen /* 32 bit nonce */ 83493e289cSPascal van Leeuwen cdesc->control_data.token[0] = ctx->nonce; 84493e289cSPascal van Leeuwen /* 64 bit IV part */ 85493e289cSPascal van Leeuwen memcpy(&cdesc->control_data.token[1], iv, 8); 86098e51e5SPascal van Leeuwen /* 32 bit counter, start at 0 or 1 (big endian!) */ 8713a1bb93SPascal van Leeuwen cdesc->control_data.token[3] = 88098e51e5SPascal van Leeuwen (__force u32)cpu_to_be32(ctx->ctrinit); 89098e51e5SPascal van Leeuwen return 4; 90a19052d4SPascal van Leeuwen } 91a19052d4SPascal van Leeuwen if (ctx->alg == SAFEXCEL_CHACHA20) { 924a593fb3SPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 934a593fb3SPascal van Leeuwen /* 96 bit nonce part */ 944a593fb3SPascal van Leeuwen memcpy(&cdesc->control_data.token[0], &iv[4], 12); 954a593fb3SPascal van Leeuwen /* 32 bit counter */ 964a593fb3SPascal van Leeuwen cdesc->control_data.token[3] = *(u32 *)iv; 97098e51e5SPascal van Leeuwen return 4; 98493e289cSPascal van Leeuwen } 99493e289cSPascal van Leeuwen 100098e51e5SPascal van Leeuwen cdesc->control_data.options |= ctx->ivmask; 101098e51e5SPascal van Leeuwen memcpy(cdesc->control_data.token, iv, ctx->blocksz); 102098e51e5SPascal van Leeuwen return ctx->blocksz / sizeof(u32); 10354f9e8faSPascal van Leeuwen } 1040e17e362SPascal van Leeuwen 1050e17e362SPascal van Leeuwen static void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 1060e17e362SPascal van Leeuwen struct safexcel_command_desc *cdesc, 107098e51e5SPascal van Leeuwen struct safexcel_token *atoken, 1080e17e362SPascal van Leeuwen u32 length) 1090e17e362SPascal van Leeuwen { 1100e17e362SPascal van Leeuwen struct safexcel_token *token; 111098e51e5SPascal van Leeuwen int ivlen; 1120e17e362SPascal van Leeuwen 113098e51e5SPascal van Leeuwen ivlen = safexcel_skcipher_iv(ctx, iv, cdesc); 114098e51e5SPascal van Leeuwen if (ivlen == 4) { 115098e51e5SPascal van Leeuwen /* No space in cdesc, instruction moves to atoken */ 116098e51e5SPascal van Leeuwen cdesc->additional_cdata_size = 1; 117098e51e5SPascal van Leeuwen token = atoken; 118098e51e5SPascal van Leeuwen } else { 119098e51e5SPascal van Leeuwen /* Everything fits in cdesc */ 120098e51e5SPascal van Leeuwen token = (struct safexcel_token *)(cdesc->control_data.token + 2); 121098e51e5SPascal van Leeuwen /* Need to pad with NOP */ 122098e51e5SPascal van Leeuwen eip197_noop_token(&token[1]); 123098e51e5SPascal van Leeuwen } 1241b44c5a6SAntoine Ténart 125098e51e5SPascal van Leeuwen token->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 126098e51e5SPascal van Leeuwen token->packet_length = length; 127098e51e5SPascal van Leeuwen token->stat = EIP197_TOKEN_STAT_LAST_PACKET | 12815f64ee0SAntoine Tenart EIP197_TOKEN_STAT_LAST_HASH; 129098e51e5SPascal van Leeuwen token->instructions = EIP197_TOKEN_INS_LAST | 130a74d850fSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_CRYPTO | 1311b44c5a6SAntoine Ténart EIP197_TOKEN_INS_TYPE_OUTPUT; 1321b44c5a6SAntoine Ténart } 1331b44c5a6SAntoine Ténart 134098e51e5SPascal van Leeuwen static void safexcel_aead_iv(struct safexcel_cipher_ctx *ctx, u8 *iv, 135098e51e5SPascal van Leeuwen struct safexcel_command_desc *cdesc) 136098e51e5SPascal van Leeuwen { 137098e51e5SPascal van Leeuwen if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD || 138098e51e5SPascal van Leeuwen ctx->aead & EIP197_AEAD_TYPE_IPSEC_ESP) { /* _ESP and _ESP_GMAC */ 139098e51e5SPascal van Leeuwen /* 32 bit nonce */ 140098e51e5SPascal van Leeuwen cdesc->control_data.token[0] = ctx->nonce; 141098e51e5SPascal van Leeuwen /* 64 bit IV part */ 142098e51e5SPascal van Leeuwen memcpy(&cdesc->control_data.token[1], iv, 8); 143098e51e5SPascal van Leeuwen /* 32 bit counter, start at 0 or 1 (big endian!) */ 144098e51e5SPascal van Leeuwen cdesc->control_data.token[3] = 145098e51e5SPascal van Leeuwen (__force u32)cpu_to_be32(ctx->ctrinit); 146098e51e5SPascal van Leeuwen return; 147098e51e5SPascal van Leeuwen } 148098e51e5SPascal van Leeuwen if (ctx->xcm == EIP197_XCM_MODE_GCM || ctx->alg == SAFEXCEL_CHACHA20) { 149098e51e5SPascal van Leeuwen /* 96 bit IV part */ 150098e51e5SPascal van Leeuwen memcpy(&cdesc->control_data.token[0], iv, 12); 151098e51e5SPascal van Leeuwen /* 32 bit counter, start at 0 or 1 (big endian!) */ 152098e51e5SPascal van Leeuwen cdesc->control_data.token[3] = 153098e51e5SPascal van Leeuwen (__force u32)cpu_to_be32(ctx->ctrinit); 154098e51e5SPascal van Leeuwen return; 155098e51e5SPascal van Leeuwen } 156098e51e5SPascal van Leeuwen /* CBC */ 157098e51e5SPascal van Leeuwen memcpy(cdesc->control_data.token, iv, ctx->blocksz); 158098e51e5SPascal van Leeuwen } 159098e51e5SPascal van Leeuwen 160f6beaea3SAntoine Tenart static void safexcel_aead_token(struct safexcel_cipher_ctx *ctx, u8 *iv, 161f6beaea3SAntoine Tenart struct safexcel_command_desc *cdesc, 162098e51e5SPascal van Leeuwen struct safexcel_token *atoken, 163f6beaea3SAntoine Tenart enum safexcel_cipher_direction direction, 164f6beaea3SAntoine Tenart u32 cryptlen, u32 assoclen, u32 digestsize) 165f6beaea3SAntoine Tenart { 166098e51e5SPascal van Leeuwen struct safexcel_token *aadref; 167098e51e5SPascal van Leeuwen int atoksize = 2; /* Start with minimum size */ 168098e51e5SPascal van Leeuwen int assocadj = assoclen - ctx->aadskip, aadalign; 169f6beaea3SAntoine Tenart 170098e51e5SPascal van Leeuwen /* Always 4 dwords of embedded IV for AEAD modes */ 171098e51e5SPascal van Leeuwen cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; 172f6beaea3SAntoine Tenart 173098e51e5SPascal van Leeuwen if (direction == SAFEXCEL_DECRYPT) 174d2d9e6fdSPascal van Leeuwen cryptlen -= digestsize; 175d2d9e6fdSPascal van Leeuwen 176098e51e5SPascal van Leeuwen if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM)) { 177098e51e5SPascal van Leeuwen /* Construct IV block B0 for the CBC-MAC */ 178098e51e5SPascal van Leeuwen u8 *final_iv = (u8 *)cdesc->control_data.token; 179098e51e5SPascal van Leeuwen u8 *cbcmaciv = (u8 *)&atoken[1]; 180098e51e5SPascal van Leeuwen __le32 *aadlen = (__le32 *)&atoken[5]; 18154f9e8faSPascal van Leeuwen 182098e51e5SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 183098e51e5SPascal van Leeuwen /* Length + nonce */ 184098e51e5SPascal van Leeuwen cdesc->control_data.token[0] = ctx->nonce; 185098e51e5SPascal van Leeuwen /* Fixup flags byte */ 186098e51e5SPascal van Leeuwen *(__le32 *)cbcmaciv = 187098e51e5SPascal van Leeuwen cpu_to_le32(ctx->nonce | 188098e51e5SPascal van Leeuwen ((assocadj > 0) << 6) | 189098e51e5SPascal van Leeuwen ((digestsize - 2) << 2)); 190098e51e5SPascal van Leeuwen /* 64 bit IV part */ 191098e51e5SPascal van Leeuwen memcpy(&cdesc->control_data.token[1], iv, 8); 192098e51e5SPascal van Leeuwen memcpy(cbcmaciv + 4, iv, 8); 193098e51e5SPascal van Leeuwen /* Start counter at 0 */ 194098e51e5SPascal van Leeuwen cdesc->control_data.token[3] = 0; 195098e51e5SPascal van Leeuwen /* Message length */ 196098e51e5SPascal van Leeuwen *(__be32 *)(cbcmaciv + 12) = cpu_to_be32(cryptlen); 197098e51e5SPascal van Leeuwen } else { 198098e51e5SPascal van Leeuwen /* Variable length IV part */ 199098e51e5SPascal van Leeuwen memcpy(final_iv, iv, 15 - iv[0]); 200098e51e5SPascal van Leeuwen memcpy(cbcmaciv, iv, 15 - iv[0]); 201098e51e5SPascal van Leeuwen /* Start variable length counter at 0 */ 202098e51e5SPascal van Leeuwen memset(final_iv + 15 - iv[0], 0, iv[0] + 1); 203098e51e5SPascal van Leeuwen memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1); 204098e51e5SPascal van Leeuwen /* fixup flags byte */ 205098e51e5SPascal van Leeuwen cbcmaciv[0] |= ((assocadj > 0) << 6) | 206098e51e5SPascal van Leeuwen ((digestsize - 2) << 2); 207098e51e5SPascal van Leeuwen /* insert lower 2 bytes of message length */ 208098e51e5SPascal van Leeuwen cbcmaciv[14] = cryptlen >> 8; 209098e51e5SPascal van Leeuwen cbcmaciv[15] = cryptlen & 255; 210f6beaea3SAntoine Tenart } 21154f9e8faSPascal van Leeuwen 212098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 213098e51e5SPascal van Leeuwen atoken->packet_length = AES_BLOCK_SIZE + 214098e51e5SPascal van Leeuwen ((assocadj > 0) << 1); 215098e51e5SPascal van Leeuwen atoken->stat = 0; 216098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN | 217098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH; 218098e51e5SPascal van Leeuwen 219098e51e5SPascal van Leeuwen if (likely(assocadj)) { 220098e51e5SPascal van Leeuwen *aadlen = cpu_to_le32((assocadj >> 8) | 221098e51e5SPascal van Leeuwen (assocadj & 255) << 8); 222098e51e5SPascal van Leeuwen atoken += 6; 223098e51e5SPascal van Leeuwen atoksize += 7; 224098e51e5SPascal van Leeuwen } else { 225098e51e5SPascal van Leeuwen atoken += 5; 226098e51e5SPascal van Leeuwen atoksize += 6; 227098e51e5SPascal van Leeuwen } 228098e51e5SPascal van Leeuwen 229098e51e5SPascal van Leeuwen /* Process AAD data */ 230098e51e5SPascal van Leeuwen aadref = atoken; 231098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 232098e51e5SPascal van Leeuwen atoken->packet_length = assocadj; 233098e51e5SPascal van Leeuwen atoken->stat = 0; 234098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 235098e51e5SPascal van Leeuwen atoken++; 236098e51e5SPascal van Leeuwen 237098e51e5SPascal van Leeuwen /* For CCM only, align AAD data towards hash engine */ 238098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 239098e51e5SPascal van Leeuwen aadalign = (assocadj + 2) & 15; 240098e51e5SPascal van Leeuwen atoken->packet_length = assocadj && aadalign ? 241098e51e5SPascal van Leeuwen 16 - aadalign : 242098e51e5SPascal van Leeuwen 0; 243098e51e5SPascal van Leeuwen if (likely(cryptlen)) { 244098e51e5SPascal van Leeuwen atoken->stat = 0; 245098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 246098e51e5SPascal van Leeuwen } else { 247098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 248098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_LAST | 249098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH; 250098e51e5SPascal van Leeuwen } 251098e51e5SPascal van Leeuwen } else { 252098e51e5SPascal van Leeuwen safexcel_aead_iv(ctx, iv, cdesc); 253098e51e5SPascal van Leeuwen 254098e51e5SPascal van Leeuwen /* Process AAD data */ 255098e51e5SPascal van Leeuwen aadref = atoken; 256098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 257098e51e5SPascal van Leeuwen atoken->packet_length = assocadj; 258098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 259098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_LAST | 260098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH; 261098e51e5SPascal van Leeuwen } 262098e51e5SPascal van Leeuwen atoken++; 263098e51e5SPascal van Leeuwen 264a6061921SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 26592c60cefSPascal van Leeuwen /* For ESP mode (and not GMAC), skip over the IV */ 266098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 267098e51e5SPascal van Leeuwen atoken->packet_length = EIP197_AEAD_IPSEC_IV_SIZE; 268098e51e5SPascal van Leeuwen atoken->stat = 0; 269098e51e5SPascal van Leeuwen atoken->instructions = 0; 270098e51e5SPascal van Leeuwen atoken++; 271098e51e5SPascal van Leeuwen atoksize++; 272098e51e5SPascal van Leeuwen } else if (unlikely(ctx->alg == SAFEXCEL_CHACHA20 && 273098e51e5SPascal van Leeuwen direction == SAFEXCEL_DECRYPT)) { 274098e51e5SPascal van Leeuwen /* Poly-chacha decryption needs a dummy NOP here ... */ 275098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 276098e51e5SPascal van Leeuwen atoken->packet_length = 16; /* According to Op Manual */ 277098e51e5SPascal van Leeuwen atoken->stat = 0; 278098e51e5SPascal van Leeuwen atoken->instructions = 0; 279098e51e5SPascal van Leeuwen atoken++; 280098e51e5SPascal van Leeuwen atoksize++; 281a6061921SPascal van Leeuwen } 282a6061921SPascal van Leeuwen 283098e51e5SPascal van Leeuwen if (ctx->xcm) { 284098e51e5SPascal van Leeuwen /* For GCM and CCM, obtain enc(Y0) */ 285098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES; 286098e51e5SPascal van Leeuwen atoken->packet_length = 0; 287098e51e5SPascal van Leeuwen atoken->stat = 0; 288098e51e5SPascal van Leeuwen atoken->instructions = AES_BLOCK_SIZE; 289098e51e5SPascal van Leeuwen atoken++; 290098e51e5SPascal van Leeuwen 291098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 292098e51e5SPascal van Leeuwen atoken->packet_length = AES_BLOCK_SIZE; 293098e51e5SPascal van Leeuwen atoken->stat = 0; 294098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | 295098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_TYPE_CRYPTO; 296098e51e5SPascal van Leeuwen atoken++; 297098e51e5SPascal van Leeuwen atoksize += 2; 298098e51e5SPascal van Leeuwen } 29954f9e8faSPascal van Leeuwen 300a6061921SPascal van Leeuwen if (likely(cryptlen || ctx->alg == SAFEXCEL_CHACHA20)) { 301098e51e5SPascal van Leeuwen /* Fixup stat field for AAD direction instruction */ 302098e51e5SPascal van Leeuwen aadref->stat = 0; 303098e51e5SPascal van Leeuwen 304098e51e5SPascal van Leeuwen /* Process crypto data */ 305098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; 306098e51e5SPascal van Leeuwen atoken->packet_length = cryptlen; 307098e51e5SPascal van Leeuwen 30892c60cefSPascal van Leeuwen if (unlikely(ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) { 309098e51e5SPascal van Leeuwen /* Fixup instruction field for AAD dir instruction */ 310098e51e5SPascal van Leeuwen aadref->instructions = EIP197_TOKEN_INS_TYPE_HASH; 311098e51e5SPascal van Leeuwen 31292c60cefSPascal van Leeuwen /* Do not send to crypt engine in case of GMAC */ 313098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_LAST | 31492c60cefSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH | 31592c60cefSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_OUTPUT; 31692c60cefSPascal van Leeuwen } else { 317098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_LAST | 31854f9e8faSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_CRYPTO | 31954f9e8faSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_HASH | 32054f9e8faSPascal van Leeuwen EIP197_TOKEN_INS_TYPE_OUTPUT; 32192c60cefSPascal van Leeuwen } 3223e450886SPascal van Leeuwen 3234eb76fafSPascal van Leeuwen cryptlen &= 15; 324098e51e5SPascal van Leeuwen if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM && cryptlen)) { 325098e51e5SPascal van Leeuwen atoken->stat = 0; 326098e51e5SPascal van Leeuwen /* For CCM only, pad crypto data to the hash engine */ 327098e51e5SPascal van Leeuwen atoken++; 328098e51e5SPascal van Leeuwen atoksize++; 329098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 330098e51e5SPascal van Leeuwen atoken->packet_length = 16 - cryptlen; 331098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 332098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; 3334eb76fafSPascal van Leeuwen } else { 334098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; 3354eb76fafSPascal van Leeuwen } 336098e51e5SPascal van Leeuwen atoken++; 337098e51e5SPascal van Leeuwen atoksize++; 3383e450886SPascal van Leeuwen } 339098e51e5SPascal van Leeuwen 340098e51e5SPascal van Leeuwen if (direction == SAFEXCEL_ENCRYPT) { 341098e51e5SPascal van Leeuwen /* Append ICV */ 342098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; 343098e51e5SPascal van Leeuwen atoken->packet_length = digestsize; 344098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 345098e51e5SPascal van Leeuwen EIP197_TOKEN_STAT_LAST_PACKET; 346098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | 347098e51e5SPascal van Leeuwen EIP197_TOKEN_INS_INSERT_HASH_DIGEST; 348098e51e5SPascal van Leeuwen } else { 349098e51e5SPascal van Leeuwen /* Extract ICV */ 350098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_RETRIEVE; 351098e51e5SPascal van Leeuwen atoken->packet_length = digestsize; 352098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 353098e51e5SPascal van Leeuwen EIP197_TOKEN_STAT_LAST_PACKET; 354098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST; 355098e51e5SPascal van Leeuwen atoken++; 356098e51e5SPascal van Leeuwen atoksize++; 357098e51e5SPascal van Leeuwen 358098e51e5SPascal van Leeuwen /* Verify ICV */ 359098e51e5SPascal van Leeuwen atoken->opcode = EIP197_TOKEN_OPCODE_VERIFY; 360098e51e5SPascal van Leeuwen atoken->packet_length = digestsize | 361098e51e5SPascal van Leeuwen EIP197_TOKEN_HASH_RESULT_VERIFY; 362098e51e5SPascal van Leeuwen atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | 363098e51e5SPascal van Leeuwen EIP197_TOKEN_STAT_LAST_PACKET; 364098e51e5SPascal van Leeuwen atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT; 365098e51e5SPascal van Leeuwen } 366098e51e5SPascal van Leeuwen 367098e51e5SPascal van Leeuwen /* Fixup length of the token in the command descriptor */ 368098e51e5SPascal van Leeuwen cdesc->additional_cdata_size = atoksize; 369f6beaea3SAntoine Tenart } 370f6beaea3SAntoine Tenart 3718ac1283eSAntoine Tenart static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm, 3728ac1283eSAntoine Tenart const u8 *key, unsigned int len) 3731b44c5a6SAntoine Ténart { 3741b44c5a6SAntoine Ténart struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 3751b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 37618e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 3771b44c5a6SAntoine Ténart struct crypto_aes_ctx aes; 3781b44c5a6SAntoine Ténart int ret, i; 3791b44c5a6SAntoine Ténart 380363a90c2SArd Biesheuvel ret = aes_expandkey(&aes, key, len); 381674f368aSEric Biggers if (ret) 3821b44c5a6SAntoine Ténart return ret; 3831b44c5a6SAntoine Ténart 38453c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 3851b44c5a6SAntoine Ténart for (i = 0; i < len / sizeof(u32); i++) { 38613a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 3871b44c5a6SAntoine Ténart ctx->base.needs_inv = true; 3881b44c5a6SAntoine Ténart break; 3891b44c5a6SAntoine Ténart } 3901b44c5a6SAntoine Ténart } 391c4daf4ccSOfer Heifetz } 3921b44c5a6SAntoine Ténart 3931b44c5a6SAntoine Ténart for (i = 0; i < len / sizeof(u32); i++) 3941b44c5a6SAntoine Ténart ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 3951b44c5a6SAntoine Ténart 3961b44c5a6SAntoine Ténart ctx->key_len = len; 3971b44c5a6SAntoine Ténart 3981b44c5a6SAntoine Ténart memzero_explicit(&aes, sizeof(aes)); 3991b44c5a6SAntoine Ténart return 0; 4001b44c5a6SAntoine Ténart } 4011b44c5a6SAntoine Ténart 40277cdd4efSPascal van Leeuwen static int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key, 403f6beaea3SAntoine Tenart unsigned int len) 404f6beaea3SAntoine Tenart { 405f6beaea3SAntoine Tenart struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 406f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 40718e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 408f6beaea3SAntoine Tenart struct crypto_authenc_keys keys; 4090e17e362SPascal van Leeuwen struct crypto_aes_ctx aes; 41013a1bb93SPascal van Leeuwen int err = -EINVAL, i; 41163cdd870SHerbert Xu const char *alg; 412f6beaea3SAntoine Tenart 4131769f704SPascal van Leeuwen if (unlikely(crypto_authenc_extractkeys(&keys, key, len))) 414f6beaea3SAntoine Tenart goto badkey; 415f6beaea3SAntoine Tenart 4160e17e362SPascal van Leeuwen if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { 4171769f704SPascal van Leeuwen /* Must have at least space for the nonce here */ 4181769f704SPascal van Leeuwen if (unlikely(keys.enckeylen < CTR_RFC3686_NONCE_SIZE)) 419f6beaea3SAntoine Tenart goto badkey; 4200e17e362SPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 421f26882a3SPascal van Leeuwen ctx->nonce = *(u32 *)(keys.enckey + keys.enckeylen - 422f26882a3SPascal van Leeuwen CTR_RFC3686_NONCE_SIZE); 4230e17e362SPascal van Leeuwen /* exclude the nonce here */ 4241769f704SPascal van Leeuwen keys.enckeylen -= CTR_RFC3686_NONCE_SIZE; 4250e17e362SPascal van Leeuwen } 426f6beaea3SAntoine Tenart 427f6beaea3SAntoine Tenart /* Encryption key */ 4280e17e362SPascal van Leeuwen switch (ctx->alg) { 429bb7679b8SPascal van Leeuwen case SAFEXCEL_DES: 430bb7679b8SPascal van Leeuwen err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen); 431bb7679b8SPascal van Leeuwen if (unlikely(err)) 432674f368aSEric Biggers goto badkey; 433bb7679b8SPascal van Leeuwen break; 4340e17e362SPascal van Leeuwen case SAFEXCEL_3DES: 43521f5a15eSArd Biesheuvel err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen); 43677cdd4efSPascal van Leeuwen if (unlikely(err)) 437674f368aSEric Biggers goto badkey; 4380e17e362SPascal van Leeuwen break; 4390e17e362SPascal van Leeuwen case SAFEXCEL_AES: 4400e17e362SPascal van Leeuwen err = aes_expandkey(&aes, keys.enckey, keys.enckeylen); 4410e17e362SPascal van Leeuwen if (unlikely(err)) 4420e17e362SPascal van Leeuwen goto badkey; 4430e17e362SPascal van Leeuwen break; 4441769f704SPascal van Leeuwen case SAFEXCEL_SM4: 4451769f704SPascal van Leeuwen if (unlikely(keys.enckeylen != SM4_KEY_SIZE)) 4461769f704SPascal van Leeuwen goto badkey; 4471769f704SPascal van Leeuwen break; 4480e17e362SPascal van Leeuwen default: 4490e17e362SPascal van Leeuwen dev_err(priv->dev, "aead: unsupported cipher algorithm\n"); 4500e17e362SPascal van Leeuwen goto badkey; 45177cdd4efSPascal van Leeuwen } 45277cdd4efSPascal van Leeuwen 45313a1bb93SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 45413a1bb93SPascal van Leeuwen for (i = 0; i < keys.enckeylen / sizeof(u32); i++) { 455b8151220SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != 456b8151220SPascal van Leeuwen ((u32 *)keys.enckey)[i]) { 457f6beaea3SAntoine Tenart ctx->base.needs_inv = true; 45813a1bb93SPascal van Leeuwen break; 45913a1bb93SPascal van Leeuwen } 46013a1bb93SPascal van Leeuwen } 46113a1bb93SPascal van Leeuwen } 462f6beaea3SAntoine Tenart 463f6beaea3SAntoine Tenart /* Auth key */ 464a7dea8c0SOfer Heifetz switch (ctx->hash_alg) { 46501ba061dSAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA1: 46663cdd870SHerbert Xu alg = "safexcel-sha1"; 46701ba061dSAntoine Tenart break; 468678b2878SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA224: 46963cdd870SHerbert Xu alg = "safexcel-sha224"; 470678b2878SAntoine Tenart break; 471678b2878SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA256: 47263cdd870SHerbert Xu alg = "safexcel-sha256"; 473678b2878SAntoine Tenart break; 474ea23cb53SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA384: 47563cdd870SHerbert Xu alg = "safexcel-sha384"; 476ea23cb53SAntoine Tenart break; 47787eee125SAntoine Tenart case CONTEXT_CONTROL_CRYPTO_ALG_SHA512: 47863cdd870SHerbert Xu alg = "safexcel-sha512"; 47987eee125SAntoine Tenart break; 4801769f704SPascal van Leeuwen case CONTEXT_CONTROL_CRYPTO_ALG_SM3: 48163cdd870SHerbert Xu alg = "safexcel-sm3"; 4821769f704SPascal van Leeuwen break; 483678b2878SAntoine Tenart default: 4841a61af28SColin Ian King dev_err(priv->dev, "aead: unsupported hash algorithm\n"); 485678b2878SAntoine Tenart goto badkey; 486678b2878SAntoine Tenart } 487f6beaea3SAntoine Tenart 48863cdd870SHerbert Xu if (safexcel_hmac_setkey(&ctx->base, keys.authkey, keys.authkeylen, 48963cdd870SHerbert Xu alg, ctx->state_sz)) 49063cdd870SHerbert Xu goto badkey; 491f6beaea3SAntoine Tenart 492f6beaea3SAntoine Tenart /* Now copy the keys into the context */ 49313a1bb93SPascal van Leeuwen for (i = 0; i < keys.enckeylen / sizeof(u32); i++) 494b8151220SPascal van Leeuwen ctx->key[i] = cpu_to_le32(((u32 *)keys.enckey)[i]); 495f6beaea3SAntoine Tenart ctx->key_len = keys.enckeylen; 496f6beaea3SAntoine Tenart 497f6beaea3SAntoine Tenart memzero_explicit(&keys, sizeof(keys)); 498f6beaea3SAntoine Tenart return 0; 499f6beaea3SAntoine Tenart 500f6beaea3SAntoine Tenart badkey: 501f6beaea3SAntoine Tenart memzero_explicit(&keys, sizeof(keys)); 5020e17e362SPascal van Leeuwen return err; 503f6beaea3SAntoine Tenart } 504f6beaea3SAntoine Tenart 5051b44c5a6SAntoine Ténart static int safexcel_context_control(struct safexcel_cipher_ctx *ctx, 506847ccfc5SOfer Heifetz struct crypto_async_request *async, 5078ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 5081b44c5a6SAntoine Ténart struct safexcel_command_desc *cdesc) 5091b44c5a6SAntoine Ténart { 51018e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 511d2d9e6fdSPascal van Leeuwen int ctrl_size = ctx->key_len / sizeof(u32); 512d2d9e6fdSPascal van Leeuwen 513d2d9e6fdSPascal van Leeuwen cdesc->control_data.control1 = ctx->mode; 5141b44c5a6SAntoine Ténart 515f6beaea3SAntoine Tenart if (ctx->aead) { 516d2d9e6fdSPascal van Leeuwen /* Take in account the ipad+opad digests */ 5173e450886SPascal van Leeuwen if (ctx->xcm) { 5183e450886SPascal van Leeuwen ctrl_size += ctx->state_sz / sizeof(u32); 5193e450886SPascal van Leeuwen cdesc->control_data.control0 = 5203e450886SPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 5213e450886SPascal van Leeuwen CONTEXT_CONTROL_DIGEST_XCM | 5223e450886SPascal van Leeuwen ctx->hash_alg | 5233e450886SPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 524a6061921SPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_CHACHA20) { 525a6061921SPascal van Leeuwen /* Chacha20-Poly1305 */ 526a6061921SPascal van Leeuwen cdesc->control_data.control0 = 527a6061921SPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 528a6061921SPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 | 529a6061921SPascal van Leeuwen (sreq->direction == SAFEXCEL_ENCRYPT ? 530a6061921SPascal van Leeuwen CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT : 531a6061921SPascal van Leeuwen CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN) | 532a6061921SPascal van Leeuwen ctx->hash_alg | 533a6061921SPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 534a6061921SPascal van Leeuwen return 0; 5353e450886SPascal van Leeuwen } else { 536d2d9e6fdSPascal van Leeuwen ctrl_size += ctx->state_sz / sizeof(u32) * 2; 5373e450886SPascal van Leeuwen cdesc->control_data.control0 = 5383e450886SPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 5393e450886SPascal van Leeuwen CONTEXT_CONTROL_DIGEST_HMAC | 5403e450886SPascal van Leeuwen ctx->hash_alg | 5413e450886SPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 5423e450886SPascal van Leeuwen } 5434eb76fafSPascal van Leeuwen 54492c60cefSPascal van Leeuwen if (sreq->direction == SAFEXCEL_ENCRYPT && 54592c60cefSPascal van Leeuwen (ctx->xcm == EIP197_XCM_MODE_CCM || 54692c60cefSPascal van Leeuwen ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) 54792c60cefSPascal van Leeuwen cdesc->control_data.control0 |= 54892c60cefSPascal van Leeuwen CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT; 54992c60cefSPascal van Leeuwen else if (sreq->direction == SAFEXCEL_ENCRYPT) 55092c60cefSPascal van Leeuwen cdesc->control_data.control0 |= 55192c60cefSPascal van Leeuwen CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT; 55292c60cefSPascal van Leeuwen else if (ctx->xcm == EIP197_XCM_MODE_CCM) 55392c60cefSPascal van Leeuwen cdesc->control_data.control0 |= 55492c60cefSPascal van Leeuwen CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN; 555d2d9e6fdSPascal van Leeuwen else 5563e450886SPascal van Leeuwen cdesc->control_data.control0 |= 5573e450886SPascal van Leeuwen CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN; 558d2d9e6fdSPascal van Leeuwen } else { 559d2d9e6fdSPascal van Leeuwen if (sreq->direction == SAFEXCEL_ENCRYPT) 560d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 = 561d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_TYPE_CRYPTO_OUT | 562d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 563d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 564d2d9e6fdSPascal van Leeuwen else 565d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 = 566d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_TYPE_CRYPTO_IN | 567d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_KEY_EN | 568d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_SIZE(ctrl_size); 569f6beaea3SAntoine Tenart } 5701b44c5a6SAntoine Ténart 571a7dea8c0SOfer Heifetz if (ctx->alg == SAFEXCEL_DES) { 572d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 573d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_DES; 57462469879SOfer Heifetz } else if (ctx->alg == SAFEXCEL_3DES) { 575d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 576d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_3DES; 577a7dea8c0SOfer Heifetz } else if (ctx->alg == SAFEXCEL_AES) { 578c7da38a7SPascal van Leeuwen switch (ctx->key_len >> ctx->xts) { 5791b44c5a6SAntoine Ténart case AES_KEYSIZE_128: 580d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 581d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_AES128; 5821b44c5a6SAntoine Ténart break; 5831b44c5a6SAntoine Ténart case AES_KEYSIZE_192: 584d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 585d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_AES192; 5861b44c5a6SAntoine Ténart break; 5871b44c5a6SAntoine Ténart case AES_KEYSIZE_256: 588d2d9e6fdSPascal van Leeuwen cdesc->control_data.control0 |= 589d2d9e6fdSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_AES256; 5901b44c5a6SAntoine Ténart break; 5911b44c5a6SAntoine Ténart default: 5921b44c5a6SAntoine Ténart dev_err(priv->dev, "aes keysize not supported: %u\n", 593c7da38a7SPascal van Leeuwen ctx->key_len >> ctx->xts); 5941b44c5a6SAntoine Ténart return -EINVAL; 5951b44c5a6SAntoine Ténart } 5964a593fb3SPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_CHACHA20) { 5974a593fb3SPascal van Leeuwen cdesc->control_data.control0 |= 5984a593fb3SPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20; 599fcca797dSPascal van Leeuwen } else if (ctx->alg == SAFEXCEL_SM4) { 600fcca797dSPascal van Leeuwen cdesc->control_data.control0 |= 601fcca797dSPascal van Leeuwen CONTEXT_CONTROL_CRYPTO_ALG_SM4; 602a7dea8c0SOfer Heifetz } 603fef0cfe5SAntoine Tenart 6041b44c5a6SAntoine Ténart return 0; 6051b44c5a6SAntoine Ténart } 6061b44c5a6SAntoine Ténart 6071eb7b403SOfer Heifetz static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring, 6081b44c5a6SAntoine Ténart struct crypto_async_request *async, 6098ac1283eSAntoine Tenart struct scatterlist *src, 6108ac1283eSAntoine Tenart struct scatterlist *dst, 6118ac1283eSAntoine Tenart unsigned int cryptlen, 6128ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 6131b44c5a6SAntoine Ténart bool *should_complete, int *ret) 6141b44c5a6SAntoine Ténart { 6155bdb6e6aSPascal van Leeuwen struct skcipher_request *areq = skcipher_request_cast(async); 6165bdb6e6aSPascal van Leeuwen struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq); 6175bdb6e6aSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(skcipher); 6181b44c5a6SAntoine Ténart struct safexcel_result_desc *rdesc; 6191b44c5a6SAntoine Ténart int ndesc = 0; 6201b44c5a6SAntoine Ténart 6211b44c5a6SAntoine Ténart *ret = 0; 6221b44c5a6SAntoine Ténart 62389332590SAntoine Tenart if (unlikely(!sreq->rdescs)) 62489332590SAntoine Tenart return 0; 62589332590SAntoine Tenart 62689332590SAntoine Tenart while (sreq->rdescs--) { 6271b44c5a6SAntoine Ténart rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr); 6281b44c5a6SAntoine Ténart if (IS_ERR(rdesc)) { 6291b44c5a6SAntoine Ténart dev_err(priv->dev, 6301b44c5a6SAntoine Ténart "cipher: result: could not retrieve the result descriptor\n"); 6311b44c5a6SAntoine Ténart *ret = PTR_ERR(rdesc); 6321b44c5a6SAntoine Ténart break; 6331b44c5a6SAntoine Ténart } 6341b44c5a6SAntoine Ténart 635bdfd1909SAntoine Tenart if (likely(!*ret)) 636bdfd1909SAntoine Tenart *ret = safexcel_rdesc_check_errors(priv, rdesc); 6371b44c5a6SAntoine Ténart 6381b44c5a6SAntoine Ténart ndesc++; 63989332590SAntoine Tenart } 6401b44c5a6SAntoine Ténart 6411b44c5a6SAntoine Ténart safexcel_complete(priv, ring); 6421b44c5a6SAntoine Ténart 6438ac1283eSAntoine Tenart if (src == dst) { 64449186a7dSPeter Harliman Liem if (sreq->nr_src > 0) 64549186a7dSPeter Harliman Liem dma_unmap_sg(priv->dev, src, sreq->nr_src, 64649186a7dSPeter Harliman Liem DMA_BIDIRECTIONAL); 6471b44c5a6SAntoine Ténart } else { 64849186a7dSPeter Harliman Liem if (sreq->nr_src > 0) 64949186a7dSPeter Harliman Liem dma_unmap_sg(priv->dev, src, sreq->nr_src, 65049186a7dSPeter Harliman Liem DMA_TO_DEVICE); 65149186a7dSPeter Harliman Liem if (sreq->nr_dst > 0) 65249186a7dSPeter Harliman Liem dma_unmap_sg(priv->dev, dst, sreq->nr_dst, 65349186a7dSPeter Harliman Liem DMA_FROM_DEVICE); 6541b44c5a6SAntoine Ténart } 6551b44c5a6SAntoine Ténart 6565bdb6e6aSPascal van Leeuwen /* 6575bdb6e6aSPascal van Leeuwen * Update IV in req from last crypto output word for CBC modes 6585bdb6e6aSPascal van Leeuwen */ 6595bdb6e6aSPascal van Leeuwen if ((!ctx->aead) && (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) && 6605bdb6e6aSPascal van Leeuwen (sreq->direction == SAFEXCEL_ENCRYPT)) { 6615bdb6e6aSPascal van Leeuwen /* For encrypt take the last output word */ 66219b347b3SPascal van Leeuwen sg_pcopy_to_buffer(dst, sreq->nr_dst, areq->iv, 6635bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher), 6645bdb6e6aSPascal van Leeuwen (cryptlen - 6655bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher))); 6665bdb6e6aSPascal van Leeuwen } 6675bdb6e6aSPascal van Leeuwen 6681b44c5a6SAntoine Ténart *should_complete = true; 6691b44c5a6SAntoine Ténart 6701b44c5a6SAntoine Ténart return ndesc; 6711b44c5a6SAntoine Ténart } 6721b44c5a6SAntoine Ténart 673a7dea8c0SOfer Heifetz static int safexcel_send_req(struct crypto_async_request *base, int ring, 6748ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 6758ac1283eSAntoine Tenart struct scatterlist *src, struct scatterlist *dst, 676f6beaea3SAntoine Tenart unsigned int cryptlen, unsigned int assoclen, 677f6beaea3SAntoine Tenart unsigned int digestsize, u8 *iv, int *commands, 6788ac1283eSAntoine Tenart int *results) 6791b44c5a6SAntoine Ténart { 6805bdb6e6aSPascal van Leeuwen struct skcipher_request *areq = skcipher_request_cast(base); 6815bdb6e6aSPascal van Leeuwen struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq); 6828ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 68318e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 6841b44c5a6SAntoine Ténart struct safexcel_command_desc *cdesc; 68519b347b3SPascal van Leeuwen struct safexcel_command_desc *first_cdesc = NULL; 686e5c8ee1fSAntoine Tenart struct safexcel_result_desc *rdesc, *first_rdesc = NULL; 6871b44c5a6SAntoine Ténart struct scatterlist *sg; 68819b347b3SPascal van Leeuwen unsigned int totlen; 68919b347b3SPascal van Leeuwen unsigned int totlen_src = cryptlen + assoclen; 69019b347b3SPascal van Leeuwen unsigned int totlen_dst = totlen_src; 691098e51e5SPascal van Leeuwen struct safexcel_token *atoken; 69219b347b3SPascal van Leeuwen int n_cdesc = 0, n_rdesc = 0; 69319b347b3SPascal van Leeuwen int queued, i, ret = 0; 69419b347b3SPascal van Leeuwen bool first = true; 6951b44c5a6SAntoine Ténart 69619b347b3SPascal van Leeuwen sreq->nr_src = sg_nents_for_len(src, totlen_src); 69719b347b3SPascal van Leeuwen 69819b347b3SPascal van Leeuwen if (ctx->aead) { 69919b347b3SPascal van Leeuwen /* 70019b347b3SPascal van Leeuwen * AEAD has auth tag appended to output for encrypt and 70119b347b3SPascal van Leeuwen * removed from the output for decrypt! 70219b347b3SPascal van Leeuwen */ 70319b347b3SPascal van Leeuwen if (sreq->direction == SAFEXCEL_DECRYPT) 70419b347b3SPascal van Leeuwen totlen_dst -= digestsize; 70519b347b3SPascal van Leeuwen else 70619b347b3SPascal van Leeuwen totlen_dst += digestsize; 70719b347b3SPascal van Leeuwen 70819b347b3SPascal van Leeuwen memcpy(ctx->base.ctxr->data + ctx->key_len / sizeof(u32), 70978cf1c8bSHerbert Xu &ctx->base.ipad, ctx->state_sz); 7103e450886SPascal van Leeuwen if (!ctx->xcm) 7113e450886SPascal van Leeuwen memcpy(ctx->base.ctxr->data + (ctx->key_len + 71278cf1c8bSHerbert Xu ctx->state_sz) / sizeof(u32), &ctx->base.opad, 7133e450886SPascal van Leeuwen ctx->state_sz); 71419b347b3SPascal van Leeuwen } else if ((ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) && 7155bdb6e6aSPascal van Leeuwen (sreq->direction == SAFEXCEL_DECRYPT)) { 7165bdb6e6aSPascal van Leeuwen /* 7175bdb6e6aSPascal van Leeuwen * Save IV from last crypto input word for CBC modes in decrypt 7185bdb6e6aSPascal van Leeuwen * direction. Need to do this first in case of inplace operation 7195bdb6e6aSPascal van Leeuwen * as it will be overwritten. 7205bdb6e6aSPascal van Leeuwen */ 72119b347b3SPascal van Leeuwen sg_pcopy_to_buffer(src, sreq->nr_src, areq->iv, 7225bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher), 72319b347b3SPascal van Leeuwen (totlen_src - 7245bdb6e6aSPascal van Leeuwen crypto_skcipher_ivsize(skcipher))); 7255bdb6e6aSPascal van Leeuwen } 7265bdb6e6aSPascal van Leeuwen 72719b347b3SPascal van Leeuwen sreq->nr_dst = sg_nents_for_len(dst, totlen_dst); 7281b44c5a6SAntoine Ténart 72919b347b3SPascal van Leeuwen /* 73019b347b3SPascal van Leeuwen * Remember actual input length, source buffer length may be 73119b347b3SPascal van Leeuwen * updated in case of inline operation below. 73219b347b3SPascal van Leeuwen */ 73319b347b3SPascal van Leeuwen totlen = totlen_src; 73419b347b3SPascal van Leeuwen queued = totlen_src; 73519b347b3SPascal van Leeuwen 73619b347b3SPascal van Leeuwen if (src == dst) { 73719b347b3SPascal van Leeuwen sreq->nr_src = max(sreq->nr_src, sreq->nr_dst); 73819b347b3SPascal van Leeuwen sreq->nr_dst = sreq->nr_src; 73919b347b3SPascal van Leeuwen if (unlikely((totlen_src || totlen_dst) && 74019b347b3SPascal van Leeuwen (sreq->nr_src <= 0))) { 74119b347b3SPascal van Leeuwen dev_err(priv->dev, "In-place buffer not large enough (need %d bytes)!", 74219b347b3SPascal van Leeuwen max(totlen_src, totlen_dst)); 7431b44c5a6SAntoine Ténart return -EINVAL; 7441b44c5a6SAntoine Ténart } 74549186a7dSPeter Harliman Liem if (sreq->nr_src > 0) 74649186a7dSPeter Harliman Liem dma_map_sg(priv->dev, src, sreq->nr_src, 74749186a7dSPeter Harliman Liem DMA_BIDIRECTIONAL); 74819b347b3SPascal van Leeuwen } else { 74919b347b3SPascal van Leeuwen if (unlikely(totlen_src && (sreq->nr_src <= 0))) { 75019b347b3SPascal van Leeuwen dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!", 75119b347b3SPascal van Leeuwen totlen_src); 75219b347b3SPascal van Leeuwen return -EINVAL; 75319b347b3SPascal van Leeuwen } 75449186a7dSPeter Harliman Liem 75549186a7dSPeter Harliman Liem if (sreq->nr_src > 0) 75619b347b3SPascal van Leeuwen dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); 75719b347b3SPascal van Leeuwen 75819b347b3SPascal van Leeuwen if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) { 75919b347b3SPascal van Leeuwen dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!", 76019b347b3SPascal van Leeuwen totlen_dst); 76149186a7dSPeter Harliman Liem ret = -EINVAL; 76249186a7dSPeter Harliman Liem goto unmap; 76319b347b3SPascal van Leeuwen } 76449186a7dSPeter Harliman Liem 76549186a7dSPeter Harliman Liem if (sreq->nr_dst > 0) 76649186a7dSPeter Harliman Liem dma_map_sg(priv->dev, dst, sreq->nr_dst, 76749186a7dSPeter Harliman Liem DMA_FROM_DEVICE); 7681b44c5a6SAntoine Ténart } 7691b44c5a6SAntoine Ténart 7701b44c5a6SAntoine Ténart memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len); 7711b44c5a6SAntoine Ténart 772cb97aa94SPascal van Leeuwen if (!totlen) { 773cb97aa94SPascal van Leeuwen /* 774cb97aa94SPascal van Leeuwen * The EIP97 cannot deal with zero length input packets! 775cb97aa94SPascal van Leeuwen * So stuff a dummy command descriptor indicating a 1 byte 776cb97aa94SPascal van Leeuwen * (dummy) input packet, using the context record as source. 777cb97aa94SPascal van Leeuwen */ 778cb97aa94SPascal van Leeuwen first_cdesc = safexcel_add_cdesc(priv, ring, 779cb97aa94SPascal van Leeuwen 1, 1, ctx->base.ctxr_dma, 780cb97aa94SPascal van Leeuwen 1, 1, ctx->base.ctxr_dma, 781cb97aa94SPascal van Leeuwen &atoken); 782cb97aa94SPascal van Leeuwen if (IS_ERR(first_cdesc)) { 783cb97aa94SPascal van Leeuwen /* No space left in the command descriptor ring */ 784cb97aa94SPascal van Leeuwen ret = PTR_ERR(first_cdesc); 785cb97aa94SPascal van Leeuwen goto cdesc_rollback; 786cb97aa94SPascal van Leeuwen } 787cb97aa94SPascal van Leeuwen n_cdesc = 1; 788cb97aa94SPascal van Leeuwen goto skip_cdesc; 789cb97aa94SPascal van Leeuwen } 790f6beaea3SAntoine Tenart 7911b44c5a6SAntoine Ténart /* command descriptors */ 79219b347b3SPascal van Leeuwen for_each_sg(src, sg, sreq->nr_src, i) { 7931b44c5a6SAntoine Ténart int len = sg_dma_len(sg); 7941b44c5a6SAntoine Ténart 7951b44c5a6SAntoine Ténart /* Do not overflow the request */ 796cb97aa94SPascal van Leeuwen if (queued < len) 7971b44c5a6SAntoine Ténart len = queued; 7981b44c5a6SAntoine Ténart 79919b347b3SPascal van Leeuwen cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc, 80019b347b3SPascal van Leeuwen !(queued - len), 801f6beaea3SAntoine Tenart sg_dma_address(sg), len, totlen, 802098e51e5SPascal van Leeuwen ctx->base.ctxr_dma, &atoken); 8031b44c5a6SAntoine Ténart if (IS_ERR(cdesc)) { 8041b44c5a6SAntoine Ténart /* No space left in the command descriptor ring */ 8051b44c5a6SAntoine Ténart ret = PTR_ERR(cdesc); 8061b44c5a6SAntoine Ténart goto cdesc_rollback; 8071b44c5a6SAntoine Ténart } 8081b44c5a6SAntoine Ténart 809cb97aa94SPascal van Leeuwen if (!n_cdesc) 81019b347b3SPascal van Leeuwen first_cdesc = cdesc; 8111b44c5a6SAntoine Ténart 812cb97aa94SPascal van Leeuwen n_cdesc++; 8131b44c5a6SAntoine Ténart queued -= len; 8141b44c5a6SAntoine Ténart if (!queued) 8151b44c5a6SAntoine Ténart break; 8161b44c5a6SAntoine Ténart } 817cb97aa94SPascal van Leeuwen skip_cdesc: 81819b347b3SPascal van Leeuwen /* Add context control words and token to first command descriptor */ 81919b347b3SPascal van Leeuwen safexcel_context_control(ctx, base, sreq, first_cdesc); 82019b347b3SPascal van Leeuwen if (ctx->aead) 821098e51e5SPascal van Leeuwen safexcel_aead_token(ctx, iv, first_cdesc, atoken, 82219b347b3SPascal van Leeuwen sreq->direction, cryptlen, 82319b347b3SPascal van Leeuwen assoclen, digestsize); 82419b347b3SPascal van Leeuwen else 825098e51e5SPascal van Leeuwen safexcel_skcipher_token(ctx, iv, first_cdesc, atoken, 82619b347b3SPascal van Leeuwen cryptlen); 82719b347b3SPascal van Leeuwen 8281b44c5a6SAntoine Ténart /* result descriptors */ 82919b347b3SPascal van Leeuwen for_each_sg(dst, sg, sreq->nr_dst, i) { 83019b347b3SPascal van Leeuwen bool last = (i == sreq->nr_dst - 1); 8311b44c5a6SAntoine Ténart u32 len = sg_dma_len(sg); 8321b44c5a6SAntoine Ténart 83319b347b3SPascal van Leeuwen /* only allow the part of the buffer we know we need */ 83419b347b3SPascal van Leeuwen if (len > totlen_dst) 83519b347b3SPascal van Leeuwen len = totlen_dst; 83619b347b3SPascal van Leeuwen if (unlikely(!len)) 83719b347b3SPascal van Leeuwen break; 83819b347b3SPascal van Leeuwen totlen_dst -= len; 83919b347b3SPascal van Leeuwen 84019b347b3SPascal van Leeuwen /* skip over AAD space in buffer - not written */ 84119b347b3SPascal van Leeuwen if (assoclen) { 84219b347b3SPascal van Leeuwen if (assoclen >= len) { 84319b347b3SPascal van Leeuwen assoclen -= len; 84419b347b3SPascal van Leeuwen continue; 84519b347b3SPascal van Leeuwen } 8461b44c5a6SAntoine Ténart rdesc = safexcel_add_rdesc(priv, ring, first, last, 84719b347b3SPascal van Leeuwen sg_dma_address(sg) + 84819b347b3SPascal van Leeuwen assoclen, 84919b347b3SPascal van Leeuwen len - assoclen); 85019b347b3SPascal van Leeuwen assoclen = 0; 85119b347b3SPascal van Leeuwen } else { 85219b347b3SPascal van Leeuwen rdesc = safexcel_add_rdesc(priv, ring, first, last, 85319b347b3SPascal van Leeuwen sg_dma_address(sg), 85419b347b3SPascal van Leeuwen len); 85519b347b3SPascal van Leeuwen } 8561b44c5a6SAntoine Ténart if (IS_ERR(rdesc)) { 8571b44c5a6SAntoine Ténart /* No space left in the result descriptor ring */ 8581b44c5a6SAntoine Ténart ret = PTR_ERR(rdesc); 8591b44c5a6SAntoine Ténart goto rdesc_rollback; 8601b44c5a6SAntoine Ténart } 86119b347b3SPascal van Leeuwen if (first) { 8629744fec9SOfer Heifetz first_rdesc = rdesc; 86319b347b3SPascal van Leeuwen first = false; 86419b347b3SPascal van Leeuwen } 8651b44c5a6SAntoine Ténart n_rdesc++; 8661b44c5a6SAntoine Ténart } 8671b44c5a6SAntoine Ténart 86819b347b3SPascal van Leeuwen if (unlikely(first)) { 86919b347b3SPascal van Leeuwen /* 87019b347b3SPascal van Leeuwen * Special case: AEAD decrypt with only AAD data. 87119b347b3SPascal van Leeuwen * In this case there is NO output data from the engine, 87219b347b3SPascal van Leeuwen * but the engine still needs a result descriptor! 87319b347b3SPascal van Leeuwen * Create a dummy one just for catching the result token. 87419b347b3SPascal van Leeuwen */ 87519b347b3SPascal van Leeuwen rdesc = safexcel_add_rdesc(priv, ring, true, true, 0, 0); 87619b347b3SPascal van Leeuwen if (IS_ERR(rdesc)) { 87719b347b3SPascal van Leeuwen /* No space left in the result descriptor ring */ 87819b347b3SPascal van Leeuwen ret = PTR_ERR(rdesc); 87919b347b3SPascal van Leeuwen goto rdesc_rollback; 88019b347b3SPascal van Leeuwen } 88119b347b3SPascal van Leeuwen first_rdesc = rdesc; 88219b347b3SPascal van Leeuwen n_rdesc = 1; 88319b347b3SPascal van Leeuwen } 88419b347b3SPascal van Leeuwen 8859744fec9SOfer Heifetz safexcel_rdr_req_set(priv, ring, first_rdesc, base); 88697858434SAntoine Ténart 8871b44c5a6SAntoine Ténart *commands = n_cdesc; 888152bdf4cSOfer Heifetz *results = n_rdesc; 8891b44c5a6SAntoine Ténart return 0; 8901b44c5a6SAntoine Ténart 8911b44c5a6SAntoine Ténart rdesc_rollback: 8921b44c5a6SAntoine Ténart for (i = 0; i < n_rdesc; i++) 8931b44c5a6SAntoine Ténart safexcel_ring_rollback_wptr(priv, &priv->ring[ring].rdr); 8941b44c5a6SAntoine Ténart cdesc_rollback: 8951b44c5a6SAntoine Ténart for (i = 0; i < n_cdesc; i++) 8961b44c5a6SAntoine Ténart safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr); 89749186a7dSPeter Harliman Liem unmap: 8988ac1283eSAntoine Tenart if (src == dst) { 89949186a7dSPeter Harliman Liem if (sreq->nr_src > 0) 90049186a7dSPeter Harliman Liem dma_unmap_sg(priv->dev, src, sreq->nr_src, 90149186a7dSPeter Harliman Liem DMA_BIDIRECTIONAL); 9021b44c5a6SAntoine Ténart } else { 90349186a7dSPeter Harliman Liem if (sreq->nr_src > 0) 90449186a7dSPeter Harliman Liem dma_unmap_sg(priv->dev, src, sreq->nr_src, 90549186a7dSPeter Harliman Liem DMA_TO_DEVICE); 90649186a7dSPeter Harliman Liem if (sreq->nr_dst > 0) 90749186a7dSPeter Harliman Liem dma_unmap_sg(priv->dev, dst, sreq->nr_dst, 90849186a7dSPeter Harliman Liem DMA_FROM_DEVICE); 9091b44c5a6SAntoine Ténart } 9101b44c5a6SAntoine Ténart 9111b44c5a6SAntoine Ténart return ret; 9121b44c5a6SAntoine Ténart } 9131b44c5a6SAntoine Ténart 9141b44c5a6SAntoine Ténart static int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv, 9151b44c5a6SAntoine Ténart int ring, 9168ac1283eSAntoine Tenart struct crypto_async_request *base, 91789332590SAntoine Tenart struct safexcel_cipher_req *sreq, 9181b44c5a6SAntoine Ténart bool *should_complete, int *ret) 9191b44c5a6SAntoine Ténart { 9208ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 9211b44c5a6SAntoine Ténart struct safexcel_result_desc *rdesc; 9221b44c5a6SAntoine Ténart int ndesc = 0, enq_ret; 9231b44c5a6SAntoine Ténart 9241b44c5a6SAntoine Ténart *ret = 0; 9251b44c5a6SAntoine Ténart 92689332590SAntoine Tenart if (unlikely(!sreq->rdescs)) 92789332590SAntoine Tenart return 0; 92889332590SAntoine Tenart 92989332590SAntoine Tenart while (sreq->rdescs--) { 9301b44c5a6SAntoine Ténart rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr); 9311b44c5a6SAntoine Ténart if (IS_ERR(rdesc)) { 9321b44c5a6SAntoine Ténart dev_err(priv->dev, 9331b44c5a6SAntoine Ténart "cipher: invalidate: could not retrieve the result descriptor\n"); 9341b44c5a6SAntoine Ténart *ret = PTR_ERR(rdesc); 9351b44c5a6SAntoine Ténart break; 9361b44c5a6SAntoine Ténart } 9371b44c5a6SAntoine Ténart 938cda3e73aSAntoine Tenart if (likely(!*ret)) 939cda3e73aSAntoine Tenart *ret = safexcel_rdesc_check_errors(priv, rdesc); 9401b44c5a6SAntoine Ténart 9411b44c5a6SAntoine Ténart ndesc++; 94289332590SAntoine Tenart } 9431b44c5a6SAntoine Ténart 9441b44c5a6SAntoine Ténart safexcel_complete(priv, ring); 9451b44c5a6SAntoine Ténart 9461b44c5a6SAntoine Ténart if (ctx->base.exit_inv) { 9471b44c5a6SAntoine Ténart dma_pool_free(priv->context_pool, ctx->base.ctxr, 9481b44c5a6SAntoine Ténart ctx->base.ctxr_dma); 9491b44c5a6SAntoine Ténart 9501b44c5a6SAntoine Ténart *should_complete = true; 9511b44c5a6SAntoine Ténart 9521b44c5a6SAntoine Ténart return ndesc; 9531b44c5a6SAntoine Ténart } 9541b44c5a6SAntoine Ténart 95586671abbSAntoine Ténart ring = safexcel_select_ring(priv); 95686671abbSAntoine Ténart ctx->base.ring = ring; 9571b44c5a6SAntoine Ténart 95886671abbSAntoine Ténart spin_lock_bh(&priv->ring[ring].queue_lock); 9598ac1283eSAntoine Tenart enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, base); 96086671abbSAntoine Ténart spin_unlock_bh(&priv->ring[ring].queue_lock); 9611b44c5a6SAntoine Ténart 9621b44c5a6SAntoine Ténart if (enq_ret != -EINPROGRESS) 9631b44c5a6SAntoine Ténart *ret = enq_ret; 9641b44c5a6SAntoine Ténart 9658472e778SAntoine Ténart queue_work(priv->ring[ring].workqueue, 9668472e778SAntoine Ténart &priv->ring[ring].work_data.work); 96786671abbSAntoine Ténart 9681b44c5a6SAntoine Ténart *should_complete = false; 9691b44c5a6SAntoine Ténart 9701b44c5a6SAntoine Ténart return ndesc; 9711b44c5a6SAntoine Ténart } 9721b44c5a6SAntoine Ténart 9738ac1283eSAntoine Tenart static int safexcel_skcipher_handle_result(struct safexcel_crypto_priv *priv, 9748ac1283eSAntoine Tenart int ring, 9751eb7b403SOfer Heifetz struct crypto_async_request *async, 9761eb7b403SOfer Heifetz bool *should_complete, int *ret) 9771eb7b403SOfer Heifetz { 9781eb7b403SOfer Heifetz struct skcipher_request *req = skcipher_request_cast(async); 9791eb7b403SOfer Heifetz struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 9801eb7b403SOfer Heifetz int err; 9811eb7b403SOfer Heifetz 9821eb7b403SOfer Heifetz if (sreq->needs_inv) { 9831eb7b403SOfer Heifetz sreq->needs_inv = false; 98489332590SAntoine Tenart err = safexcel_handle_inv_result(priv, ring, async, sreq, 9851eb7b403SOfer Heifetz should_complete, ret); 9861eb7b403SOfer Heifetz } else { 9878ac1283eSAntoine Tenart err = safexcel_handle_req_result(priv, ring, async, req->src, 9888ac1283eSAntoine Tenart req->dst, req->cryptlen, sreq, 9891eb7b403SOfer Heifetz should_complete, ret); 9901eb7b403SOfer Heifetz } 9911eb7b403SOfer Heifetz 9921eb7b403SOfer Heifetz return err; 9931eb7b403SOfer Heifetz } 9941eb7b403SOfer Heifetz 995f6beaea3SAntoine Tenart static int safexcel_aead_handle_result(struct safexcel_crypto_priv *priv, 996f6beaea3SAntoine Tenart int ring, 997f6beaea3SAntoine Tenart struct crypto_async_request *async, 998f6beaea3SAntoine Tenart bool *should_complete, int *ret) 999f6beaea3SAntoine Tenart { 1000f6beaea3SAntoine Tenart struct aead_request *req = aead_request_cast(async); 1001f6beaea3SAntoine Tenart struct crypto_aead *tfm = crypto_aead_reqtfm(req); 1002f6beaea3SAntoine Tenart struct safexcel_cipher_req *sreq = aead_request_ctx(req); 1003f6beaea3SAntoine Tenart int err; 1004f6beaea3SAntoine Tenart 1005f6beaea3SAntoine Tenart if (sreq->needs_inv) { 1006f6beaea3SAntoine Tenart sreq->needs_inv = false; 100789332590SAntoine Tenart err = safexcel_handle_inv_result(priv, ring, async, sreq, 1008f6beaea3SAntoine Tenart should_complete, ret); 1009f6beaea3SAntoine Tenart } else { 1010f6beaea3SAntoine Tenart err = safexcel_handle_req_result(priv, ring, async, req->src, 1011f6beaea3SAntoine Tenart req->dst, 1012f6beaea3SAntoine Tenart req->cryptlen + crypto_aead_authsize(tfm), 1013f6beaea3SAntoine Tenart sreq, should_complete, ret); 1014f6beaea3SAntoine Tenart } 1015f6beaea3SAntoine Tenart 1016f6beaea3SAntoine Tenart return err; 1017f6beaea3SAntoine Tenart } 1018f6beaea3SAntoine Tenart 10198ac1283eSAntoine Tenart static int safexcel_cipher_send_inv(struct crypto_async_request *base, 10209744fec9SOfer Heifetz int ring, int *commands, int *results) 10211b44c5a6SAntoine Ténart { 10228ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 102318e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 10241b44c5a6SAntoine Ténart int ret; 10251b44c5a6SAntoine Ténart 10269744fec9SOfer Heifetz ret = safexcel_invalidate_cache(base, priv, ctx->base.ctxr_dma, ring); 10271b44c5a6SAntoine Ténart if (unlikely(ret)) 10281b44c5a6SAntoine Ténart return ret; 10291b44c5a6SAntoine Ténart 10301b44c5a6SAntoine Ténart *commands = 1; 10311b44c5a6SAntoine Ténart *results = 1; 10321b44c5a6SAntoine Ténart 10331b44c5a6SAntoine Ténart return 0; 10341b44c5a6SAntoine Ténart } 10351b44c5a6SAntoine Ténart 10368ac1283eSAntoine Tenart static int safexcel_skcipher_send(struct crypto_async_request *async, int ring, 10371eb7b403SOfer Heifetz int *commands, int *results) 10381eb7b403SOfer Heifetz { 10391eb7b403SOfer Heifetz struct skcipher_request *req = skcipher_request_cast(async); 1040871df319SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 10411eb7b403SOfer Heifetz struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 104218e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 10431eb7b403SOfer Heifetz int ret; 10441eb7b403SOfer Heifetz 104553c83e91SAntoine Tenart BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv); 1046871df319SAntoine Ténart 10475bdb6e6aSPascal van Leeuwen if (sreq->needs_inv) { 10489744fec9SOfer Heifetz ret = safexcel_cipher_send_inv(async, ring, commands, results); 10495bdb6e6aSPascal van Leeuwen } else { 10505bdb6e6aSPascal van Leeuwen struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 10515bdb6e6aSPascal van Leeuwen u8 input_iv[AES_BLOCK_SIZE]; 10525bdb6e6aSPascal van Leeuwen 10535bdb6e6aSPascal van Leeuwen /* 10545bdb6e6aSPascal van Leeuwen * Save input IV in case of CBC decrypt mode 10555bdb6e6aSPascal van Leeuwen * Will be overwritten with output IV prior to use! 10565bdb6e6aSPascal van Leeuwen */ 10575bdb6e6aSPascal van Leeuwen memcpy(input_iv, req->iv, crypto_skcipher_ivsize(skcipher)); 10585bdb6e6aSPascal van Leeuwen 10599744fec9SOfer Heifetz ret = safexcel_send_req(async, ring, sreq, req->src, 10605bdb6e6aSPascal van Leeuwen req->dst, req->cryptlen, 0, 0, input_iv, 1061f6beaea3SAntoine Tenart commands, results); 10625bdb6e6aSPascal van Leeuwen } 106389332590SAntoine Tenart 106489332590SAntoine Tenart sreq->rdescs = *results; 1065f6beaea3SAntoine Tenart return ret; 1066f6beaea3SAntoine Tenart } 1067f6beaea3SAntoine Tenart 1068f6beaea3SAntoine Tenart static int safexcel_aead_send(struct crypto_async_request *async, int ring, 10699744fec9SOfer Heifetz int *commands, int *results) 1070f6beaea3SAntoine Tenart { 1071f6beaea3SAntoine Tenart struct aead_request *req = aead_request_cast(async); 1072f6beaea3SAntoine Tenart struct crypto_aead *tfm = crypto_aead_reqtfm(req); 1073f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 1074f6beaea3SAntoine Tenart struct safexcel_cipher_req *sreq = aead_request_ctx(req); 107518e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 1076f6beaea3SAntoine Tenart int ret; 1077f6beaea3SAntoine Tenart 107853c83e91SAntoine Tenart BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv); 1079f6beaea3SAntoine Tenart 1080f6beaea3SAntoine Tenart if (sreq->needs_inv) 10819744fec9SOfer Heifetz ret = safexcel_cipher_send_inv(async, ring, commands, results); 1082f6beaea3SAntoine Tenart else 10839744fec9SOfer Heifetz ret = safexcel_send_req(async, ring, sreq, req->src, req->dst, 10849744fec9SOfer Heifetz req->cryptlen, req->assoclen, 1085f6beaea3SAntoine Tenart crypto_aead_authsize(tfm), req->iv, 10861eb7b403SOfer Heifetz commands, results); 108789332590SAntoine Tenart sreq->rdescs = *results; 10881eb7b403SOfer Heifetz return ret; 10891eb7b403SOfer Heifetz } 10901eb7b403SOfer Heifetz 10918ac1283eSAntoine Tenart static int safexcel_cipher_exit_inv(struct crypto_tfm *tfm, 10928ac1283eSAntoine Tenart struct crypto_async_request *base, 10938ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 1094*acc3f550SHerbert Xu struct crypto_wait *result) 10951b44c5a6SAntoine Ténart { 10961b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 109718e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 109886671abbSAntoine Ténart int ring = ctx->base.ring; 1099*acc3f550SHerbert Xu int err; 11001b44c5a6SAntoine Ténart 11018ac1283eSAntoine Tenart ctx = crypto_tfm_ctx(base->tfm); 11021b44c5a6SAntoine Ténart ctx->base.exit_inv = true; 11031eb7b403SOfer Heifetz sreq->needs_inv = true; 11041b44c5a6SAntoine Ténart 110586671abbSAntoine Ténart spin_lock_bh(&priv->ring[ring].queue_lock); 11068ac1283eSAntoine Tenart crypto_enqueue_request(&priv->ring[ring].queue, base); 110786671abbSAntoine Ténart spin_unlock_bh(&priv->ring[ring].queue_lock); 11081b44c5a6SAntoine Ténart 11098472e778SAntoine Ténart queue_work(priv->ring[ring].workqueue, 11108472e778SAntoine Ténart &priv->ring[ring].work_data.work); 11111b44c5a6SAntoine Ténart 1112*acc3f550SHerbert Xu err = crypto_wait_req(-EINPROGRESS, result); 11131b44c5a6SAntoine Ténart 1114*acc3f550SHerbert Xu if (err) { 11151b44c5a6SAntoine Ténart dev_warn(priv->dev, 11161b44c5a6SAntoine Ténart "cipher: sync: invalidate: completion error %d\n", 1117*acc3f550SHerbert Xu err); 1118*acc3f550SHerbert Xu return err; 11191b44c5a6SAntoine Ténart } 11201b44c5a6SAntoine Ténart 11211b44c5a6SAntoine Ténart return 0; 11221b44c5a6SAntoine Ténart } 11231b44c5a6SAntoine Ténart 11248ac1283eSAntoine Tenart static int safexcel_skcipher_exit_inv(struct crypto_tfm *tfm) 11258ac1283eSAntoine Tenart { 11268ac1283eSAntoine Tenart EIP197_REQUEST_ON_STACK(req, skcipher, EIP197_SKCIPHER_REQ_SIZE); 11278ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 1128*acc3f550SHerbert Xu DECLARE_CRYPTO_WAIT(result); 11298ac1283eSAntoine Tenart 11308ac1283eSAntoine Tenart memset(req, 0, sizeof(struct skcipher_request)); 11318ac1283eSAntoine Tenart 11328ac1283eSAntoine Tenart skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 1133*acc3f550SHerbert Xu crypto_req_done, &result); 11348ac1283eSAntoine Tenart skcipher_request_set_tfm(req, __crypto_skcipher_cast(tfm)); 11358ac1283eSAntoine Tenart 11368ac1283eSAntoine Tenart return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result); 11378ac1283eSAntoine Tenart } 11388ac1283eSAntoine Tenart 1139f6beaea3SAntoine Tenart static int safexcel_aead_exit_inv(struct crypto_tfm *tfm) 1140f6beaea3SAntoine Tenart { 1141f6beaea3SAntoine Tenart EIP197_REQUEST_ON_STACK(req, aead, EIP197_AEAD_REQ_SIZE); 1142f6beaea3SAntoine Tenart struct safexcel_cipher_req *sreq = aead_request_ctx(req); 1143*acc3f550SHerbert Xu DECLARE_CRYPTO_WAIT(result); 1144f6beaea3SAntoine Tenart 1145f6beaea3SAntoine Tenart memset(req, 0, sizeof(struct aead_request)); 1146f6beaea3SAntoine Tenart 1147f6beaea3SAntoine Tenart aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 1148*acc3f550SHerbert Xu crypto_req_done, &result); 1149f6beaea3SAntoine Tenart aead_request_set_tfm(req, __crypto_aead_cast(tfm)); 1150f6beaea3SAntoine Tenart 1151f6beaea3SAntoine Tenart return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result); 1152f6beaea3SAntoine Tenart } 1153f6beaea3SAntoine Tenart 1154a7dea8c0SOfer Heifetz static int safexcel_queue_req(struct crypto_async_request *base, 11558ac1283eSAntoine Tenart struct safexcel_cipher_req *sreq, 115693369b5dSPascal van Leeuwen enum safexcel_cipher_direction dir) 11571b44c5a6SAntoine Ténart { 11588ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm); 115918e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 116086671abbSAntoine Ténart int ret, ring; 11611b44c5a6SAntoine Ténart 11621eb7b403SOfer Heifetz sreq->needs_inv = false; 1163847ccfc5SOfer Heifetz sreq->direction = dir; 11641b44c5a6SAntoine Ténart 11651b44c5a6SAntoine Ténart if (ctx->base.ctxr) { 116653c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE && ctx->base.needs_inv) { 11671eb7b403SOfer Heifetz sreq->needs_inv = true; 11681eb7b403SOfer Heifetz ctx->base.needs_inv = false; 11691eb7b403SOfer Heifetz } 11701b44c5a6SAntoine Ténart } else { 11711b44c5a6SAntoine Ténart ctx->base.ring = safexcel_select_ring(priv); 11721b44c5a6SAntoine Ténart ctx->base.ctxr = dma_pool_zalloc(priv->context_pool, 11738ac1283eSAntoine Tenart EIP197_GFP_FLAGS(*base), 11741b44c5a6SAntoine Ténart &ctx->base.ctxr_dma); 11751b44c5a6SAntoine Ténart if (!ctx->base.ctxr) 11761b44c5a6SAntoine Ténart return -ENOMEM; 11771b44c5a6SAntoine Ténart } 11781b44c5a6SAntoine Ténart 117986671abbSAntoine Ténart ring = ctx->base.ring; 11801b44c5a6SAntoine Ténart 118186671abbSAntoine Ténart spin_lock_bh(&priv->ring[ring].queue_lock); 11828ac1283eSAntoine Tenart ret = crypto_enqueue_request(&priv->ring[ring].queue, base); 118386671abbSAntoine Ténart spin_unlock_bh(&priv->ring[ring].queue_lock); 118486671abbSAntoine Ténart 11858472e778SAntoine Ténart queue_work(priv->ring[ring].workqueue, 11868472e778SAntoine Ténart &priv->ring[ring].work_data.work); 11871b44c5a6SAntoine Ténart 11881b44c5a6SAntoine Ténart return ret; 11891b44c5a6SAntoine Ténart } 11901b44c5a6SAntoine Ténart 119193369b5dSPascal van Leeuwen static int safexcel_encrypt(struct skcipher_request *req) 11921b44c5a6SAntoine Ténart { 1193a7dea8c0SOfer Heifetz return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 119493369b5dSPascal van Leeuwen SAFEXCEL_ENCRYPT); 11951b44c5a6SAntoine Ténart } 11961b44c5a6SAntoine Ténart 119793369b5dSPascal van Leeuwen static int safexcel_decrypt(struct skcipher_request *req) 11981b44c5a6SAntoine Ténart { 1199a7dea8c0SOfer Heifetz return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 120093369b5dSPascal van Leeuwen SAFEXCEL_DECRYPT); 12011b44c5a6SAntoine Ténart } 12021b44c5a6SAntoine Ténart 12031b44c5a6SAntoine Ténart static int safexcel_skcipher_cra_init(struct crypto_tfm *tfm) 12041b44c5a6SAntoine Ténart { 12051b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 12061b44c5a6SAntoine Ténart struct safexcel_alg_template *tmpl = 12071b44c5a6SAntoine Ténart container_of(tfm->__crt_alg, struct safexcel_alg_template, 12081b44c5a6SAntoine Ténart alg.skcipher.base); 12091b44c5a6SAntoine Ténart 12101eb7b403SOfer Heifetz crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), 12111eb7b403SOfer Heifetz sizeof(struct safexcel_cipher_req)); 12121b44c5a6SAntoine Ténart 121318e51895SHerbert Xu ctx->base.priv = tmpl->priv; 12148ac1283eSAntoine Tenart 12158ac1283eSAntoine Tenart ctx->base.send = safexcel_skcipher_send; 12168ac1283eSAntoine Tenart ctx->base.handle_result = safexcel_skcipher_handle_result; 1217098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD; 1218098e51e5SPascal van Leeuwen ctx->ctrinit = 1; 12198ac1283eSAntoine Tenart return 0; 12208ac1283eSAntoine Tenart } 12218ac1283eSAntoine Tenart 12228ac1283eSAntoine Tenart static int safexcel_cipher_cra_exit(struct crypto_tfm *tfm) 12238ac1283eSAntoine Tenart { 12248ac1283eSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 12258ac1283eSAntoine Tenart 1226ce679559SAntoine Tenart memzero_explicit(ctx->key, sizeof(ctx->key)); 12278ac1283eSAntoine Tenart 12288ac1283eSAntoine Tenart /* context not allocated, skip invalidation */ 12298ac1283eSAntoine Tenart if (!ctx->base.ctxr) 12308ac1283eSAntoine Tenart return -ENOMEM; 12318ac1283eSAntoine Tenart 1232ce679559SAntoine Tenart memzero_explicit(ctx->base.ctxr->data, sizeof(ctx->base.ctxr->data)); 12331b44c5a6SAntoine Ténart return 0; 12341b44c5a6SAntoine Ténart } 12351b44c5a6SAntoine Ténart 12361b44c5a6SAntoine Ténart static void safexcel_skcipher_cra_exit(struct crypto_tfm *tfm) 12371b44c5a6SAntoine Ténart { 12381b44c5a6SAntoine Ténart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 123918e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 12401b44c5a6SAntoine Ténart int ret; 12411b44c5a6SAntoine Ténart 12428ac1283eSAntoine Tenart if (safexcel_cipher_cra_exit(tfm)) 12431b44c5a6SAntoine Ténart return; 12441b44c5a6SAntoine Ténart 124553c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE) { 12468ac1283eSAntoine Tenart ret = safexcel_skcipher_exit_inv(tfm); 12471b44c5a6SAntoine Ténart if (ret) 12488ac1283eSAntoine Tenart dev_warn(priv->dev, "skcipher: invalidation error %d\n", 12498ac1283eSAntoine Tenart ret); 1250871df319SAntoine Ténart } else { 1251871df319SAntoine Ténart dma_pool_free(priv->context_pool, ctx->base.ctxr, 1252871df319SAntoine Ténart ctx->base.ctxr_dma); 1253871df319SAntoine Ténart } 12541b44c5a6SAntoine Ténart } 12551b44c5a6SAntoine Ténart 1256f6beaea3SAntoine Tenart static void safexcel_aead_cra_exit(struct crypto_tfm *tfm) 1257f6beaea3SAntoine Tenart { 1258f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 125918e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 1260f6beaea3SAntoine Tenart int ret; 1261f6beaea3SAntoine Tenart 1262f6beaea3SAntoine Tenart if (safexcel_cipher_cra_exit(tfm)) 1263f6beaea3SAntoine Tenart return; 1264f6beaea3SAntoine Tenart 126553c83e91SAntoine Tenart if (priv->flags & EIP197_TRC_CACHE) { 1266f6beaea3SAntoine Tenart ret = safexcel_aead_exit_inv(tfm); 1267f6beaea3SAntoine Tenart if (ret) 1268f6beaea3SAntoine Tenart dev_warn(priv->dev, "aead: invalidation error %d\n", 1269f6beaea3SAntoine Tenart ret); 1270f6beaea3SAntoine Tenart } else { 1271f6beaea3SAntoine Tenart dma_pool_free(priv->context_pool, ctx->base.ctxr, 1272f6beaea3SAntoine Tenart ctx->base.ctxr_dma); 1273f6beaea3SAntoine Tenart } 1274f6beaea3SAntoine Tenart } 1275f6beaea3SAntoine Tenart 127693369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_ecb_cra_init(struct crypto_tfm *tfm) 127793369b5dSPascal van Leeuwen { 127893369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 127993369b5dSPascal van Leeuwen 128093369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 128193369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 128293369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 1283098e51e5SPascal van Leeuwen ctx->blocksz = 0; 1284098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 128593369b5dSPascal van Leeuwen return 0; 128693369b5dSPascal van Leeuwen } 128793369b5dSPascal van Leeuwen 12881b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_ecb_aes = { 12891b44c5a6SAntoine Ténart .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1290062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES, 12911b44c5a6SAntoine Ténart .alg.skcipher = { 12928ac1283eSAntoine Tenart .setkey = safexcel_skcipher_aes_setkey, 129393369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 129493369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 12951b44c5a6SAntoine Ténart .min_keysize = AES_MIN_KEY_SIZE, 12961b44c5a6SAntoine Ténart .max_keysize = AES_MAX_KEY_SIZE, 12971b44c5a6SAntoine Ténart .base = { 12981b44c5a6SAntoine Ténart .cra_name = "ecb(aes)", 12991b44c5a6SAntoine Ténart .cra_driver_name = "safexcel-ecb-aes", 1300aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 13012c95e6d9SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1302b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 13031b44c5a6SAntoine Ténart CRYPTO_ALG_KERN_DRIVER_ONLY, 13041b44c5a6SAntoine Ténart .cra_blocksize = AES_BLOCK_SIZE, 13051b44c5a6SAntoine Ténart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 13061b44c5a6SAntoine Ténart .cra_alignmask = 0, 130793369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_ecb_cra_init, 13081b44c5a6SAntoine Ténart .cra_exit = safexcel_skcipher_cra_exit, 13091b44c5a6SAntoine Ténart .cra_module = THIS_MODULE, 13101b44c5a6SAntoine Ténart }, 13111b44c5a6SAntoine Ténart }, 13121b44c5a6SAntoine Ténart }; 13131b44c5a6SAntoine Ténart 131493369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_cbc_cra_init(struct crypto_tfm *tfm) 13151b44c5a6SAntoine Ténart { 131693369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 13171b44c5a6SAntoine Ténart 131893369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 131993369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 1320098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 132193369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 132293369b5dSPascal van Leeuwen return 0; 13231b44c5a6SAntoine Ténart } 13241b44c5a6SAntoine Ténart 13251b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_cbc_aes = { 13261b44c5a6SAntoine Ténart .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1327062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES, 13281b44c5a6SAntoine Ténart .alg.skcipher = { 13298ac1283eSAntoine Tenart .setkey = safexcel_skcipher_aes_setkey, 133093369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 133193369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 13321b44c5a6SAntoine Ténart .min_keysize = AES_MIN_KEY_SIZE, 13331b44c5a6SAntoine Ténart .max_keysize = AES_MAX_KEY_SIZE, 13341b44c5a6SAntoine Ténart .ivsize = AES_BLOCK_SIZE, 13351b44c5a6SAntoine Ténart .base = { 13361b44c5a6SAntoine Ténart .cra_name = "cbc(aes)", 13371b44c5a6SAntoine Ténart .cra_driver_name = "safexcel-cbc-aes", 1338aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 13392c95e6d9SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1340b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 13411b44c5a6SAntoine Ténart CRYPTO_ALG_KERN_DRIVER_ONLY, 13421b44c5a6SAntoine Ténart .cra_blocksize = AES_BLOCK_SIZE, 13431b44c5a6SAntoine Ténart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 13441b44c5a6SAntoine Ténart .cra_alignmask = 0, 134593369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_cbc_cra_init, 13461b44c5a6SAntoine Ténart .cra_exit = safexcel_skcipher_cra_exit, 13471b44c5a6SAntoine Ténart .cra_module = THIS_MODULE, 13481b44c5a6SAntoine Ténart }, 13491b44c5a6SAntoine Ténart }, 13501b44c5a6SAntoine Ténart }; 1351f6beaea3SAntoine Tenart 135248e97afaSPascal van Leeuwen static int safexcel_skcipher_aes_cfb_cra_init(struct crypto_tfm *tfm) 135348e97afaSPascal van Leeuwen { 135448e97afaSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 135548e97afaSPascal van Leeuwen 135648e97afaSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 135748e97afaSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 1358098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 135948e97afaSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; 136048e97afaSPascal van Leeuwen return 0; 136148e97afaSPascal van Leeuwen } 136248e97afaSPascal van Leeuwen 136348e97afaSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cfb_aes = { 136448e97afaSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 136548e97afaSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB, 136648e97afaSPascal van Leeuwen .alg.skcipher = { 136748e97afaSPascal van Leeuwen .setkey = safexcel_skcipher_aes_setkey, 136848e97afaSPascal van Leeuwen .encrypt = safexcel_encrypt, 136948e97afaSPascal van Leeuwen .decrypt = safexcel_decrypt, 137048e97afaSPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE, 137148e97afaSPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE, 137248e97afaSPascal van Leeuwen .ivsize = AES_BLOCK_SIZE, 137348e97afaSPascal van Leeuwen .base = { 137448e97afaSPascal van Leeuwen .cra_name = "cfb(aes)", 137548e97afaSPascal van Leeuwen .cra_driver_name = "safexcel-cfb-aes", 137648e97afaSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 137748e97afaSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1378b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 137948e97afaSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 138048e97afaSPascal van Leeuwen .cra_blocksize = 1, 138148e97afaSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 138248e97afaSPascal van Leeuwen .cra_alignmask = 0, 138348e97afaSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_cfb_cra_init, 138448e97afaSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 138548e97afaSPascal van Leeuwen .cra_module = THIS_MODULE, 138648e97afaSPascal van Leeuwen }, 138748e97afaSPascal van Leeuwen }, 138848e97afaSPascal van Leeuwen }; 138948e97afaSPascal van Leeuwen 139050485dfbSPascal van Leeuwen static int safexcel_skcipher_aes_ofb_cra_init(struct crypto_tfm *tfm) 139150485dfbSPascal van Leeuwen { 139250485dfbSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 139350485dfbSPascal van Leeuwen 139450485dfbSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 139550485dfbSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 1396098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 139750485dfbSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; 139850485dfbSPascal van Leeuwen return 0; 139950485dfbSPascal van Leeuwen } 140050485dfbSPascal van Leeuwen 140150485dfbSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ofb_aes = { 140250485dfbSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 140350485dfbSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB, 140450485dfbSPascal van Leeuwen .alg.skcipher = { 140550485dfbSPascal van Leeuwen .setkey = safexcel_skcipher_aes_setkey, 140650485dfbSPascal van Leeuwen .encrypt = safexcel_encrypt, 140750485dfbSPascal van Leeuwen .decrypt = safexcel_decrypt, 140850485dfbSPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE, 140950485dfbSPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE, 141050485dfbSPascal van Leeuwen .ivsize = AES_BLOCK_SIZE, 141150485dfbSPascal van Leeuwen .base = { 141250485dfbSPascal van Leeuwen .cra_name = "ofb(aes)", 141350485dfbSPascal van Leeuwen .cra_driver_name = "safexcel-ofb-aes", 141450485dfbSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 141550485dfbSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1416b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 141750485dfbSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 141850485dfbSPascal van Leeuwen .cra_blocksize = 1, 141950485dfbSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 142050485dfbSPascal van Leeuwen .cra_alignmask = 0, 142150485dfbSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_ofb_cra_init, 142250485dfbSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 142350485dfbSPascal van Leeuwen .cra_module = THIS_MODULE, 142450485dfbSPascal van Leeuwen }, 142550485dfbSPascal van Leeuwen }, 142650485dfbSPascal van Leeuwen }; 142750485dfbSPascal van Leeuwen 142854f9e8faSPascal van Leeuwen static int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm, 142954f9e8faSPascal van Leeuwen const u8 *key, unsigned int len) 143054f9e8faSPascal van Leeuwen { 143154f9e8faSPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 143254f9e8faSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 143318e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 143454f9e8faSPascal van Leeuwen struct crypto_aes_ctx aes; 143554f9e8faSPascal van Leeuwen int ret, i; 143654f9e8faSPascal van Leeuwen unsigned int keylen; 143754f9e8faSPascal van Leeuwen 143854f9e8faSPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 1439f26882a3SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 144054f9e8faSPascal van Leeuwen /* exclude the nonce here */ 1441f26882a3SPascal van Leeuwen keylen = len - CTR_RFC3686_NONCE_SIZE; 144254f9e8faSPascal van Leeuwen ret = aes_expandkey(&aes, key, keylen); 1443674f368aSEric Biggers if (ret) 144454f9e8faSPascal van Leeuwen return ret; 144554f9e8faSPascal van Leeuwen 144654f9e8faSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 144754f9e8faSPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) { 144813a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 144954f9e8faSPascal van Leeuwen ctx->base.needs_inv = true; 145054f9e8faSPascal van Leeuwen break; 145154f9e8faSPascal van Leeuwen } 145254f9e8faSPascal van Leeuwen } 145354f9e8faSPascal van Leeuwen } 145454f9e8faSPascal van Leeuwen 145554f9e8faSPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) 145654f9e8faSPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 145754f9e8faSPascal van Leeuwen 145854f9e8faSPascal van Leeuwen ctx->key_len = keylen; 145954f9e8faSPascal van Leeuwen 146054f9e8faSPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 146154f9e8faSPascal van Leeuwen return 0; 146254f9e8faSPascal van Leeuwen } 146354f9e8faSPascal van Leeuwen 146493369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_ctr_cra_init(struct crypto_tfm *tfm) 146593369b5dSPascal van Leeuwen { 146693369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 146793369b5dSPascal van Leeuwen 146893369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 146993369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 1470098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 147193369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 147293369b5dSPascal van Leeuwen return 0; 147393369b5dSPascal van Leeuwen } 147493369b5dSPascal van Leeuwen 147554f9e8faSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ctr_aes = { 147654f9e8faSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1477062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES, 147854f9e8faSPascal van Leeuwen .alg.skcipher = { 147954f9e8faSPascal van Leeuwen .setkey = safexcel_skcipher_aesctr_setkey, 148093369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 148193369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 1482f26882a3SPascal van Leeuwen /* Add nonce size */ 1483f26882a3SPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 1484f26882a3SPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 1485f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 148654f9e8faSPascal van Leeuwen .base = { 148754f9e8faSPascal van Leeuwen .cra_name = "rfc3686(ctr(aes))", 148854f9e8faSPascal van Leeuwen .cra_driver_name = "safexcel-ctr-aes", 1489aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 149054f9e8faSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1491b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 149254f9e8faSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 149354f9e8faSPascal van Leeuwen .cra_blocksize = 1, 149454f9e8faSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 149554f9e8faSPascal van Leeuwen .cra_alignmask = 0, 149693369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_aes_ctr_cra_init, 149754f9e8faSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 149854f9e8faSPascal van Leeuwen .cra_module = THIS_MODULE, 149954f9e8faSPascal van Leeuwen }, 150054f9e8faSPascal van Leeuwen }, 150154f9e8faSPascal van Leeuwen }; 150254f9e8faSPascal van Leeuwen 1503a7dea8c0SOfer Heifetz static int safexcel_des_setkey(struct crypto_skcipher *ctfm, const u8 *key, 1504a7dea8c0SOfer Heifetz unsigned int len) 1505a7dea8c0SOfer Heifetz { 150621f5a15eSArd Biesheuvel struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 150718e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 1508a7dea8c0SOfer Heifetz int ret; 1509a7dea8c0SOfer Heifetz 151021f5a15eSArd Biesheuvel ret = verify_skcipher_des_key(ctfm, key); 151121f5a15eSArd Biesheuvel if (ret) 151221f5a15eSArd Biesheuvel return ret; 1513a7dea8c0SOfer Heifetz 1514a7dea8c0SOfer Heifetz /* if context exits and key changed, need to invalidate it */ 1515177e358cSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 1516a7dea8c0SOfer Heifetz if (memcmp(ctx->key, key, len)) 1517a7dea8c0SOfer Heifetz ctx->base.needs_inv = true; 1518a7dea8c0SOfer Heifetz 1519a7dea8c0SOfer Heifetz memcpy(ctx->key, key, len); 1520a7dea8c0SOfer Heifetz ctx->key_len = len; 1521a7dea8c0SOfer Heifetz 1522a7dea8c0SOfer Heifetz return 0; 1523a7dea8c0SOfer Heifetz } 1524a7dea8c0SOfer Heifetz 152593369b5dSPascal van Leeuwen static int safexcel_skcipher_des_cbc_cra_init(struct crypto_tfm *tfm) 152693369b5dSPascal van Leeuwen { 152793369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 152893369b5dSPascal van Leeuwen 152993369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 153093369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; 1531098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 1532098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 153393369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 153493369b5dSPascal van Leeuwen return 0; 153593369b5dSPascal van Leeuwen } 153693369b5dSPascal van Leeuwen 1537a7dea8c0SOfer Heifetz struct safexcel_alg_template safexcel_alg_cbc_des = { 1538a7dea8c0SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1539062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 1540a7dea8c0SOfer Heifetz .alg.skcipher = { 1541a7dea8c0SOfer Heifetz .setkey = safexcel_des_setkey, 154293369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 154393369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 1544a7dea8c0SOfer Heifetz .min_keysize = DES_KEY_SIZE, 1545a7dea8c0SOfer Heifetz .max_keysize = DES_KEY_SIZE, 1546a7dea8c0SOfer Heifetz .ivsize = DES_BLOCK_SIZE, 1547a7dea8c0SOfer Heifetz .base = { 1548a7dea8c0SOfer Heifetz .cra_name = "cbc(des)", 1549a7dea8c0SOfer Heifetz .cra_driver_name = "safexcel-cbc-des", 1550aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 15512b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1552b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 1553a7dea8c0SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 1554a7dea8c0SOfer Heifetz .cra_blocksize = DES_BLOCK_SIZE, 1555a7dea8c0SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1556a7dea8c0SOfer Heifetz .cra_alignmask = 0, 155793369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des_cbc_cra_init, 1558a7dea8c0SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 1559a7dea8c0SOfer Heifetz .cra_module = THIS_MODULE, 1560a7dea8c0SOfer Heifetz }, 1561a7dea8c0SOfer Heifetz }, 1562a7dea8c0SOfer Heifetz }; 1563a7dea8c0SOfer Heifetz 156493369b5dSPascal van Leeuwen static int safexcel_skcipher_des_ecb_cra_init(struct crypto_tfm *tfm) 1565a7dea8c0SOfer Heifetz { 156693369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1567a7dea8c0SOfer Heifetz 156893369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 156993369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; 157093369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 1571098e51e5SPascal van Leeuwen ctx->blocksz = 0; 1572098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 157393369b5dSPascal van Leeuwen return 0; 1574a7dea8c0SOfer Heifetz } 1575a7dea8c0SOfer Heifetz 1576a7dea8c0SOfer Heifetz struct safexcel_alg_template safexcel_alg_ecb_des = { 1577a7dea8c0SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1578062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 1579a7dea8c0SOfer Heifetz .alg.skcipher = { 1580a7dea8c0SOfer Heifetz .setkey = safexcel_des_setkey, 158193369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 158293369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 1583a7dea8c0SOfer Heifetz .min_keysize = DES_KEY_SIZE, 1584a7dea8c0SOfer Heifetz .max_keysize = DES_KEY_SIZE, 1585a7dea8c0SOfer Heifetz .base = { 1586a7dea8c0SOfer Heifetz .cra_name = "ecb(des)", 1587a7dea8c0SOfer Heifetz .cra_driver_name = "safexcel-ecb-des", 1588aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 15892b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1590b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 1591a7dea8c0SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 1592a7dea8c0SOfer Heifetz .cra_blocksize = DES_BLOCK_SIZE, 1593a7dea8c0SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1594a7dea8c0SOfer Heifetz .cra_alignmask = 0, 159593369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des_ecb_cra_init, 1596a7dea8c0SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 1597a7dea8c0SOfer Heifetz .cra_module = THIS_MODULE, 1598a7dea8c0SOfer Heifetz }, 1599a7dea8c0SOfer Heifetz }, 1600a7dea8c0SOfer Heifetz }; 160162469879SOfer Heifetz 160262469879SOfer Heifetz static int safexcel_des3_ede_setkey(struct crypto_skcipher *ctfm, 160362469879SOfer Heifetz const u8 *key, unsigned int len) 160462469879SOfer Heifetz { 160567ac62bfSHerbert Xu struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 160618e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 160767ac62bfSHerbert Xu int err; 160862469879SOfer Heifetz 160921f5a15eSArd Biesheuvel err = verify_skcipher_des3_key(ctfm, key); 161021f5a15eSArd Biesheuvel if (err) 161167ac62bfSHerbert Xu return err; 161262469879SOfer Heifetz 161362469879SOfer Heifetz /* if context exits and key changed, need to invalidate it */ 1614177e358cSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 161562469879SOfer Heifetz if (memcmp(ctx->key, key, len)) 161662469879SOfer Heifetz ctx->base.needs_inv = true; 161762469879SOfer Heifetz 161862469879SOfer Heifetz memcpy(ctx->key, key, len); 161962469879SOfer Heifetz ctx->key_len = len; 162062469879SOfer Heifetz 162162469879SOfer Heifetz return 0; 162262469879SOfer Heifetz } 162362469879SOfer Heifetz 162493369b5dSPascal van Leeuwen static int safexcel_skcipher_des3_cbc_cra_init(struct crypto_tfm *tfm) 162593369b5dSPascal van Leeuwen { 162693369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 162793369b5dSPascal van Leeuwen 162893369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 162993369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; 1630098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 1631098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 163293369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 163393369b5dSPascal van Leeuwen return 0; 163493369b5dSPascal van Leeuwen } 163593369b5dSPascal van Leeuwen 163662469879SOfer Heifetz struct safexcel_alg_template safexcel_alg_cbc_des3_ede = { 163762469879SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1638062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 163962469879SOfer Heifetz .alg.skcipher = { 164062469879SOfer Heifetz .setkey = safexcel_des3_ede_setkey, 164193369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 164293369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 164362469879SOfer Heifetz .min_keysize = DES3_EDE_KEY_SIZE, 164462469879SOfer Heifetz .max_keysize = DES3_EDE_KEY_SIZE, 164562469879SOfer Heifetz .ivsize = DES3_EDE_BLOCK_SIZE, 164662469879SOfer Heifetz .base = { 164762469879SOfer Heifetz .cra_name = "cbc(des3_ede)", 164862469879SOfer Heifetz .cra_driver_name = "safexcel-cbc-des3_ede", 1649aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 16502b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1651b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 165262469879SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 165362469879SOfer Heifetz .cra_blocksize = DES3_EDE_BLOCK_SIZE, 165462469879SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 165562469879SOfer Heifetz .cra_alignmask = 0, 165693369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des3_cbc_cra_init, 165762469879SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 165862469879SOfer Heifetz .cra_module = THIS_MODULE, 165962469879SOfer Heifetz }, 166062469879SOfer Heifetz }, 166162469879SOfer Heifetz }; 166262469879SOfer Heifetz 166393369b5dSPascal van Leeuwen static int safexcel_skcipher_des3_ecb_cra_init(struct crypto_tfm *tfm) 166462469879SOfer Heifetz { 166593369b5dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 166662469879SOfer Heifetz 166793369b5dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 166893369b5dSPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; 166993369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 1670098e51e5SPascal van Leeuwen ctx->blocksz = 0; 1671098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 167293369b5dSPascal van Leeuwen return 0; 167362469879SOfer Heifetz } 167462469879SOfer Heifetz 167562469879SOfer Heifetz struct safexcel_alg_template safexcel_alg_ecb_des3_ede = { 167662469879SOfer Heifetz .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 1677062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES, 167862469879SOfer Heifetz .alg.skcipher = { 167962469879SOfer Heifetz .setkey = safexcel_des3_ede_setkey, 168093369b5dSPascal van Leeuwen .encrypt = safexcel_encrypt, 168193369b5dSPascal van Leeuwen .decrypt = safexcel_decrypt, 168262469879SOfer Heifetz .min_keysize = DES3_EDE_KEY_SIZE, 168362469879SOfer Heifetz .max_keysize = DES3_EDE_KEY_SIZE, 168462469879SOfer Heifetz .base = { 168562469879SOfer Heifetz .cra_name = "ecb(des3_ede)", 168662469879SOfer Heifetz .cra_driver_name = "safexcel-ecb-des3_ede", 1687aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 16882b78aeb3SEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1689b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 169062469879SOfer Heifetz CRYPTO_ALG_KERN_DRIVER_ONLY, 169162469879SOfer Heifetz .cra_blocksize = DES3_EDE_BLOCK_SIZE, 169262469879SOfer Heifetz .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 169362469879SOfer Heifetz .cra_alignmask = 0, 169493369b5dSPascal van Leeuwen .cra_init = safexcel_skcipher_des3_ecb_cra_init, 169562469879SOfer Heifetz .cra_exit = safexcel_skcipher_cra_exit, 169662469879SOfer Heifetz .cra_module = THIS_MODULE, 169762469879SOfer Heifetz }, 169862469879SOfer Heifetz }, 169962469879SOfer Heifetz }; 170062469879SOfer Heifetz 170193369b5dSPascal van Leeuwen static int safexcel_aead_encrypt(struct aead_request *req) 1702f6beaea3SAntoine Tenart { 1703f6beaea3SAntoine Tenart struct safexcel_cipher_req *creq = aead_request_ctx(req); 1704f6beaea3SAntoine Tenart 170593369b5dSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 1706f6beaea3SAntoine Tenart } 1707f6beaea3SAntoine Tenart 170893369b5dSPascal van Leeuwen static int safexcel_aead_decrypt(struct aead_request *req) 1709f6beaea3SAntoine Tenart { 1710f6beaea3SAntoine Tenart struct safexcel_cipher_req *creq = aead_request_ctx(req); 1711f6beaea3SAntoine Tenart 171293369b5dSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 1713f6beaea3SAntoine Tenart } 1714f6beaea3SAntoine Tenart 1715f6beaea3SAntoine Tenart static int safexcel_aead_cra_init(struct crypto_tfm *tfm) 1716f6beaea3SAntoine Tenart { 1717f6beaea3SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1718f6beaea3SAntoine Tenart struct safexcel_alg_template *tmpl = 1719f6beaea3SAntoine Tenart container_of(tfm->__crt_alg, struct safexcel_alg_template, 1720f6beaea3SAntoine Tenart alg.aead.base); 1721f6beaea3SAntoine Tenart 1722f6beaea3SAntoine Tenart crypto_aead_set_reqsize(__crypto_aead_cast(tfm), 1723f6beaea3SAntoine Tenart sizeof(struct safexcel_cipher_req)); 1724f6beaea3SAntoine Tenart 172518e51895SHerbert Xu ctx->base.priv = tmpl->priv; 1726f6beaea3SAntoine Tenart 17270e17e362SPascal van Leeuwen ctx->alg = SAFEXCEL_AES; /* default */ 1728098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 1729098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD; 1730098e51e5SPascal van Leeuwen ctx->ctrinit = 1; 173193369b5dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; /* default */ 1732f6beaea3SAntoine Tenart ctx->aead = true; 1733f6beaea3SAntoine Tenart ctx->base.send = safexcel_aead_send; 1734f6beaea3SAntoine Tenart ctx->base.handle_result = safexcel_aead_handle_result; 1735f6beaea3SAntoine Tenart return 0; 1736f6beaea3SAntoine Tenart } 1737f6beaea3SAntoine Tenart 173801ba061dSAntoine Tenart static int safexcel_aead_sha1_cra_init(struct crypto_tfm *tfm) 173901ba061dSAntoine Tenart { 174001ba061dSAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 174101ba061dSAntoine Tenart 174201ba061dSAntoine Tenart safexcel_aead_cra_init(tfm); 1743a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; 174401ba061dSAntoine Tenart ctx->state_sz = SHA1_DIGEST_SIZE; 174501ba061dSAntoine Tenart return 0; 174601ba061dSAntoine Tenart } 174701ba061dSAntoine Tenart 174801ba061dSAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_aes = { 174901ba061dSAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1750062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1, 175101ba061dSAntoine Tenart .alg.aead = { 175277cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 175393369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 175493369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 175501ba061dSAntoine Tenart .ivsize = AES_BLOCK_SIZE, 175601ba061dSAntoine Tenart .maxauthsize = SHA1_DIGEST_SIZE, 175701ba061dSAntoine Tenart .base = { 175801ba061dSAntoine Tenart .cra_name = "authenc(hmac(sha1),cbc(aes))", 175901ba061dSAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-aes", 1760aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 17613f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1762b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 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 | 1798b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 1799f6beaea3SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 1800f6beaea3SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 1801f6beaea3SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1802f6beaea3SAntoine Tenart .cra_alignmask = 0, 1803f6beaea3SAntoine Tenart .cra_init = safexcel_aead_sha256_cra_init, 1804f6beaea3SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 1805f6beaea3SAntoine Tenart .cra_module = THIS_MODULE, 1806f6beaea3SAntoine Tenart }, 1807f6beaea3SAntoine Tenart }, 1808f6beaea3SAntoine Tenart }; 1809678b2878SAntoine Tenart 1810678b2878SAntoine Tenart static int safexcel_aead_sha224_cra_init(struct crypto_tfm *tfm) 1811678b2878SAntoine Tenart { 1812678b2878SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1813678b2878SAntoine Tenart 1814678b2878SAntoine Tenart safexcel_aead_cra_init(tfm); 1815a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224; 1816678b2878SAntoine Tenart ctx->state_sz = SHA256_DIGEST_SIZE; 1817678b2878SAntoine Tenart return 0; 1818678b2878SAntoine Tenart } 1819678b2878SAntoine Tenart 1820678b2878SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_aes = { 1821678b2878SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1822062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 1823678b2878SAntoine Tenart .alg.aead = { 182477cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 182593369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 182693369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1827678b2878SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 1828678b2878SAntoine Tenart .maxauthsize = SHA224_DIGEST_SIZE, 1829678b2878SAntoine Tenart .base = { 1830678b2878SAntoine Tenart .cra_name = "authenc(hmac(sha224),cbc(aes))", 1831678b2878SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-aes", 1832aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 18333f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1834b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 1835678b2878SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 1836678b2878SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 1837678b2878SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1838678b2878SAntoine Tenart .cra_alignmask = 0, 1839678b2878SAntoine Tenart .cra_init = safexcel_aead_sha224_cra_init, 1840678b2878SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 1841678b2878SAntoine Tenart .cra_module = THIS_MODULE, 1842678b2878SAntoine Tenart }, 1843678b2878SAntoine Tenart }, 1844678b2878SAntoine Tenart }; 184587eee125SAntoine Tenart 184687eee125SAntoine Tenart static int safexcel_aead_sha512_cra_init(struct crypto_tfm *tfm) 184787eee125SAntoine Tenart { 184887eee125SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 184987eee125SAntoine Tenart 185087eee125SAntoine Tenart safexcel_aead_cra_init(tfm); 1851a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512; 185287eee125SAntoine Tenart ctx->state_sz = SHA512_DIGEST_SIZE; 185387eee125SAntoine Tenart return 0; 185487eee125SAntoine Tenart } 185587eee125SAntoine Tenart 185687eee125SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_aes = { 185787eee125SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1858062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 185987eee125SAntoine Tenart .alg.aead = { 186077cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 186193369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 186293369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 186387eee125SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 186487eee125SAntoine Tenart .maxauthsize = SHA512_DIGEST_SIZE, 186587eee125SAntoine Tenart .base = { 186687eee125SAntoine Tenart .cra_name = "authenc(hmac(sha512),cbc(aes))", 186787eee125SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-aes", 1868aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 18693f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1870b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 187187eee125SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 187287eee125SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 187387eee125SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 187487eee125SAntoine Tenart .cra_alignmask = 0, 187587eee125SAntoine Tenart .cra_init = safexcel_aead_sha512_cra_init, 187687eee125SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 187787eee125SAntoine Tenart .cra_module = THIS_MODULE, 187887eee125SAntoine Tenart }, 187987eee125SAntoine Tenart }, 188087eee125SAntoine Tenart }; 1881ea23cb53SAntoine Tenart 1882ea23cb53SAntoine Tenart static int safexcel_aead_sha384_cra_init(struct crypto_tfm *tfm) 1883ea23cb53SAntoine Tenart { 1884ea23cb53SAntoine Tenart struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1885ea23cb53SAntoine Tenart 1886ea23cb53SAntoine Tenart safexcel_aead_cra_init(tfm); 1887a7dea8c0SOfer Heifetz ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384; 1888ea23cb53SAntoine Tenart ctx->state_sz = SHA512_DIGEST_SIZE; 1889ea23cb53SAntoine Tenart return 0; 1890ea23cb53SAntoine Tenart } 1891ea23cb53SAntoine Tenart 1892ea23cb53SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_aes = { 1893ea23cb53SAntoine Tenart .type = SAFEXCEL_ALG_TYPE_AEAD, 1894062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 1895ea23cb53SAntoine Tenart .alg.aead = { 189677cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 189793369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 189893369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1899ea23cb53SAntoine Tenart .ivsize = AES_BLOCK_SIZE, 1900ea23cb53SAntoine Tenart .maxauthsize = SHA384_DIGEST_SIZE, 1901ea23cb53SAntoine Tenart .base = { 1902ea23cb53SAntoine Tenart .cra_name = "authenc(hmac(sha384),cbc(aes))", 1903ea23cb53SAntoine Tenart .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-aes", 1904aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 19053f4a537aSEric Biggers .cra_flags = CRYPTO_ALG_ASYNC | 1906b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 1907ea23cb53SAntoine Tenart CRYPTO_ALG_KERN_DRIVER_ONLY, 1908ea23cb53SAntoine Tenart .cra_blocksize = AES_BLOCK_SIZE, 1909ea23cb53SAntoine Tenart .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1910ea23cb53SAntoine Tenart .cra_alignmask = 0, 1911ea23cb53SAntoine Tenart .cra_init = safexcel_aead_sha384_cra_init, 1912ea23cb53SAntoine Tenart .cra_exit = safexcel_aead_cra_exit, 1913ea23cb53SAntoine Tenart .cra_module = THIS_MODULE, 1914ea23cb53SAntoine Tenart }, 1915ea23cb53SAntoine Tenart }, 1916ea23cb53SAntoine Tenart }; 191777cdd4efSPascal van Leeuwen 19180e17e362SPascal van Leeuwen static int safexcel_aead_sha1_des3_cra_init(struct crypto_tfm *tfm) 19190e17e362SPascal van Leeuwen { 19200e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 19210e17e362SPascal van Leeuwen 19220e17e362SPascal van Leeuwen safexcel_aead_sha1_cra_init(tfm); 19230e17e362SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1924098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 1925098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 19260e17e362SPascal van Leeuwen return 0; 19270e17e362SPascal van Leeuwen } 19280e17e362SPascal van Leeuwen 192977cdd4efSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des3_ede = { 193077cdd4efSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1931062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, 193277cdd4efSPascal van Leeuwen .alg.aead = { 193377cdd4efSPascal van Leeuwen .setkey = safexcel_aead_setkey, 193493369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 193593369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 193677cdd4efSPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 193777cdd4efSPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 193877cdd4efSPascal van Leeuwen .base = { 193977cdd4efSPascal van Leeuwen .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", 194077cdd4efSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des3_ede", 1941aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 194277cdd4efSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1943b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 194477cdd4efSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 194577cdd4efSPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 194677cdd4efSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 194777cdd4efSPascal van Leeuwen .cra_alignmask = 0, 19480e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha1_des3_cra_init, 19490e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 19500e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 19510e17e362SPascal van Leeuwen }, 19520e17e362SPascal van Leeuwen }, 19530e17e362SPascal van Leeuwen }; 19540e17e362SPascal van Leeuwen 1955f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha256_des3_cra_init(struct crypto_tfm *tfm) 1956f0a8bdf0SPascal van Leeuwen { 1957f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1958f0a8bdf0SPascal van Leeuwen 1959f0a8bdf0SPascal van Leeuwen safexcel_aead_sha256_cra_init(tfm); 1960f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1961098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 1962098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 1963f0a8bdf0SPascal van Leeuwen return 0; 1964f0a8bdf0SPascal van Leeuwen } 1965f0a8bdf0SPascal van Leeuwen 1966f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede = { 1967f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 1968f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 1969f0a8bdf0SPascal van Leeuwen .alg.aead = { 1970f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 1971f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 1972f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 1973f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 1974f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA256_DIGEST_SIZE, 1975f0a8bdf0SPascal van Leeuwen .base = { 1976f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", 1977f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des3_ede", 1978f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 1979f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 1980b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 1981f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 1982f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 1983f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 1984f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 1985f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha256_des3_cra_init, 1986f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 1987f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 1988f0a8bdf0SPascal van Leeuwen }, 1989f0a8bdf0SPascal van Leeuwen }, 1990f0a8bdf0SPascal van Leeuwen }; 1991f0a8bdf0SPascal van Leeuwen 1992f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha224_des3_cra_init(struct crypto_tfm *tfm) 1993f0a8bdf0SPascal van Leeuwen { 1994f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 1995f0a8bdf0SPascal van Leeuwen 1996f0a8bdf0SPascal van Leeuwen safexcel_aead_sha224_cra_init(tfm); 1997f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 1998098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 1999098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2000f0a8bdf0SPascal van Leeuwen return 0; 2001f0a8bdf0SPascal van Leeuwen } 2002f0a8bdf0SPascal van Leeuwen 2003f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede = { 2004f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2005f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 2006f0a8bdf0SPascal van Leeuwen .alg.aead = { 2007f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 2008f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2009f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2010f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 2011f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA224_DIGEST_SIZE, 2012f0a8bdf0SPascal van Leeuwen .base = { 2013f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha224),cbc(des3_ede))", 2014f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des3_ede", 2015f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2016f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2017b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2018f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2019f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2020f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2021f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 2022f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha224_des3_cra_init, 2023f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2024f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 2025f0a8bdf0SPascal van Leeuwen }, 2026f0a8bdf0SPascal van Leeuwen }, 2027f0a8bdf0SPascal van Leeuwen }; 2028f0a8bdf0SPascal van Leeuwen 2029f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha512_des3_cra_init(struct crypto_tfm *tfm) 2030f0a8bdf0SPascal van Leeuwen { 2031f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2032f0a8bdf0SPascal van Leeuwen 2033f0a8bdf0SPascal van Leeuwen safexcel_aead_sha512_cra_init(tfm); 2034f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 2035098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 2036098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2037f0a8bdf0SPascal van Leeuwen return 0; 2038f0a8bdf0SPascal van Leeuwen } 2039f0a8bdf0SPascal van Leeuwen 2040f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede = { 2041f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2042f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2043f0a8bdf0SPascal van Leeuwen .alg.aead = { 2044f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 2045f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2046f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2047f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 2048f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA512_DIGEST_SIZE, 2049f0a8bdf0SPascal van Leeuwen .base = { 2050f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha512),cbc(des3_ede))", 2051f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des3_ede", 2052f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2053f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2054b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2055f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2056f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2057f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2058f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 2059f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha512_des3_cra_init, 2060f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2061f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 2062f0a8bdf0SPascal van Leeuwen }, 2063f0a8bdf0SPascal van Leeuwen }, 2064f0a8bdf0SPascal van Leeuwen }; 2065f0a8bdf0SPascal van Leeuwen 2066f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha384_des3_cra_init(struct crypto_tfm *tfm) 2067f0a8bdf0SPascal van Leeuwen { 2068f0a8bdf0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2069f0a8bdf0SPascal van Leeuwen 2070f0a8bdf0SPascal van Leeuwen safexcel_aead_sha384_cra_init(tfm); 2071f0a8bdf0SPascal van Leeuwen ctx->alg = SAFEXCEL_3DES; /* override default */ 2072098e51e5SPascal van Leeuwen ctx->blocksz = DES3_EDE_BLOCK_SIZE; 2073098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2074f0a8bdf0SPascal van Leeuwen return 0; 2075f0a8bdf0SPascal van Leeuwen } 2076f0a8bdf0SPascal van Leeuwen 2077f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede = { 2078f0a8bdf0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2079f0a8bdf0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2080f0a8bdf0SPascal van Leeuwen .alg.aead = { 2081f0a8bdf0SPascal van Leeuwen .setkey = safexcel_aead_setkey, 2082f0a8bdf0SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2083f0a8bdf0SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2084f0a8bdf0SPascal van Leeuwen .ivsize = DES3_EDE_BLOCK_SIZE, 2085f0a8bdf0SPascal van Leeuwen .maxauthsize = SHA384_DIGEST_SIZE, 2086f0a8bdf0SPascal van Leeuwen .base = { 2087f0a8bdf0SPascal van Leeuwen .cra_name = "authenc(hmac(sha384),cbc(des3_ede))", 2088f0a8bdf0SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des3_ede", 2089f0a8bdf0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2090f0a8bdf0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2091b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2092f0a8bdf0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2093f0a8bdf0SPascal van Leeuwen .cra_blocksize = DES3_EDE_BLOCK_SIZE, 2094f0a8bdf0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2095f0a8bdf0SPascal van Leeuwen .cra_alignmask = 0, 2096f0a8bdf0SPascal van Leeuwen .cra_init = safexcel_aead_sha384_des3_cra_init, 2097f0a8bdf0SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2098f0a8bdf0SPascal van Leeuwen .cra_module = THIS_MODULE, 2099f0a8bdf0SPascal van Leeuwen }, 2100f0a8bdf0SPascal van Leeuwen }, 2101f0a8bdf0SPascal van Leeuwen }; 2102f0a8bdf0SPascal van Leeuwen 2103bb7679b8SPascal van Leeuwen static int safexcel_aead_sha1_des_cra_init(struct crypto_tfm *tfm) 2104bb7679b8SPascal van Leeuwen { 2105bb7679b8SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2106bb7679b8SPascal van Leeuwen 2107bb7679b8SPascal van Leeuwen safexcel_aead_sha1_cra_init(tfm); 2108bb7679b8SPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2109098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2110098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2111bb7679b8SPascal van Leeuwen return 0; 2112bb7679b8SPascal van Leeuwen } 2113bb7679b8SPascal van Leeuwen 2114bb7679b8SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des = { 2115bb7679b8SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2116bb7679b8SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, 2117bb7679b8SPascal van Leeuwen .alg.aead = { 2118bb7679b8SPascal van Leeuwen .setkey = safexcel_aead_setkey, 2119bb7679b8SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2120bb7679b8SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2121bb7679b8SPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2122bb7679b8SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 2123bb7679b8SPascal van Leeuwen .base = { 2124bb7679b8SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),cbc(des))", 2125bb7679b8SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des", 2126bb7679b8SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2127bb7679b8SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2128b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2129bb7679b8SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2130bb7679b8SPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2131bb7679b8SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2132bb7679b8SPascal van Leeuwen .cra_alignmask = 0, 2133bb7679b8SPascal van Leeuwen .cra_init = safexcel_aead_sha1_des_cra_init, 2134bb7679b8SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2135bb7679b8SPascal van Leeuwen .cra_module = THIS_MODULE, 2136bb7679b8SPascal van Leeuwen }, 2137bb7679b8SPascal van Leeuwen }, 2138bb7679b8SPascal van Leeuwen }; 2139bb7679b8SPascal van Leeuwen 2140457a6fdfSPascal van Leeuwen static int safexcel_aead_sha256_des_cra_init(struct crypto_tfm *tfm) 2141457a6fdfSPascal van Leeuwen { 2142457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2143457a6fdfSPascal van Leeuwen 2144457a6fdfSPascal van Leeuwen safexcel_aead_sha256_cra_init(tfm); 2145457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2146098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2147098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2148457a6fdfSPascal van Leeuwen return 0; 2149457a6fdfSPascal van Leeuwen } 2150457a6fdfSPascal van Leeuwen 2151457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des = { 2152457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2153457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 2154457a6fdfSPascal van Leeuwen .alg.aead = { 2155457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2156457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2157457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2158457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2159457a6fdfSPascal van Leeuwen .maxauthsize = SHA256_DIGEST_SIZE, 2160457a6fdfSPascal van Leeuwen .base = { 2161457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha256),cbc(des))", 2162457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des", 2163457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2164457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2165b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2166457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2167457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2168457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2169457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2170457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha256_des_cra_init, 2171457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2172457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2173457a6fdfSPascal van Leeuwen }, 2174457a6fdfSPascal van Leeuwen }, 2175457a6fdfSPascal van Leeuwen }; 2176457a6fdfSPascal van Leeuwen 2177457a6fdfSPascal van Leeuwen static int safexcel_aead_sha224_des_cra_init(struct crypto_tfm *tfm) 2178457a6fdfSPascal van Leeuwen { 2179457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2180457a6fdfSPascal van Leeuwen 2181457a6fdfSPascal van Leeuwen safexcel_aead_sha224_cra_init(tfm); 2182457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2183098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2184098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2185457a6fdfSPascal van Leeuwen return 0; 2186457a6fdfSPascal van Leeuwen } 2187457a6fdfSPascal van Leeuwen 2188457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des = { 2189457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2190457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, 2191457a6fdfSPascal van Leeuwen .alg.aead = { 2192457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2193457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2194457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2195457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2196457a6fdfSPascal van Leeuwen .maxauthsize = SHA224_DIGEST_SIZE, 2197457a6fdfSPascal van Leeuwen .base = { 2198457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha224),cbc(des))", 2199457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des", 2200457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2201457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2202b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2203457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2204457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2205457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2206457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2207457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha224_des_cra_init, 2208457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2209457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2210457a6fdfSPascal van Leeuwen }, 2211457a6fdfSPascal van Leeuwen }, 2212457a6fdfSPascal van Leeuwen }; 2213457a6fdfSPascal van Leeuwen 2214457a6fdfSPascal van Leeuwen static int safexcel_aead_sha512_des_cra_init(struct crypto_tfm *tfm) 2215457a6fdfSPascal van Leeuwen { 2216457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2217457a6fdfSPascal van Leeuwen 2218457a6fdfSPascal van Leeuwen safexcel_aead_sha512_cra_init(tfm); 2219457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2220098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2221098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2222457a6fdfSPascal van Leeuwen return 0; 2223457a6fdfSPascal van Leeuwen } 2224457a6fdfSPascal van Leeuwen 2225457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des = { 2226457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2227457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2228457a6fdfSPascal van Leeuwen .alg.aead = { 2229457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2230457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2231457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2232457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2233457a6fdfSPascal van Leeuwen .maxauthsize = SHA512_DIGEST_SIZE, 2234457a6fdfSPascal van Leeuwen .base = { 2235457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha512),cbc(des))", 2236457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des", 2237457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2238457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2239b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2240457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2241457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2242457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2243457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2244457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha512_des_cra_init, 2245457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2246457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2247457a6fdfSPascal van Leeuwen }, 2248457a6fdfSPascal van Leeuwen }, 2249457a6fdfSPascal van Leeuwen }; 2250457a6fdfSPascal van Leeuwen 2251457a6fdfSPascal van Leeuwen static int safexcel_aead_sha384_des_cra_init(struct crypto_tfm *tfm) 2252457a6fdfSPascal van Leeuwen { 2253457a6fdfSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2254457a6fdfSPascal van Leeuwen 2255457a6fdfSPascal van Leeuwen safexcel_aead_sha384_cra_init(tfm); 2256457a6fdfSPascal van Leeuwen ctx->alg = SAFEXCEL_DES; /* override default */ 2257098e51e5SPascal van Leeuwen ctx->blocksz = DES_BLOCK_SIZE; 2258098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 2259457a6fdfSPascal van Leeuwen return 0; 2260457a6fdfSPascal van Leeuwen } 2261457a6fdfSPascal van Leeuwen 2262457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des = { 2263457a6fdfSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2264457a6fdfSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, 2265457a6fdfSPascal van Leeuwen .alg.aead = { 2266457a6fdfSPascal van Leeuwen .setkey = safexcel_aead_setkey, 2267457a6fdfSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 2268457a6fdfSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2269457a6fdfSPascal van Leeuwen .ivsize = DES_BLOCK_SIZE, 2270457a6fdfSPascal van Leeuwen .maxauthsize = SHA384_DIGEST_SIZE, 2271457a6fdfSPascal van Leeuwen .base = { 2272457a6fdfSPascal van Leeuwen .cra_name = "authenc(hmac(sha384),cbc(des))", 2273457a6fdfSPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des", 2274457a6fdfSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2275457a6fdfSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2276b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2277457a6fdfSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2278457a6fdfSPascal van Leeuwen .cra_blocksize = DES_BLOCK_SIZE, 2279457a6fdfSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2280457a6fdfSPascal van Leeuwen .cra_alignmask = 0, 2281457a6fdfSPascal van Leeuwen .cra_init = safexcel_aead_sha384_des_cra_init, 2282457a6fdfSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 2283457a6fdfSPascal van Leeuwen .cra_module = THIS_MODULE, 2284457a6fdfSPascal van Leeuwen }, 2285457a6fdfSPascal van Leeuwen }, 2286457a6fdfSPascal van Leeuwen }; 2287457a6fdfSPascal van Leeuwen 22880e17e362SPascal van Leeuwen static int safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm *tfm) 22890e17e362SPascal van Leeuwen { 22900e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 22910e17e362SPascal van Leeuwen 22920e17e362SPascal van Leeuwen safexcel_aead_sha1_cra_init(tfm); 22930e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 22940e17e362SPascal van Leeuwen return 0; 22950e17e362SPascal van Leeuwen } 22960e17e362SPascal van Leeuwen 22970e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_aes = { 22980e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2299062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1, 23000e17e362SPascal van Leeuwen .alg.aead = { 23010e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 230293369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 230393369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2304f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 23050e17e362SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 23060e17e362SPascal van Leeuwen .base = { 23070e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))", 23080e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-aes", 2309aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 23100e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2311b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 23120e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 23130e17e362SPascal van Leeuwen .cra_blocksize = 1, 23140e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 23150e17e362SPascal van Leeuwen .cra_alignmask = 0, 23160e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha1_ctr_cra_init, 23170e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 23180e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 23190e17e362SPascal van Leeuwen }, 23200e17e362SPascal van Leeuwen }, 23210e17e362SPascal van Leeuwen }; 23220e17e362SPascal van Leeuwen 23230e17e362SPascal van Leeuwen static int safexcel_aead_sha256_ctr_cra_init(struct crypto_tfm *tfm) 23240e17e362SPascal van Leeuwen { 23250e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 23260e17e362SPascal van Leeuwen 23270e17e362SPascal van Leeuwen safexcel_aead_sha256_cra_init(tfm); 23280e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 23290e17e362SPascal van Leeuwen return 0; 23300e17e362SPascal van Leeuwen } 23310e17e362SPascal van Leeuwen 23320e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes = { 23330e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2334062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 23350e17e362SPascal van Leeuwen .alg.aead = { 23360e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 233793369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 233893369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2339f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 23400e17e362SPascal van Leeuwen .maxauthsize = SHA256_DIGEST_SIZE, 23410e17e362SPascal van Leeuwen .base = { 23420e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))", 23430e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha256-ctr-aes", 2344aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 23450e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2346b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 23470e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 23480e17e362SPascal van Leeuwen .cra_blocksize = 1, 23490e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 23500e17e362SPascal van Leeuwen .cra_alignmask = 0, 23510e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha256_ctr_cra_init, 23520e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 23530e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 23540e17e362SPascal van Leeuwen }, 23550e17e362SPascal van Leeuwen }, 23560e17e362SPascal van Leeuwen }; 23570e17e362SPascal van Leeuwen 23580e17e362SPascal van Leeuwen static int safexcel_aead_sha224_ctr_cra_init(struct crypto_tfm *tfm) 23590e17e362SPascal van Leeuwen { 23600e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 23610e17e362SPascal van Leeuwen 23620e17e362SPascal van Leeuwen safexcel_aead_sha224_cra_init(tfm); 23630e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 23640e17e362SPascal van Leeuwen return 0; 23650e17e362SPascal van Leeuwen } 23660e17e362SPascal van Leeuwen 23670e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_ctr_aes = { 23680e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2369062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256, 23700e17e362SPascal van Leeuwen .alg.aead = { 23710e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 237293369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 237393369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2374f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 23750e17e362SPascal van Leeuwen .maxauthsize = SHA224_DIGEST_SIZE, 23760e17e362SPascal van Leeuwen .base = { 23770e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))", 23780e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha224-ctr-aes", 2379aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 23800e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2381b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 23820e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 23830e17e362SPascal van Leeuwen .cra_blocksize = 1, 23840e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 23850e17e362SPascal van Leeuwen .cra_alignmask = 0, 23860e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha224_ctr_cra_init, 23870e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 23880e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 23890e17e362SPascal van Leeuwen }, 23900e17e362SPascal van Leeuwen }, 23910e17e362SPascal van Leeuwen }; 23920e17e362SPascal van Leeuwen 23930e17e362SPascal van Leeuwen static int safexcel_aead_sha512_ctr_cra_init(struct crypto_tfm *tfm) 23940e17e362SPascal van Leeuwen { 23950e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 23960e17e362SPascal van Leeuwen 23970e17e362SPascal van Leeuwen safexcel_aead_sha512_cra_init(tfm); 23980e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 23990e17e362SPascal van Leeuwen return 0; 24000e17e362SPascal van Leeuwen } 24010e17e362SPascal van Leeuwen 24020e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes = { 24030e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2404062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 24050e17e362SPascal van Leeuwen .alg.aead = { 24060e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 240793369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 240893369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2409f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 24100e17e362SPascal van Leeuwen .maxauthsize = SHA512_DIGEST_SIZE, 24110e17e362SPascal van Leeuwen .base = { 24120e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha512),rfc3686(ctr(aes)))", 24130e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha512-ctr-aes", 2414aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 24150e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2416b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 24170e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 24180e17e362SPascal van Leeuwen .cra_blocksize = 1, 24190e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 24200e17e362SPascal van Leeuwen .cra_alignmask = 0, 24210e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha512_ctr_cra_init, 24220e17e362SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 24230e17e362SPascal van Leeuwen .cra_module = THIS_MODULE, 24240e17e362SPascal van Leeuwen }, 24250e17e362SPascal van Leeuwen }, 24260e17e362SPascal van Leeuwen }; 24270e17e362SPascal van Leeuwen 24280e17e362SPascal van Leeuwen static int safexcel_aead_sha384_ctr_cra_init(struct crypto_tfm *tfm) 24290e17e362SPascal van Leeuwen { 24300e17e362SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 24310e17e362SPascal van Leeuwen 24320e17e362SPascal van Leeuwen safexcel_aead_sha384_cra_init(tfm); 24330e17e362SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */ 24340e17e362SPascal van Leeuwen return 0; 24350e17e362SPascal van Leeuwen } 24360e17e362SPascal van Leeuwen 24370e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes = { 24380e17e362SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 2439062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512, 24400e17e362SPascal van Leeuwen .alg.aead = { 24410e17e362SPascal van Leeuwen .setkey = safexcel_aead_setkey, 244293369b5dSPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 244393369b5dSPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 2444f26882a3SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 24450e17e362SPascal van Leeuwen .maxauthsize = SHA384_DIGEST_SIZE, 24460e17e362SPascal van Leeuwen .base = { 24470e17e362SPascal van Leeuwen .cra_name = "authenc(hmac(sha384),rfc3686(ctr(aes)))", 24480e17e362SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha384-ctr-aes", 2449aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 24500e17e362SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2451b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 24520e17e362SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 24530e17e362SPascal van Leeuwen .cra_blocksize = 1, 24540e17e362SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 24550e17e362SPascal van Leeuwen .cra_alignmask = 0, 24560e17e362SPascal van Leeuwen .cra_init = safexcel_aead_sha384_ctr_cra_init, 245777cdd4efSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 245877cdd4efSPascal van Leeuwen .cra_module = THIS_MODULE, 245977cdd4efSPascal van Leeuwen }, 246077cdd4efSPascal van Leeuwen }, 246177cdd4efSPascal van Leeuwen }; 2462c7da38a7SPascal van Leeuwen 2463c7da38a7SPascal van Leeuwen static int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm, 2464c7da38a7SPascal van Leeuwen const u8 *key, unsigned int len) 2465c7da38a7SPascal van Leeuwen { 2466c7da38a7SPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 2467c7da38a7SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 246818e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 2469c7da38a7SPascal van Leeuwen struct crypto_aes_ctx aes; 2470c7da38a7SPascal van Leeuwen int ret, i; 2471c7da38a7SPascal van Leeuwen unsigned int keylen; 2472c7da38a7SPascal van Leeuwen 2473c7da38a7SPascal van Leeuwen /* Check for illegal XTS keys */ 2474c7da38a7SPascal van Leeuwen ret = xts_verify_key(ctfm, key, len); 2475c7da38a7SPascal van Leeuwen if (ret) 2476c7da38a7SPascal van Leeuwen return ret; 2477c7da38a7SPascal van Leeuwen 2478c7da38a7SPascal van Leeuwen /* Only half of the key data is cipher key */ 2479c7da38a7SPascal van Leeuwen keylen = (len >> 1); 2480c7da38a7SPascal van Leeuwen ret = aes_expandkey(&aes, key, keylen); 2481674f368aSEric Biggers if (ret) 2482c7da38a7SPascal van Leeuwen return ret; 2483c7da38a7SPascal van Leeuwen 2484c7da38a7SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 2485c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) { 248613a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 2487c7da38a7SPascal van Leeuwen ctx->base.needs_inv = true; 2488c7da38a7SPascal van Leeuwen break; 2489c7da38a7SPascal van Leeuwen } 2490c7da38a7SPascal van Leeuwen } 2491c7da38a7SPascal van Leeuwen } 2492c7da38a7SPascal van Leeuwen 2493c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) 2494c7da38a7SPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 2495c7da38a7SPascal van Leeuwen 2496c7da38a7SPascal van Leeuwen /* The other half is the tweak key */ 2497c7da38a7SPascal van Leeuwen ret = aes_expandkey(&aes, (u8 *)(key + keylen), keylen); 2498674f368aSEric Biggers if (ret) 2499c7da38a7SPascal van Leeuwen return ret; 2500c7da38a7SPascal van Leeuwen 2501c7da38a7SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 2502c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) { 250313a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i + keylen / sizeof(u32)]) != 250413a1bb93SPascal van Leeuwen aes.key_enc[i]) { 2505c7da38a7SPascal van Leeuwen ctx->base.needs_inv = true; 2506c7da38a7SPascal van Leeuwen break; 2507c7da38a7SPascal van Leeuwen } 2508c7da38a7SPascal van Leeuwen } 2509c7da38a7SPascal van Leeuwen } 2510c7da38a7SPascal van Leeuwen 2511c7da38a7SPascal van Leeuwen for (i = 0; i < keylen / sizeof(u32); i++) 2512c7da38a7SPascal van Leeuwen ctx->key[i + keylen / sizeof(u32)] = 2513c7da38a7SPascal van Leeuwen cpu_to_le32(aes.key_enc[i]); 2514c7da38a7SPascal van Leeuwen 2515c7da38a7SPascal van Leeuwen ctx->key_len = keylen << 1; 2516c7da38a7SPascal van Leeuwen 2517c7da38a7SPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 2518c7da38a7SPascal van Leeuwen return 0; 2519c7da38a7SPascal van Leeuwen } 2520c7da38a7SPascal van Leeuwen 2521c7da38a7SPascal van Leeuwen static int safexcel_skcipher_aes_xts_cra_init(struct crypto_tfm *tfm) 2522c7da38a7SPascal van Leeuwen { 2523c7da38a7SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2524c7da38a7SPascal van Leeuwen 2525c7da38a7SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 2526c7da38a7SPascal van Leeuwen ctx->alg = SAFEXCEL_AES; 2527098e51e5SPascal van Leeuwen ctx->blocksz = AES_BLOCK_SIZE; 2528c7da38a7SPascal van Leeuwen ctx->xts = 1; 2529c7da38a7SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS; 2530c7da38a7SPascal van Leeuwen return 0; 2531c7da38a7SPascal van Leeuwen } 2532c7da38a7SPascal van Leeuwen 2533c7da38a7SPascal van Leeuwen static int safexcel_encrypt_xts(struct skcipher_request *req) 2534c7da38a7SPascal van Leeuwen { 2535c7da38a7SPascal van Leeuwen if (req->cryptlen < XTS_BLOCK_SIZE) 2536c7da38a7SPascal van Leeuwen return -EINVAL; 2537c7da38a7SPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 2538c7da38a7SPascal van Leeuwen SAFEXCEL_ENCRYPT); 2539c7da38a7SPascal van Leeuwen } 2540c7da38a7SPascal van Leeuwen 2541c7da38a7SPascal van Leeuwen static int safexcel_decrypt_xts(struct skcipher_request *req) 2542c7da38a7SPascal van Leeuwen { 2543c7da38a7SPascal van Leeuwen if (req->cryptlen < XTS_BLOCK_SIZE) 2544c7da38a7SPascal van Leeuwen return -EINVAL; 2545c7da38a7SPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 2546c7da38a7SPascal van Leeuwen SAFEXCEL_DECRYPT); 2547c7da38a7SPascal van Leeuwen } 2548c7da38a7SPascal van Leeuwen 2549c7da38a7SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_xts_aes = { 2550c7da38a7SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 2551062b64caSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XTS, 2552c7da38a7SPascal van Leeuwen .alg.skcipher = { 2553c7da38a7SPascal van Leeuwen .setkey = safexcel_skcipher_aesxts_setkey, 2554c7da38a7SPascal van Leeuwen .encrypt = safexcel_encrypt_xts, 2555c7da38a7SPascal van Leeuwen .decrypt = safexcel_decrypt_xts, 2556c7da38a7SPascal van Leeuwen /* XTS actually uses 2 AES keys glued together */ 2557c7da38a7SPascal van Leeuwen .min_keysize = AES_MIN_KEY_SIZE * 2, 2558c7da38a7SPascal van Leeuwen .max_keysize = AES_MAX_KEY_SIZE * 2, 2559c7da38a7SPascal van Leeuwen .ivsize = XTS_BLOCK_SIZE, 2560c7da38a7SPascal van Leeuwen .base = { 2561c7da38a7SPascal van Leeuwen .cra_name = "xts(aes)", 2562c7da38a7SPascal van Leeuwen .cra_driver_name = "safexcel-xts-aes", 2563aa88f331SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 2564c7da38a7SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2565b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 2566c7da38a7SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 2567c7da38a7SPascal van Leeuwen .cra_blocksize = XTS_BLOCK_SIZE, 2568c7da38a7SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 2569c7da38a7SPascal van Leeuwen .cra_alignmask = 0, 2570c7da38a7SPascal van Leeuwen .cra_init = safexcel_skcipher_aes_xts_cra_init, 2571c7da38a7SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 2572c7da38a7SPascal van Leeuwen .cra_module = THIS_MODULE, 2573c7da38a7SPascal van Leeuwen }, 2574c7da38a7SPascal van Leeuwen }, 2575c7da38a7SPascal van Leeuwen }; 25763e450886SPascal van Leeuwen 25773e450886SPascal van Leeuwen static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, 25783e450886SPascal van Leeuwen unsigned int len) 25793e450886SPascal van Leeuwen { 25803e450886SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 25813e450886SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 258218e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 25833e450886SPascal van Leeuwen struct crypto_aes_ctx aes; 25843e450886SPascal van Leeuwen u32 hashkey[AES_BLOCK_SIZE >> 2]; 25853e450886SPascal van Leeuwen int ret, i; 25863e450886SPascal van Leeuwen 25873e450886SPascal van Leeuwen ret = aes_expandkey(&aes, key, len); 25883e450886SPascal van Leeuwen if (ret) { 25893e450886SPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 25903e450886SPascal van Leeuwen return ret; 25913e450886SPascal van Leeuwen } 25923e450886SPascal van Leeuwen 25933e450886SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 25943e450886SPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) { 259513a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 25963e450886SPascal van Leeuwen ctx->base.needs_inv = true; 25973e450886SPascal van Leeuwen break; 25983e450886SPascal van Leeuwen } 25993e450886SPascal van Leeuwen } 26003e450886SPascal van Leeuwen } 26013e450886SPascal van Leeuwen 26023e450886SPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) 26033e450886SPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 26043e450886SPascal van Leeuwen 26053e450886SPascal van Leeuwen ctx->key_len = len; 26063e450886SPascal van Leeuwen 26073e450886SPascal van Leeuwen /* Compute hash key by encrypting zeroes with cipher key */ 26083e450886SPascal van Leeuwen memset(hashkey, 0, AES_BLOCK_SIZE); 2609320406cbSPeter Harliman Liem aes_encrypt(&aes, (u8 *)hashkey, (u8 *)hashkey); 26103e450886SPascal van Leeuwen 26113e450886SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 26123e450886SPascal van Leeuwen for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) { 261378cf1c8bSHerbert Xu if (be32_to_cpu(ctx->base.ipad.be[i]) != hashkey[i]) { 26143e450886SPascal van Leeuwen ctx->base.needs_inv = true; 26153e450886SPascal van Leeuwen break; 26163e450886SPascal van Leeuwen } 26173e450886SPascal van Leeuwen } 26183e450886SPascal van Leeuwen } 26193e450886SPascal van Leeuwen 26203e450886SPascal van Leeuwen for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) 262178cf1c8bSHerbert Xu ctx->base.ipad.be[i] = cpu_to_be32(hashkey[i]); 26223e450886SPascal van Leeuwen 26233e450886SPascal van Leeuwen memzero_explicit(hashkey, AES_BLOCK_SIZE); 26243e450886SPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 26253e450886SPascal van Leeuwen return 0; 26263e450886SPascal van Leeuwen } 26273e450886SPascal van Leeuwen 26283e450886SPascal van Leeuwen static int safexcel_aead_gcm_cra_init(struct crypto_tfm *tfm) 26293e450886SPascal van Leeuwen { 26303e450886SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 26313e450886SPascal van Leeuwen 26323e450886SPascal van Leeuwen safexcel_aead_cra_init(tfm); 26333e450886SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_GHASH; 26343e450886SPascal van Leeuwen ctx->state_sz = GHASH_BLOCK_SIZE; 26354eb76fafSPascal van Leeuwen ctx->xcm = EIP197_XCM_MODE_GCM; 26363e450886SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ 26373e450886SPascal van Leeuwen 2638320406cbSPeter Harliman Liem return 0; 26393e450886SPascal van Leeuwen } 26403e450886SPascal van Leeuwen 26413e450886SPascal van Leeuwen static void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm) 26423e450886SPascal van Leeuwen { 26433e450886SPascal van Leeuwen safexcel_aead_cra_exit(tfm); 26443e450886SPascal van Leeuwen } 26453e450886SPascal van Leeuwen 26463e450886SPascal van Leeuwen static int safexcel_aead_gcm_setauthsize(struct crypto_aead *tfm, 26473e450886SPascal van Leeuwen unsigned int authsize) 26483e450886SPascal van Leeuwen { 26493e450886SPascal van Leeuwen return crypto_gcm_check_authsize(authsize); 26503e450886SPascal van Leeuwen } 26513e450886SPascal van Leeuwen 26523e450886SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_gcm = { 26533e450886SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 26543e450886SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 26553e450886SPascal van Leeuwen .alg.aead = { 26563e450886SPascal van Leeuwen .setkey = safexcel_aead_gcm_setkey, 26573e450886SPascal van Leeuwen .setauthsize = safexcel_aead_gcm_setauthsize, 26583e450886SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 26593e450886SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 26603e450886SPascal van Leeuwen .ivsize = GCM_AES_IV_SIZE, 26613e450886SPascal van Leeuwen .maxauthsize = GHASH_DIGEST_SIZE, 26623e450886SPascal van Leeuwen .base = { 26633e450886SPascal van Leeuwen .cra_name = "gcm(aes)", 26643e450886SPascal van Leeuwen .cra_driver_name = "safexcel-gcm-aes", 26653e450886SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 26663e450886SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2667b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 26683e450886SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 26693e450886SPascal van Leeuwen .cra_blocksize = 1, 26703e450886SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 26713e450886SPascal van Leeuwen .cra_alignmask = 0, 26723e450886SPascal van Leeuwen .cra_init = safexcel_aead_gcm_cra_init, 26733e450886SPascal van Leeuwen .cra_exit = safexcel_aead_gcm_cra_exit, 26743e450886SPascal van Leeuwen .cra_module = THIS_MODULE, 26753e450886SPascal van Leeuwen }, 26763e450886SPascal van Leeuwen }, 26773e450886SPascal van Leeuwen }; 26784eb76fafSPascal van Leeuwen 26794eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, 26804eb76fafSPascal van Leeuwen unsigned int len) 26814eb76fafSPascal van Leeuwen { 26824eb76fafSPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 26834eb76fafSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 268418e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 26854eb76fafSPascal van Leeuwen struct crypto_aes_ctx aes; 26864eb76fafSPascal van Leeuwen int ret, i; 26874eb76fafSPascal van Leeuwen 26884eb76fafSPascal van Leeuwen ret = aes_expandkey(&aes, key, len); 26894eb76fafSPascal van Leeuwen if (ret) { 26904eb76fafSPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 26914eb76fafSPascal van Leeuwen return ret; 26924eb76fafSPascal van Leeuwen } 26934eb76fafSPascal van Leeuwen 26944eb76fafSPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { 26954eb76fafSPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) { 269613a1bb93SPascal van Leeuwen if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { 26974eb76fafSPascal van Leeuwen ctx->base.needs_inv = true; 26984eb76fafSPascal van Leeuwen break; 26994eb76fafSPascal van Leeuwen } 27004eb76fafSPascal van Leeuwen } 27014eb76fafSPascal van Leeuwen } 27024eb76fafSPascal van Leeuwen 27034eb76fafSPascal van Leeuwen for (i = 0; i < len / sizeof(u32); i++) { 27044eb76fafSPascal van Leeuwen ctx->key[i] = cpu_to_le32(aes.key_enc[i]); 270578cf1c8bSHerbert Xu ctx->base.ipad.be[i + 2 * AES_BLOCK_SIZE / sizeof(u32)] = 27064eb76fafSPascal van Leeuwen cpu_to_be32(aes.key_enc[i]); 27074eb76fafSPascal van Leeuwen } 27084eb76fafSPascal van Leeuwen 27094eb76fafSPascal van Leeuwen ctx->key_len = len; 27104eb76fafSPascal van Leeuwen ctx->state_sz = 2 * AES_BLOCK_SIZE + len; 27114eb76fafSPascal van Leeuwen 27124eb76fafSPascal van Leeuwen if (len == AES_KEYSIZE_192) 27134eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192; 27144eb76fafSPascal van Leeuwen else if (len == AES_KEYSIZE_256) 27154eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256; 27164eb76fafSPascal van Leeuwen else 27174eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; 27184eb76fafSPascal van Leeuwen 27194eb76fafSPascal van Leeuwen memzero_explicit(&aes, sizeof(aes)); 27204eb76fafSPascal van Leeuwen return 0; 27214eb76fafSPascal van Leeuwen } 27224eb76fafSPascal van Leeuwen 27234eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_cra_init(struct crypto_tfm *tfm) 27244eb76fafSPascal van Leeuwen { 27254eb76fafSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 27264eb76fafSPascal van Leeuwen 27274eb76fafSPascal van Leeuwen safexcel_aead_cra_init(tfm); 27284eb76fafSPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; 27294eb76fafSPascal van Leeuwen ctx->state_sz = 3 * AES_BLOCK_SIZE; 27304eb76fafSPascal van Leeuwen ctx->xcm = EIP197_XCM_MODE_CCM; 27314eb76fafSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ 2732098e51e5SPascal van Leeuwen ctx->ctrinit = 0; 27334eb76fafSPascal van Leeuwen return 0; 27344eb76fafSPascal van Leeuwen } 27354eb76fafSPascal van Leeuwen 27364eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_setauthsize(struct crypto_aead *tfm, 27374eb76fafSPascal van Leeuwen unsigned int authsize) 27384eb76fafSPascal van Leeuwen { 27394eb76fafSPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 27404eb76fafSPascal van Leeuwen switch (authsize) { 27414eb76fafSPascal van Leeuwen case 4: 27424eb76fafSPascal van Leeuwen case 6: 27434eb76fafSPascal van Leeuwen case 8: 27444eb76fafSPascal van Leeuwen case 10: 27454eb76fafSPascal van Leeuwen case 12: 27464eb76fafSPascal van Leeuwen case 14: 27474eb76fafSPascal van Leeuwen case 16: 27484eb76fafSPascal van Leeuwen break; 27494eb76fafSPascal van Leeuwen default: 27504eb76fafSPascal van Leeuwen return -EINVAL; 27514eb76fafSPascal van Leeuwen } 27524eb76fafSPascal van Leeuwen 27534eb76fafSPascal van Leeuwen return 0; 27544eb76fafSPascal van Leeuwen } 27554eb76fafSPascal van Leeuwen 27564eb76fafSPascal van Leeuwen static int safexcel_ccm_encrypt(struct aead_request *req) 27574eb76fafSPascal van Leeuwen { 27584eb76fafSPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 27594eb76fafSPascal van Leeuwen 27604eb76fafSPascal van Leeuwen if (req->iv[0] < 1 || req->iv[0] > 7) 27614eb76fafSPascal van Leeuwen return -EINVAL; 27624eb76fafSPascal van Leeuwen 27634eb76fafSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 27644eb76fafSPascal van Leeuwen } 27654eb76fafSPascal van Leeuwen 27664eb76fafSPascal van Leeuwen static int safexcel_ccm_decrypt(struct aead_request *req) 27674eb76fafSPascal van Leeuwen { 27684eb76fafSPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 27694eb76fafSPascal van Leeuwen 27704eb76fafSPascal van Leeuwen if (req->iv[0] < 1 || req->iv[0] > 7) 27714eb76fafSPascal van Leeuwen return -EINVAL; 27724eb76fafSPascal van Leeuwen 27734eb76fafSPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 27744eb76fafSPascal van Leeuwen } 27754eb76fafSPascal van Leeuwen 27764eb76fafSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ccm = { 27774eb76fafSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 27784eb76fafSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, 27794eb76fafSPascal van Leeuwen .alg.aead = { 27804eb76fafSPascal van Leeuwen .setkey = safexcel_aead_ccm_setkey, 27814eb76fafSPascal van Leeuwen .setauthsize = safexcel_aead_ccm_setauthsize, 27824eb76fafSPascal van Leeuwen .encrypt = safexcel_ccm_encrypt, 27834eb76fafSPascal van Leeuwen .decrypt = safexcel_ccm_decrypt, 27844eb76fafSPascal van Leeuwen .ivsize = AES_BLOCK_SIZE, 27854eb76fafSPascal van Leeuwen .maxauthsize = AES_BLOCK_SIZE, 27864eb76fafSPascal van Leeuwen .base = { 27874eb76fafSPascal van Leeuwen .cra_name = "ccm(aes)", 27884eb76fafSPascal van Leeuwen .cra_driver_name = "safexcel-ccm-aes", 27894eb76fafSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 27904eb76fafSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2791b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 27924eb76fafSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 27934eb76fafSPascal van Leeuwen .cra_blocksize = 1, 27944eb76fafSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 27954eb76fafSPascal van Leeuwen .cra_alignmask = 0, 27964eb76fafSPascal van Leeuwen .cra_init = safexcel_aead_ccm_cra_init, 27974eb76fafSPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 27984eb76fafSPascal van Leeuwen .cra_module = THIS_MODULE, 27994eb76fafSPascal van Leeuwen }, 28004eb76fafSPascal van Leeuwen }, 28014eb76fafSPascal van Leeuwen }; 28024a593fb3SPascal van Leeuwen 2803a6061921SPascal van Leeuwen static void safexcel_chacha20_setkey(struct safexcel_cipher_ctx *ctx, 2804a6061921SPascal van Leeuwen const u8 *key) 28054a593fb3SPascal van Leeuwen { 280618e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 28074a593fb3SPascal van Leeuwen 280813a1bb93SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 280913a1bb93SPascal van Leeuwen if (memcmp(ctx->key, key, CHACHA_KEY_SIZE)) 28104a593fb3SPascal van Leeuwen ctx->base.needs_inv = true; 28114a593fb3SPascal van Leeuwen 281213a1bb93SPascal van Leeuwen memcpy(ctx->key, key, CHACHA_KEY_SIZE); 28134a593fb3SPascal van Leeuwen ctx->key_len = CHACHA_KEY_SIZE; 2814a6061921SPascal van Leeuwen } 2815a6061921SPascal van Leeuwen 2816a6061921SPascal van Leeuwen static int safexcel_skcipher_chacha20_setkey(struct crypto_skcipher *ctfm, 2817a6061921SPascal van Leeuwen const u8 *key, unsigned int len) 2818a6061921SPascal van Leeuwen { 2819a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); 2820a6061921SPascal van Leeuwen 2821674f368aSEric Biggers if (len != CHACHA_KEY_SIZE) 2822a6061921SPascal van Leeuwen return -EINVAL; 2823674f368aSEric Biggers 2824a6061921SPascal van Leeuwen safexcel_chacha20_setkey(ctx, key); 28254a593fb3SPascal van Leeuwen 28264a593fb3SPascal van Leeuwen return 0; 28274a593fb3SPascal van Leeuwen } 28284a593fb3SPascal van Leeuwen 28294a593fb3SPascal van Leeuwen static int safexcel_skcipher_chacha20_cra_init(struct crypto_tfm *tfm) 28304a593fb3SPascal van Leeuwen { 28314a593fb3SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 28324a593fb3SPascal van Leeuwen 28334a593fb3SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 28344a593fb3SPascal van Leeuwen ctx->alg = SAFEXCEL_CHACHA20; 2835098e51e5SPascal van Leeuwen ctx->ctrinit = 0; 28364a593fb3SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32; 28374a593fb3SPascal van Leeuwen return 0; 28384a593fb3SPascal van Leeuwen } 28394a593fb3SPascal van Leeuwen 28404a593fb3SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chacha20 = { 28414a593fb3SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 28424a593fb3SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_CHACHA20, 28434a593fb3SPascal van Leeuwen .alg.skcipher = { 28444a593fb3SPascal van Leeuwen .setkey = safexcel_skcipher_chacha20_setkey, 28454a593fb3SPascal van Leeuwen .encrypt = safexcel_encrypt, 28464a593fb3SPascal van Leeuwen .decrypt = safexcel_decrypt, 28474a593fb3SPascal van Leeuwen .min_keysize = CHACHA_KEY_SIZE, 28484a593fb3SPascal van Leeuwen .max_keysize = CHACHA_KEY_SIZE, 28494a593fb3SPascal van Leeuwen .ivsize = CHACHA_IV_SIZE, 28504a593fb3SPascal van Leeuwen .base = { 28514a593fb3SPascal van Leeuwen .cra_name = "chacha20", 28524a593fb3SPascal van Leeuwen .cra_driver_name = "safexcel-chacha20", 28534a593fb3SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 28544a593fb3SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 2855b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 28564a593fb3SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 28574a593fb3SPascal van Leeuwen .cra_blocksize = 1, 28584a593fb3SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 28594a593fb3SPascal van Leeuwen .cra_alignmask = 0, 28604a593fb3SPascal van Leeuwen .cra_init = safexcel_skcipher_chacha20_cra_init, 28614a593fb3SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 28624a593fb3SPascal van Leeuwen .cra_module = THIS_MODULE, 28634a593fb3SPascal van Leeuwen }, 28644a593fb3SPascal van Leeuwen }, 28654a593fb3SPascal van Leeuwen }; 2866a6061921SPascal van Leeuwen 2867a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_setkey(struct crypto_aead *ctfm, 2868a6061921SPascal van Leeuwen const u8 *key, unsigned int len) 2869a6061921SPascal van Leeuwen { 2870a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_aead_ctx(ctfm); 2871a6061921SPascal van Leeuwen 2872a6061921SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP && 2873a6061921SPascal van Leeuwen len > EIP197_AEAD_IPSEC_NONCE_SIZE) { 2874a6061921SPascal van Leeuwen /* ESP variant has nonce appended to key */ 2875a6061921SPascal van Leeuwen len -= EIP197_AEAD_IPSEC_NONCE_SIZE; 2876a6061921SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len); 2877a6061921SPascal van Leeuwen } 2878674f368aSEric Biggers if (len != CHACHA_KEY_SIZE) 2879a6061921SPascal van Leeuwen return -EINVAL; 2880674f368aSEric Biggers 2881a6061921SPascal van Leeuwen safexcel_chacha20_setkey(ctx, key); 2882a6061921SPascal van Leeuwen 2883a6061921SPascal van Leeuwen return 0; 2884a6061921SPascal van Leeuwen } 2885a6061921SPascal van Leeuwen 2886a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_setauthsize(struct crypto_aead *tfm, 2887a6061921SPascal van Leeuwen unsigned int authsize) 2888a6061921SPascal van Leeuwen { 2889a6061921SPascal van Leeuwen if (authsize != POLY1305_DIGEST_SIZE) 2890a6061921SPascal van Leeuwen return -EINVAL; 2891a6061921SPascal van Leeuwen return 0; 2892a6061921SPascal van Leeuwen } 2893a6061921SPascal van Leeuwen 2894a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_crypt(struct aead_request *req, 2895a6061921SPascal van Leeuwen enum safexcel_cipher_direction dir) 2896a6061921SPascal van Leeuwen { 2897a6061921SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 2898a6061921SPascal van Leeuwen struct crypto_aead *aead = crypto_aead_reqtfm(req); 2899a6061921SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(aead); 2900a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2901a6061921SPascal van Leeuwen struct aead_request *subreq = aead_request_ctx(req); 2902a6061921SPascal van Leeuwen u32 key[CHACHA_KEY_SIZE / sizeof(u32) + 1]; 290313a1bb93SPascal van Leeuwen int ret = 0; 2904a6061921SPascal van Leeuwen 2905a6061921SPascal van Leeuwen /* 2906a6061921SPascal van Leeuwen * Instead of wasting time detecting umpteen silly corner cases, 2907a6061921SPascal van Leeuwen * just dump all "small" requests to the fallback implementation. 2908a6061921SPascal van Leeuwen * HW would not be faster on such small requests anyway. 2909a6061921SPascal van Leeuwen */ 2910a6061921SPascal van Leeuwen if (likely((ctx->aead != EIP197_AEAD_TYPE_IPSEC_ESP || 2911a6061921SPascal van Leeuwen req->assoclen >= EIP197_AEAD_IPSEC_IV_SIZE) && 2912a6061921SPascal van Leeuwen req->cryptlen > POLY1305_DIGEST_SIZE)) { 2913a6061921SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, dir); 2914a6061921SPascal van Leeuwen } 2915a6061921SPascal van Leeuwen 2916a6061921SPascal van Leeuwen /* HW cannot do full (AAD+payload) zero length, use fallback */ 291713a1bb93SPascal van Leeuwen memcpy(key, ctx->key, CHACHA_KEY_SIZE); 2918a6061921SPascal van Leeuwen if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { 2919a6061921SPascal van Leeuwen /* ESP variant has nonce appended to the key */ 2920a6061921SPascal van Leeuwen key[CHACHA_KEY_SIZE / sizeof(u32)] = ctx->nonce; 2921a6061921SPascal van Leeuwen ret = crypto_aead_setkey(ctx->fback, (u8 *)key, 2922a6061921SPascal van Leeuwen CHACHA_KEY_SIZE + 2923a6061921SPascal van Leeuwen EIP197_AEAD_IPSEC_NONCE_SIZE); 2924a6061921SPascal van Leeuwen } else { 2925a6061921SPascal van Leeuwen ret = crypto_aead_setkey(ctx->fback, (u8 *)key, 2926a6061921SPascal van Leeuwen CHACHA_KEY_SIZE); 2927a6061921SPascal van Leeuwen } 2928a6061921SPascal van Leeuwen if (ret) { 2929a6061921SPascal van Leeuwen crypto_aead_clear_flags(aead, CRYPTO_TFM_REQ_MASK); 2930a6061921SPascal van Leeuwen crypto_aead_set_flags(aead, crypto_aead_get_flags(ctx->fback) & 2931a6061921SPascal van Leeuwen CRYPTO_TFM_REQ_MASK); 2932a6061921SPascal van Leeuwen return ret; 2933a6061921SPascal van Leeuwen } 2934a6061921SPascal van Leeuwen 2935a6061921SPascal van Leeuwen aead_request_set_tfm(subreq, ctx->fback); 2936a6061921SPascal van Leeuwen aead_request_set_callback(subreq, req->base.flags, req->base.complete, 2937a6061921SPascal van Leeuwen req->base.data); 2938a6061921SPascal van Leeuwen aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 2939a6061921SPascal van Leeuwen req->iv); 2940a6061921SPascal van Leeuwen aead_request_set_ad(subreq, req->assoclen); 2941a6061921SPascal van Leeuwen 2942a6061921SPascal van Leeuwen return (dir == SAFEXCEL_ENCRYPT) ? 2943a6061921SPascal van Leeuwen crypto_aead_encrypt(subreq) : 2944a6061921SPascal van Leeuwen crypto_aead_decrypt(subreq); 2945a6061921SPascal van Leeuwen } 2946a6061921SPascal van Leeuwen 2947a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_encrypt(struct aead_request *req) 2948a6061921SPascal van Leeuwen { 2949a6061921SPascal van Leeuwen return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_ENCRYPT); 2950a6061921SPascal van Leeuwen } 2951a6061921SPascal van Leeuwen 2952a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_decrypt(struct aead_request *req) 2953a6061921SPascal van Leeuwen { 2954a6061921SPascal van Leeuwen return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_DECRYPT); 2955a6061921SPascal van Leeuwen } 2956a6061921SPascal van Leeuwen 29571769f704SPascal van Leeuwen static int safexcel_aead_fallback_cra_init(struct crypto_tfm *tfm) 2958a6061921SPascal van Leeuwen { 2959a6061921SPascal van Leeuwen struct crypto_aead *aead = __crypto_aead_cast(tfm); 2960a6061921SPascal van Leeuwen struct aead_alg *alg = crypto_aead_alg(aead); 2961a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2962a6061921SPascal van Leeuwen 2963a6061921SPascal van Leeuwen safexcel_aead_cra_init(tfm); 2964a6061921SPascal van Leeuwen 2965a6061921SPascal van Leeuwen /* Allocate fallback implementation */ 2966a6061921SPascal van Leeuwen ctx->fback = crypto_alloc_aead(alg->base.cra_name, 0, 2967a6061921SPascal van Leeuwen CRYPTO_ALG_ASYNC | 2968a6061921SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK); 2969a6061921SPascal van Leeuwen if (IS_ERR(ctx->fback)) 2970a6061921SPascal van Leeuwen return PTR_ERR(ctx->fback); 2971a6061921SPascal van Leeuwen 2972a6061921SPascal van Leeuwen crypto_aead_set_reqsize(aead, max(sizeof(struct safexcel_cipher_req), 2973a6061921SPascal van Leeuwen sizeof(struct aead_request) + 2974a6061921SPascal van Leeuwen crypto_aead_reqsize(ctx->fback))); 2975a6061921SPascal van Leeuwen 2976a6061921SPascal van Leeuwen return 0; 2977a6061921SPascal van Leeuwen } 2978a6061921SPascal van Leeuwen 29791769f704SPascal van Leeuwen static int safexcel_aead_chachapoly_cra_init(struct crypto_tfm *tfm) 29801769f704SPascal van Leeuwen { 29811769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 29821769f704SPascal van Leeuwen 29831769f704SPascal van Leeuwen safexcel_aead_fallback_cra_init(tfm); 29841769f704SPascal van Leeuwen ctx->alg = SAFEXCEL_CHACHA20; 29851769f704SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32 | 29861769f704SPascal van Leeuwen CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK; 2987098e51e5SPascal van Leeuwen ctx->ctrinit = 0; 29881769f704SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_POLY1305; 29891769f704SPascal van Leeuwen ctx->state_sz = 0; /* Precomputed by HW */ 29901769f704SPascal van Leeuwen return 0; 29911769f704SPascal van Leeuwen } 29921769f704SPascal van Leeuwen 29931769f704SPascal van Leeuwen static void safexcel_aead_fallback_cra_exit(struct crypto_tfm *tfm) 2994a6061921SPascal van Leeuwen { 2995a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 2996a6061921SPascal van Leeuwen 2997a6061921SPascal van Leeuwen crypto_free_aead(ctx->fback); 2998a6061921SPascal van Leeuwen safexcel_aead_cra_exit(tfm); 2999a6061921SPascal van Leeuwen } 3000a6061921SPascal van Leeuwen 3001a6061921SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chachapoly = { 3002a6061921SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3003a6061921SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, 3004a6061921SPascal van Leeuwen .alg.aead = { 3005a6061921SPascal van Leeuwen .setkey = safexcel_aead_chachapoly_setkey, 3006a6061921SPascal van Leeuwen .setauthsize = safexcel_aead_chachapoly_setauthsize, 3007a6061921SPascal van Leeuwen .encrypt = safexcel_aead_chachapoly_encrypt, 3008a6061921SPascal van Leeuwen .decrypt = safexcel_aead_chachapoly_decrypt, 3009a6061921SPascal van Leeuwen .ivsize = CHACHAPOLY_IV_SIZE, 3010a6061921SPascal van Leeuwen .maxauthsize = POLY1305_DIGEST_SIZE, 3011a6061921SPascal van Leeuwen .base = { 3012a6061921SPascal van Leeuwen .cra_name = "rfc7539(chacha20,poly1305)", 3013a6061921SPascal van Leeuwen .cra_driver_name = "safexcel-chacha20-poly1305", 3014a6061921SPascal van Leeuwen /* +1 to put it above HW chacha + SW poly */ 3015a6061921SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, 3016a6061921SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3017b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 3018a6061921SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY | 3019a6061921SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK, 3020a6061921SPascal van Leeuwen .cra_blocksize = 1, 3021a6061921SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3022a6061921SPascal van Leeuwen .cra_alignmask = 0, 3023a6061921SPascal van Leeuwen .cra_init = safexcel_aead_chachapoly_cra_init, 30241769f704SPascal van Leeuwen .cra_exit = safexcel_aead_fallback_cra_exit, 3025a6061921SPascal van Leeuwen .cra_module = THIS_MODULE, 3026a6061921SPascal van Leeuwen }, 3027a6061921SPascal van Leeuwen }, 3028a6061921SPascal van Leeuwen }; 3029a6061921SPascal van Leeuwen 3030a6061921SPascal van Leeuwen static int safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm *tfm) 3031a6061921SPascal van Leeuwen { 3032a6061921SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3033a6061921SPascal van Leeuwen int ret; 3034a6061921SPascal van Leeuwen 3035a6061921SPascal van Leeuwen ret = safexcel_aead_chachapoly_cra_init(tfm); 3036a6061921SPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 3037098e51e5SPascal van Leeuwen ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 3038a6061921SPascal van Leeuwen return ret; 3039a6061921SPascal van Leeuwen } 3040a6061921SPascal van Leeuwen 3041a6061921SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chachapoly_esp = { 3042a6061921SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3043a6061921SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, 3044a6061921SPascal van Leeuwen .alg.aead = { 3045a6061921SPascal van Leeuwen .setkey = safexcel_aead_chachapoly_setkey, 3046a6061921SPascal van Leeuwen .setauthsize = safexcel_aead_chachapoly_setauthsize, 3047a6061921SPascal van Leeuwen .encrypt = safexcel_aead_chachapoly_encrypt, 3048a6061921SPascal van Leeuwen .decrypt = safexcel_aead_chachapoly_decrypt, 3049a6061921SPascal van Leeuwen .ivsize = CHACHAPOLY_IV_SIZE - EIP197_AEAD_IPSEC_NONCE_SIZE, 3050a6061921SPascal van Leeuwen .maxauthsize = POLY1305_DIGEST_SIZE, 3051a6061921SPascal van Leeuwen .base = { 3052a6061921SPascal van Leeuwen .cra_name = "rfc7539esp(chacha20,poly1305)", 3053a6061921SPascal van Leeuwen .cra_driver_name = "safexcel-chacha20-poly1305-esp", 3054a6061921SPascal van Leeuwen /* +1 to put it above HW chacha + SW poly */ 3055a6061921SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, 3056a6061921SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3057b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 3058a6061921SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY | 3059a6061921SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK, 3060a6061921SPascal van Leeuwen .cra_blocksize = 1, 3061a6061921SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3062a6061921SPascal van Leeuwen .cra_alignmask = 0, 3063a6061921SPascal van Leeuwen .cra_init = safexcel_aead_chachapolyesp_cra_init, 30641769f704SPascal van Leeuwen .cra_exit = safexcel_aead_fallback_cra_exit, 3065a6061921SPascal van Leeuwen .cra_module = THIS_MODULE, 3066a6061921SPascal van Leeuwen }, 3067a6061921SPascal van Leeuwen }, 3068a6061921SPascal van Leeuwen }; 3069fcca797dSPascal van Leeuwen 3070fcca797dSPascal van Leeuwen static int safexcel_skcipher_sm4_setkey(struct crypto_skcipher *ctfm, 3071fcca797dSPascal van Leeuwen const u8 *key, unsigned int len) 3072fcca797dSPascal van Leeuwen { 3073fcca797dSPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 3074fcca797dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 307518e51895SHerbert Xu struct safexcel_crypto_priv *priv = ctx->base.priv; 3076fcca797dSPascal van Leeuwen 3077674f368aSEric Biggers if (len != SM4_KEY_SIZE) 3078fcca797dSPascal van Leeuwen return -EINVAL; 3079fcca797dSPascal van Leeuwen 308013a1bb93SPascal van Leeuwen if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) 308113a1bb93SPascal van Leeuwen if (memcmp(ctx->key, key, SM4_KEY_SIZE)) 3082fcca797dSPascal van Leeuwen ctx->base.needs_inv = true; 3083fcca797dSPascal van Leeuwen 308413a1bb93SPascal van Leeuwen memcpy(ctx->key, key, SM4_KEY_SIZE); 3085fcca797dSPascal van Leeuwen ctx->key_len = SM4_KEY_SIZE; 3086fcca797dSPascal van Leeuwen 3087fcca797dSPascal van Leeuwen return 0; 3088fcca797dSPascal van Leeuwen } 3089fcca797dSPascal van Leeuwen 3090fcca797dSPascal van Leeuwen static int safexcel_sm4_blk_encrypt(struct skcipher_request *req) 3091fcca797dSPascal van Leeuwen { 3092fcca797dSPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 3093fcca797dSPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 3094fcca797dSPascal van Leeuwen return -EINVAL; 3095fcca797dSPascal van Leeuwen else 3096fcca797dSPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 3097fcca797dSPascal van Leeuwen SAFEXCEL_ENCRYPT); 3098fcca797dSPascal van Leeuwen } 3099fcca797dSPascal van Leeuwen 3100fcca797dSPascal van Leeuwen static int safexcel_sm4_blk_decrypt(struct skcipher_request *req) 3101fcca797dSPascal van Leeuwen { 3102fcca797dSPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 3103fcca797dSPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 3104fcca797dSPascal van Leeuwen return -EINVAL; 3105fcca797dSPascal van Leeuwen else 3106fcca797dSPascal van Leeuwen return safexcel_queue_req(&req->base, skcipher_request_ctx(req), 3107fcca797dSPascal van Leeuwen SAFEXCEL_DECRYPT); 3108fcca797dSPascal van Leeuwen } 3109fcca797dSPascal van Leeuwen 3110fcca797dSPascal van Leeuwen static int safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm *tfm) 3111fcca797dSPascal van Leeuwen { 3112fcca797dSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3113fcca797dSPascal van Leeuwen 3114fcca797dSPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 3115fcca797dSPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3116fcca797dSPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; 3117098e51e5SPascal van Leeuwen ctx->blocksz = 0; 3118098e51e5SPascal van Leeuwen ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; 3119fcca797dSPascal van Leeuwen return 0; 3120fcca797dSPascal van Leeuwen } 3121fcca797dSPascal van Leeuwen 3122fcca797dSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ecb_sm4 = { 3123fcca797dSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 3124fcca797dSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4, 3125fcca797dSPascal van Leeuwen .alg.skcipher = { 3126fcca797dSPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 3127fcca797dSPascal van Leeuwen .encrypt = safexcel_sm4_blk_encrypt, 3128fcca797dSPascal van Leeuwen .decrypt = safexcel_sm4_blk_decrypt, 3129fcca797dSPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 3130fcca797dSPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 3131fcca797dSPascal van Leeuwen .base = { 3132fcca797dSPascal van Leeuwen .cra_name = "ecb(sm4)", 3133fcca797dSPascal van Leeuwen .cra_driver_name = "safexcel-ecb-sm4", 3134fcca797dSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3135fcca797dSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3136b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 3137fcca797dSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3138fcca797dSPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 3139fcca797dSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3140fcca797dSPascal van Leeuwen .cra_alignmask = 0, 3141fcca797dSPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_ecb_cra_init, 3142fcca797dSPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 3143fcca797dSPascal van Leeuwen .cra_module = THIS_MODULE, 3144fcca797dSPascal van Leeuwen }, 3145fcca797dSPascal van Leeuwen }, 3146fcca797dSPascal van Leeuwen }; 31476f2d1428SPascal van Leeuwen 31486f2d1428SPascal van Leeuwen static int safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm *tfm) 31496f2d1428SPascal van Leeuwen { 31506f2d1428SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 31516f2d1428SPascal van Leeuwen 31526f2d1428SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 31536f2d1428SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3154098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 31556f2d1428SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; 31566f2d1428SPascal van Leeuwen return 0; 31576f2d1428SPascal van Leeuwen } 31586f2d1428SPascal van Leeuwen 31596f2d1428SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cbc_sm4 = { 31606f2d1428SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 31616f2d1428SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4, 31626f2d1428SPascal van Leeuwen .alg.skcipher = { 31636f2d1428SPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 31646f2d1428SPascal van Leeuwen .encrypt = safexcel_sm4_blk_encrypt, 31656f2d1428SPascal van Leeuwen .decrypt = safexcel_sm4_blk_decrypt, 31666f2d1428SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 31676f2d1428SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 31686f2d1428SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 31696f2d1428SPascal van Leeuwen .base = { 31706f2d1428SPascal van Leeuwen .cra_name = "cbc(sm4)", 31716f2d1428SPascal van Leeuwen .cra_driver_name = "safexcel-cbc-sm4", 31726f2d1428SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 31736f2d1428SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3174b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 31756f2d1428SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 31766f2d1428SPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 31776f2d1428SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 31786f2d1428SPascal van Leeuwen .cra_alignmask = 0, 31796f2d1428SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_cbc_cra_init, 31806f2d1428SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 31816f2d1428SPascal van Leeuwen .cra_module = THIS_MODULE, 31826f2d1428SPascal van Leeuwen }, 31836f2d1428SPascal van Leeuwen }, 31846f2d1428SPascal van Leeuwen }; 318503a6cfb9SPascal van Leeuwen 318603a6cfb9SPascal van Leeuwen static int safexcel_skcipher_sm4_ofb_cra_init(struct crypto_tfm *tfm) 318703a6cfb9SPascal van Leeuwen { 318803a6cfb9SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 318903a6cfb9SPascal van Leeuwen 319003a6cfb9SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 319103a6cfb9SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3192098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 319303a6cfb9SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; 319403a6cfb9SPascal van Leeuwen return 0; 319503a6cfb9SPascal van Leeuwen } 319603a6cfb9SPascal van Leeuwen 319703a6cfb9SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ofb_sm4 = { 319803a6cfb9SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 319903a6cfb9SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, 320003a6cfb9SPascal van Leeuwen .alg.skcipher = { 320103a6cfb9SPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 320203a6cfb9SPascal van Leeuwen .encrypt = safexcel_encrypt, 320303a6cfb9SPascal van Leeuwen .decrypt = safexcel_decrypt, 320403a6cfb9SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 320503a6cfb9SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 320603a6cfb9SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 320703a6cfb9SPascal van Leeuwen .base = { 320803a6cfb9SPascal van Leeuwen .cra_name = "ofb(sm4)", 320903a6cfb9SPascal van Leeuwen .cra_driver_name = "safexcel-ofb-sm4", 321003a6cfb9SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 321103a6cfb9SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3212b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 321303a6cfb9SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 321403a6cfb9SPascal van Leeuwen .cra_blocksize = 1, 321503a6cfb9SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 321603a6cfb9SPascal van Leeuwen .cra_alignmask = 0, 321703a6cfb9SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_ofb_cra_init, 321803a6cfb9SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 321903a6cfb9SPascal van Leeuwen .cra_module = THIS_MODULE, 322003a6cfb9SPascal van Leeuwen }, 322103a6cfb9SPascal van Leeuwen }, 322203a6cfb9SPascal van Leeuwen }; 32237468ab22SPascal van Leeuwen 32247468ab22SPascal van Leeuwen static int safexcel_skcipher_sm4_cfb_cra_init(struct crypto_tfm *tfm) 32257468ab22SPascal van Leeuwen { 32267468ab22SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 32277468ab22SPascal van Leeuwen 32287468ab22SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 32297468ab22SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3230098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 32317468ab22SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; 32327468ab22SPascal van Leeuwen return 0; 32337468ab22SPascal van Leeuwen } 32347468ab22SPascal van Leeuwen 32357468ab22SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cfb_sm4 = { 32367468ab22SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 32377468ab22SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, 32387468ab22SPascal van Leeuwen .alg.skcipher = { 32397468ab22SPascal van Leeuwen .setkey = safexcel_skcipher_sm4_setkey, 32407468ab22SPascal van Leeuwen .encrypt = safexcel_encrypt, 32417468ab22SPascal van Leeuwen .decrypt = safexcel_decrypt, 32427468ab22SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE, 32437468ab22SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE, 32447468ab22SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 32457468ab22SPascal van Leeuwen .base = { 32467468ab22SPascal van Leeuwen .cra_name = "cfb(sm4)", 32477468ab22SPascal van Leeuwen .cra_driver_name = "safexcel-cfb-sm4", 32487468ab22SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 32497468ab22SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3250b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 32517468ab22SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 32527468ab22SPascal van Leeuwen .cra_blocksize = 1, 32537468ab22SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 32547468ab22SPascal van Leeuwen .cra_alignmask = 0, 32557468ab22SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_cfb_cra_init, 32567468ab22SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 32577468ab22SPascal van Leeuwen .cra_module = THIS_MODULE, 32587468ab22SPascal van Leeuwen }, 32597468ab22SPascal van Leeuwen }, 32607468ab22SPascal van Leeuwen }; 3261f77e5dc0SPascal van Leeuwen 3262f77e5dc0SPascal van Leeuwen static int safexcel_skcipher_sm4ctr_setkey(struct crypto_skcipher *ctfm, 3263f77e5dc0SPascal van Leeuwen const u8 *key, unsigned int len) 3264f77e5dc0SPascal van Leeuwen { 3265f77e5dc0SPascal van Leeuwen struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); 3266f77e5dc0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3267f77e5dc0SPascal van Leeuwen 3268f77e5dc0SPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 3269f77e5dc0SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 3270f77e5dc0SPascal van Leeuwen /* exclude the nonce here */ 3271f77e5dc0SPascal van Leeuwen len -= CTR_RFC3686_NONCE_SIZE; 3272f77e5dc0SPascal van Leeuwen 3273f77e5dc0SPascal van Leeuwen return safexcel_skcipher_sm4_setkey(ctfm, key, len); 3274f77e5dc0SPascal van Leeuwen } 3275f77e5dc0SPascal van Leeuwen 3276f77e5dc0SPascal van Leeuwen static int safexcel_skcipher_sm4_ctr_cra_init(struct crypto_tfm *tfm) 3277f77e5dc0SPascal van Leeuwen { 3278f77e5dc0SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3279f77e5dc0SPascal van Leeuwen 3280f77e5dc0SPascal van Leeuwen safexcel_skcipher_cra_init(tfm); 3281f77e5dc0SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3282098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 3283f77e5dc0SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 3284f77e5dc0SPascal van Leeuwen return 0; 3285f77e5dc0SPascal van Leeuwen } 3286f77e5dc0SPascal van Leeuwen 3287f77e5dc0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ctr_sm4 = { 3288f77e5dc0SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_SKCIPHER, 3289f77e5dc0SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4, 3290f77e5dc0SPascal van Leeuwen .alg.skcipher = { 3291f77e5dc0SPascal van Leeuwen .setkey = safexcel_skcipher_sm4ctr_setkey, 3292f77e5dc0SPascal van Leeuwen .encrypt = safexcel_encrypt, 3293f77e5dc0SPascal van Leeuwen .decrypt = safexcel_decrypt, 3294f77e5dc0SPascal van Leeuwen /* Add nonce size */ 3295f77e5dc0SPascal van Leeuwen .min_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 3296f77e5dc0SPascal van Leeuwen .max_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, 3297f77e5dc0SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 3298f77e5dc0SPascal van Leeuwen .base = { 3299f77e5dc0SPascal van Leeuwen .cra_name = "rfc3686(ctr(sm4))", 3300f77e5dc0SPascal van Leeuwen .cra_driver_name = "safexcel-ctr-sm4", 3301f77e5dc0SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3302f77e5dc0SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3303b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 3304f77e5dc0SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3305f77e5dc0SPascal van Leeuwen .cra_blocksize = 1, 3306f77e5dc0SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3307f77e5dc0SPascal van Leeuwen .cra_alignmask = 0, 3308f77e5dc0SPascal van Leeuwen .cra_init = safexcel_skcipher_sm4_ctr_cra_init, 3309f77e5dc0SPascal van Leeuwen .cra_exit = safexcel_skcipher_cra_exit, 3310f77e5dc0SPascal van Leeuwen .cra_module = THIS_MODULE, 3311f77e5dc0SPascal van Leeuwen }, 3312f77e5dc0SPascal van Leeuwen }, 3313f77e5dc0SPascal van Leeuwen }; 33141769f704SPascal van Leeuwen 33151769f704SPascal van Leeuwen static int safexcel_aead_sm4_blk_encrypt(struct aead_request *req) 33161769f704SPascal van Leeuwen { 33171769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 33181769f704SPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 33191769f704SPascal van Leeuwen return -EINVAL; 33201769f704SPascal van Leeuwen 33211769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, aead_request_ctx(req), 33221769f704SPascal van Leeuwen SAFEXCEL_ENCRYPT); 33231769f704SPascal van Leeuwen } 33241769f704SPascal van Leeuwen 33251769f704SPascal van Leeuwen static int safexcel_aead_sm4_blk_decrypt(struct aead_request *req) 33261769f704SPascal van Leeuwen { 33271769f704SPascal van Leeuwen struct crypto_aead *tfm = crypto_aead_reqtfm(req); 33281769f704SPascal van Leeuwen 33291769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 33301769f704SPascal van Leeuwen if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) 33311769f704SPascal van Leeuwen return -EINVAL; 33321769f704SPascal van Leeuwen 33331769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, aead_request_ctx(req), 33341769f704SPascal van Leeuwen SAFEXCEL_DECRYPT); 33351769f704SPascal van Leeuwen } 33361769f704SPascal van Leeuwen 33371769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sha1_cra_init(struct crypto_tfm *tfm) 33381769f704SPascal van Leeuwen { 33391769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33401769f704SPascal van Leeuwen 33411769f704SPascal van Leeuwen safexcel_aead_cra_init(tfm); 33421769f704SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3343098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 33441769f704SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; 33451769f704SPascal van Leeuwen ctx->state_sz = SHA1_DIGEST_SIZE; 33461769f704SPascal van Leeuwen return 0; 33471769f704SPascal van Leeuwen } 33481769f704SPascal van Leeuwen 33491769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4 = { 33501769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 33511769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, 33521769f704SPascal van Leeuwen .alg.aead = { 33531769f704SPascal van Leeuwen .setkey = safexcel_aead_setkey, 33541769f704SPascal van Leeuwen .encrypt = safexcel_aead_sm4_blk_encrypt, 33551769f704SPascal van Leeuwen .decrypt = safexcel_aead_sm4_blk_decrypt, 33561769f704SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 33571769f704SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 33581769f704SPascal van Leeuwen .base = { 33591769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),cbc(sm4))", 33601769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-sm4", 33611769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 33621769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3363b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 33641769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 33651769f704SPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 33661769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 33671769f704SPascal van Leeuwen .cra_alignmask = 0, 33681769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4cbc_sha1_cra_init, 33691769f704SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 33701769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 33711769f704SPascal van Leeuwen }, 33721769f704SPascal van Leeuwen }, 33731769f704SPascal van Leeuwen }; 33741769f704SPascal van Leeuwen 33751769f704SPascal van Leeuwen static int safexcel_aead_fallback_setkey(struct crypto_aead *ctfm, 33761769f704SPascal van Leeuwen const u8 *key, unsigned int len) 33771769f704SPascal van Leeuwen { 33781769f704SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 33791769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33801769f704SPascal van Leeuwen 33811769f704SPascal van Leeuwen /* Keep fallback cipher synchronized */ 33821769f704SPascal van Leeuwen return crypto_aead_setkey(ctx->fback, (u8 *)key, len) ?: 33831769f704SPascal van Leeuwen safexcel_aead_setkey(ctfm, key, len); 33841769f704SPascal van Leeuwen } 33851769f704SPascal van Leeuwen 33861769f704SPascal van Leeuwen static int safexcel_aead_fallback_setauthsize(struct crypto_aead *ctfm, 33871769f704SPascal van Leeuwen unsigned int authsize) 33881769f704SPascal van Leeuwen { 33891769f704SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 33901769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 33911769f704SPascal van Leeuwen 33921769f704SPascal van Leeuwen /* Keep fallback cipher synchronized */ 33931769f704SPascal van Leeuwen return crypto_aead_setauthsize(ctx->fback, authsize); 33941769f704SPascal van Leeuwen } 33951769f704SPascal van Leeuwen 33961769f704SPascal van Leeuwen static int safexcel_aead_fallback_crypt(struct aead_request *req, 33971769f704SPascal van Leeuwen enum safexcel_cipher_direction dir) 33981769f704SPascal van Leeuwen { 33991769f704SPascal van Leeuwen struct crypto_aead *aead = crypto_aead_reqtfm(req); 34001769f704SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(aead); 34011769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 34021769f704SPascal van Leeuwen struct aead_request *subreq = aead_request_ctx(req); 34031769f704SPascal van Leeuwen 34041769f704SPascal van Leeuwen aead_request_set_tfm(subreq, ctx->fback); 34051769f704SPascal van Leeuwen aead_request_set_callback(subreq, req->base.flags, req->base.complete, 34061769f704SPascal van Leeuwen req->base.data); 34071769f704SPascal van Leeuwen aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, 34081769f704SPascal van Leeuwen req->iv); 34091769f704SPascal van Leeuwen aead_request_set_ad(subreq, req->assoclen); 34101769f704SPascal van Leeuwen 34111769f704SPascal van Leeuwen return (dir == SAFEXCEL_ENCRYPT) ? 34121769f704SPascal van Leeuwen crypto_aead_encrypt(subreq) : 34131769f704SPascal van Leeuwen crypto_aead_decrypt(subreq); 34141769f704SPascal van Leeuwen } 34151769f704SPascal van Leeuwen 34161769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request *req) 34171769f704SPascal van Leeuwen { 34181769f704SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 34191769f704SPascal van Leeuwen 34201769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 34211769f704SPascal van Leeuwen if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) 34221769f704SPascal van Leeuwen return -EINVAL; 34231769f704SPascal van Leeuwen else if (req->cryptlen || req->assoclen) /* If input length > 0 only */ 34241769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 34251769f704SPascal van Leeuwen 34261769f704SPascal van Leeuwen /* HW cannot do full (AAD+payload) zero length, use fallback */ 34271769f704SPascal van Leeuwen return safexcel_aead_fallback_crypt(req, SAFEXCEL_ENCRYPT); 34281769f704SPascal van Leeuwen } 34291769f704SPascal van Leeuwen 34301769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request *req) 34311769f704SPascal van Leeuwen { 34321769f704SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 34331769f704SPascal van Leeuwen struct crypto_aead *tfm = crypto_aead_reqtfm(req); 34341769f704SPascal van Leeuwen 34351769f704SPascal van Leeuwen /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ 34361769f704SPascal van Leeuwen if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) 34371769f704SPascal van Leeuwen return -EINVAL; 34381769f704SPascal van Leeuwen else if (req->cryptlen > crypto_aead_authsize(tfm) || req->assoclen) 34391769f704SPascal van Leeuwen /* If input length > 0 only */ 34401769f704SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 34411769f704SPascal van Leeuwen 34421769f704SPascal van Leeuwen /* HW cannot do full (AAD+payload) zero length, use fallback */ 34431769f704SPascal van Leeuwen return safexcel_aead_fallback_crypt(req, SAFEXCEL_DECRYPT); 34441769f704SPascal van Leeuwen } 34451769f704SPascal van Leeuwen 34461769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm *tfm) 34471769f704SPascal van Leeuwen { 34481769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 34491769f704SPascal van Leeuwen 34501769f704SPascal van Leeuwen safexcel_aead_fallback_cra_init(tfm); 34511769f704SPascal van Leeuwen ctx->alg = SAFEXCEL_SM4; 3452098e51e5SPascal van Leeuwen ctx->blocksz = SM4_BLOCK_SIZE; 34531769f704SPascal van Leeuwen ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3; 34541769f704SPascal van Leeuwen ctx->state_sz = SM3_DIGEST_SIZE; 34551769f704SPascal van Leeuwen return 0; 34561769f704SPascal van Leeuwen } 34571769f704SPascal van Leeuwen 34581769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4 = { 34591769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 34601769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, 34611769f704SPascal van Leeuwen .alg.aead = { 34621769f704SPascal van Leeuwen .setkey = safexcel_aead_fallback_setkey, 34631769f704SPascal van Leeuwen .setauthsize = safexcel_aead_fallback_setauthsize, 34641769f704SPascal van Leeuwen .encrypt = safexcel_aead_sm4cbc_sm3_encrypt, 34651769f704SPascal van Leeuwen .decrypt = safexcel_aead_sm4cbc_sm3_decrypt, 34661769f704SPascal van Leeuwen .ivsize = SM4_BLOCK_SIZE, 34671769f704SPascal van Leeuwen .maxauthsize = SM3_DIGEST_SIZE, 34681769f704SPascal van Leeuwen .base = { 34691769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sm3),cbc(sm4))", 34701769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sm3-cbc-sm4", 34711769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 34721769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3473b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 34741769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY | 34751769f704SPascal van Leeuwen CRYPTO_ALG_NEED_FALLBACK, 34761769f704SPascal van Leeuwen .cra_blocksize = SM4_BLOCK_SIZE, 34771769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 34781769f704SPascal van Leeuwen .cra_alignmask = 0, 34791769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4cbc_sm3_cra_init, 34801769f704SPascal van Leeuwen .cra_exit = safexcel_aead_fallback_cra_exit, 34811769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 34821769f704SPascal van Leeuwen }, 34831769f704SPascal van Leeuwen }, 34841769f704SPascal van Leeuwen }; 34851769f704SPascal van Leeuwen 34861769f704SPascal van Leeuwen static int safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm *tfm) 34871769f704SPascal van Leeuwen { 34881769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 34891769f704SPascal van Leeuwen 34901769f704SPascal van Leeuwen safexcel_aead_sm4cbc_sha1_cra_init(tfm); 34911769f704SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 34921769f704SPascal van Leeuwen return 0; 34931769f704SPascal van Leeuwen } 34941769f704SPascal van Leeuwen 34951769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4 = { 34961769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 34971769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, 34981769f704SPascal van Leeuwen .alg.aead = { 34991769f704SPascal van Leeuwen .setkey = safexcel_aead_setkey, 35001769f704SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 35011769f704SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 35021769f704SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 35031769f704SPascal van Leeuwen .maxauthsize = SHA1_DIGEST_SIZE, 35041769f704SPascal van Leeuwen .base = { 35051769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sha1),rfc3686(ctr(sm4)))", 35061769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-sm4", 35071769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 35081769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3509b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 35101769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 35111769f704SPascal van Leeuwen .cra_blocksize = 1, 35121769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 35131769f704SPascal van Leeuwen .cra_alignmask = 0, 35141769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4ctr_sha1_cra_init, 35151769f704SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 35161769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 35171769f704SPascal van Leeuwen }, 35181769f704SPascal van Leeuwen }, 35191769f704SPascal van Leeuwen }; 35201769f704SPascal van Leeuwen 35211769f704SPascal van Leeuwen static int safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm *tfm) 35221769f704SPascal van Leeuwen { 35231769f704SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 35241769f704SPascal van Leeuwen 35251769f704SPascal van Leeuwen safexcel_aead_sm4cbc_sm3_cra_init(tfm); 35261769f704SPascal van Leeuwen ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; 35271769f704SPascal van Leeuwen return 0; 35281769f704SPascal van Leeuwen } 35291769f704SPascal van Leeuwen 35301769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4 = { 35311769f704SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 35321769f704SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, 35331769f704SPascal van Leeuwen .alg.aead = { 35341769f704SPascal van Leeuwen .setkey = safexcel_aead_setkey, 35351769f704SPascal van Leeuwen .encrypt = safexcel_aead_encrypt, 35361769f704SPascal van Leeuwen .decrypt = safexcel_aead_decrypt, 35371769f704SPascal van Leeuwen .ivsize = CTR_RFC3686_IV_SIZE, 35381769f704SPascal van Leeuwen .maxauthsize = SM3_DIGEST_SIZE, 35391769f704SPascal van Leeuwen .base = { 35401769f704SPascal van Leeuwen .cra_name = "authenc(hmac(sm3),rfc3686(ctr(sm4)))", 35411769f704SPascal van Leeuwen .cra_driver_name = "safexcel-authenc-hmac-sm3-ctr-sm4", 35421769f704SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 35431769f704SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3544b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 35451769f704SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 35461769f704SPascal van Leeuwen .cra_blocksize = 1, 35471769f704SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 35481769f704SPascal van Leeuwen .cra_alignmask = 0, 35491769f704SPascal van Leeuwen .cra_init = safexcel_aead_sm4ctr_sm3_cra_init, 35501769f704SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 35511769f704SPascal van Leeuwen .cra_module = THIS_MODULE, 35521769f704SPascal van Leeuwen }, 35531769f704SPascal van Leeuwen }, 35541769f704SPascal van Leeuwen }; 3555a19052d4SPascal van Leeuwen 3556a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, 3557a19052d4SPascal van Leeuwen unsigned int len) 3558a19052d4SPascal van Leeuwen { 3559a19052d4SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 3560a19052d4SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3561a19052d4SPascal van Leeuwen 3562a19052d4SPascal van Leeuwen /* last 4 bytes of key are the nonce! */ 3563a19052d4SPascal van Leeuwen ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); 3564a19052d4SPascal van Leeuwen 3565a19052d4SPascal van Leeuwen len -= CTR_RFC3686_NONCE_SIZE; 3566a19052d4SPascal van Leeuwen return safexcel_aead_gcm_setkey(ctfm, key, len); 3567a19052d4SPascal van Leeuwen } 3568a19052d4SPascal van Leeuwen 3569a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_setauthsize(struct crypto_aead *tfm, 3570a19052d4SPascal van Leeuwen unsigned int authsize) 3571a19052d4SPascal van Leeuwen { 3572a19052d4SPascal van Leeuwen return crypto_rfc4106_check_authsize(authsize); 3573a19052d4SPascal van Leeuwen } 3574a19052d4SPascal van Leeuwen 3575a19052d4SPascal van Leeuwen static int safexcel_rfc4106_encrypt(struct aead_request *req) 3576a19052d4SPascal van Leeuwen { 3577a19052d4SPascal van Leeuwen return crypto_ipsec_check_assoclen(req->assoclen) ?: 3578a19052d4SPascal van Leeuwen safexcel_aead_encrypt(req); 3579a19052d4SPascal van Leeuwen } 3580a19052d4SPascal van Leeuwen 3581a19052d4SPascal van Leeuwen static int safexcel_rfc4106_decrypt(struct aead_request *req) 3582a19052d4SPascal van Leeuwen { 3583a19052d4SPascal van Leeuwen return crypto_ipsec_check_assoclen(req->assoclen) ?: 3584a19052d4SPascal van Leeuwen safexcel_aead_decrypt(req); 3585a19052d4SPascal van Leeuwen } 3586a19052d4SPascal van Leeuwen 3587a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_cra_init(struct crypto_tfm *tfm) 3588a19052d4SPascal van Leeuwen { 3589a19052d4SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3590a19052d4SPascal van Leeuwen int ret; 3591a19052d4SPascal van Leeuwen 3592a19052d4SPascal van Leeuwen ret = safexcel_aead_gcm_cra_init(tfm); 3593a19052d4SPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 3594098e51e5SPascal van Leeuwen ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 3595a19052d4SPascal van Leeuwen return ret; 3596a19052d4SPascal van Leeuwen } 3597a19052d4SPascal van Leeuwen 3598a19052d4SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4106_gcm = { 3599a19052d4SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3600a19052d4SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 3601a19052d4SPascal van Leeuwen .alg.aead = { 3602a19052d4SPascal van Leeuwen .setkey = safexcel_rfc4106_gcm_setkey, 3603a19052d4SPascal van Leeuwen .setauthsize = safexcel_rfc4106_gcm_setauthsize, 3604a19052d4SPascal van Leeuwen .encrypt = safexcel_rfc4106_encrypt, 3605a19052d4SPascal van Leeuwen .decrypt = safexcel_rfc4106_decrypt, 3606a19052d4SPascal van Leeuwen .ivsize = GCM_RFC4106_IV_SIZE, 3607a19052d4SPascal van Leeuwen .maxauthsize = GHASH_DIGEST_SIZE, 3608a19052d4SPascal van Leeuwen .base = { 3609a19052d4SPascal van Leeuwen .cra_name = "rfc4106(gcm(aes))", 3610a19052d4SPascal van Leeuwen .cra_driver_name = "safexcel-rfc4106-gcm-aes", 3611a19052d4SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3612a19052d4SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3613b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 3614a19052d4SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3615a19052d4SPascal van Leeuwen .cra_blocksize = 1, 3616a19052d4SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3617a19052d4SPascal van Leeuwen .cra_alignmask = 0, 3618a19052d4SPascal van Leeuwen .cra_init = safexcel_rfc4106_gcm_cra_init, 3619a19052d4SPascal van Leeuwen .cra_exit = safexcel_aead_gcm_cra_exit, 3620a19052d4SPascal van Leeuwen }, 3621a19052d4SPascal van Leeuwen }, 3622a19052d4SPascal van Leeuwen }; 362392c60cefSPascal van Leeuwen 362492c60cefSPascal van Leeuwen static int safexcel_rfc4543_gcm_setauthsize(struct crypto_aead *tfm, 362592c60cefSPascal van Leeuwen unsigned int authsize) 362692c60cefSPascal van Leeuwen { 362792c60cefSPascal van Leeuwen if (authsize != GHASH_DIGEST_SIZE) 362892c60cefSPascal van Leeuwen return -EINVAL; 362992c60cefSPascal van Leeuwen 363092c60cefSPascal van Leeuwen return 0; 363192c60cefSPascal van Leeuwen } 363292c60cefSPascal van Leeuwen 363392c60cefSPascal van Leeuwen static int safexcel_rfc4543_gcm_cra_init(struct crypto_tfm *tfm) 363492c60cefSPascal van Leeuwen { 363592c60cefSPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 363692c60cefSPascal van Leeuwen int ret; 363792c60cefSPascal van Leeuwen 363892c60cefSPascal van Leeuwen ret = safexcel_aead_gcm_cra_init(tfm); 363992c60cefSPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP_GMAC; 364092c60cefSPascal van Leeuwen return ret; 364192c60cefSPascal van Leeuwen } 364292c60cefSPascal van Leeuwen 364392c60cefSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4543_gcm = { 364492c60cefSPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 364592c60cefSPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, 364692c60cefSPascal van Leeuwen .alg.aead = { 364792c60cefSPascal van Leeuwen .setkey = safexcel_rfc4106_gcm_setkey, 364892c60cefSPascal van Leeuwen .setauthsize = safexcel_rfc4543_gcm_setauthsize, 364992c60cefSPascal van Leeuwen .encrypt = safexcel_rfc4106_encrypt, 365092c60cefSPascal van Leeuwen .decrypt = safexcel_rfc4106_decrypt, 365192c60cefSPascal van Leeuwen .ivsize = GCM_RFC4543_IV_SIZE, 365292c60cefSPascal van Leeuwen .maxauthsize = GHASH_DIGEST_SIZE, 365392c60cefSPascal van Leeuwen .base = { 365492c60cefSPascal van Leeuwen .cra_name = "rfc4543(gcm(aes))", 365592c60cefSPascal van Leeuwen .cra_driver_name = "safexcel-rfc4543-gcm-aes", 365692c60cefSPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 365792c60cefSPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3658b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 365992c60cefSPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 366092c60cefSPascal van Leeuwen .cra_blocksize = 1, 366192c60cefSPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 366292c60cefSPascal van Leeuwen .cra_alignmask = 0, 366392c60cefSPascal van Leeuwen .cra_init = safexcel_rfc4543_gcm_cra_init, 366492c60cefSPascal van Leeuwen .cra_exit = safexcel_aead_gcm_cra_exit, 366592c60cefSPascal van Leeuwen }, 366692c60cefSPascal van Leeuwen }, 366792c60cefSPascal van Leeuwen }; 3668a9a89624SPascal van Leeuwen 3669a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, 3670a9a89624SPascal van Leeuwen unsigned int len) 3671a9a89624SPascal van Leeuwen { 3672a9a89624SPascal van Leeuwen struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); 3673a9a89624SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3674a9a89624SPascal van Leeuwen 3675a9a89624SPascal van Leeuwen /* First byte of the nonce = L = always 3 for RFC4309 (4 byte ctr) */ 3676a9a89624SPascal van Leeuwen *(u8 *)&ctx->nonce = EIP197_AEAD_IPSEC_COUNTER_SIZE - 1; 3677a9a89624SPascal van Leeuwen /* last 3 bytes of key are the nonce! */ 3678a9a89624SPascal van Leeuwen memcpy((u8 *)&ctx->nonce + 1, key + len - 3679a9a89624SPascal van Leeuwen EIP197_AEAD_IPSEC_CCM_NONCE_SIZE, 3680a9a89624SPascal van Leeuwen EIP197_AEAD_IPSEC_CCM_NONCE_SIZE); 3681a9a89624SPascal van Leeuwen 3682a9a89624SPascal van Leeuwen len -= EIP197_AEAD_IPSEC_CCM_NONCE_SIZE; 3683a9a89624SPascal van Leeuwen return safexcel_aead_ccm_setkey(ctfm, key, len); 3684a9a89624SPascal van Leeuwen } 3685a9a89624SPascal van Leeuwen 3686a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_setauthsize(struct crypto_aead *tfm, 3687a9a89624SPascal van Leeuwen unsigned int authsize) 3688a9a89624SPascal van Leeuwen { 3689a9a89624SPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 3690a9a89624SPascal van Leeuwen switch (authsize) { 3691a9a89624SPascal van Leeuwen case 8: 3692a9a89624SPascal van Leeuwen case 12: 3693a9a89624SPascal van Leeuwen case 16: 3694a9a89624SPascal van Leeuwen break; 3695a9a89624SPascal van Leeuwen default: 3696a9a89624SPascal van Leeuwen return -EINVAL; 3697a9a89624SPascal van Leeuwen } 3698a9a89624SPascal van Leeuwen 3699a9a89624SPascal van Leeuwen return 0; 3700a9a89624SPascal van Leeuwen } 3701a9a89624SPascal van Leeuwen 3702a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_encrypt(struct aead_request *req) 3703a9a89624SPascal van Leeuwen { 3704a9a89624SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 3705a9a89624SPascal van Leeuwen 3706a9a89624SPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 3707a9a89624SPascal van Leeuwen if (req->assoclen != 16 && req->assoclen != 20) 3708a9a89624SPascal van Leeuwen return -EINVAL; 3709a9a89624SPascal van Leeuwen 3710a9a89624SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); 3711a9a89624SPascal van Leeuwen } 3712a9a89624SPascal van Leeuwen 3713a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_decrypt(struct aead_request *req) 3714a9a89624SPascal van Leeuwen { 3715a9a89624SPascal van Leeuwen struct safexcel_cipher_req *creq = aead_request_ctx(req); 3716a9a89624SPascal van Leeuwen 3717a9a89624SPascal van Leeuwen /* Borrowed from crypto/ccm.c */ 3718a9a89624SPascal van Leeuwen if (req->assoclen != 16 && req->assoclen != 20) 3719a9a89624SPascal van Leeuwen return -EINVAL; 3720a9a89624SPascal van Leeuwen 3721a9a89624SPascal van Leeuwen return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); 3722a9a89624SPascal van Leeuwen } 3723a9a89624SPascal van Leeuwen 3724a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_cra_init(struct crypto_tfm *tfm) 3725a9a89624SPascal van Leeuwen { 3726a9a89624SPascal van Leeuwen struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 3727a9a89624SPascal van Leeuwen int ret; 3728a9a89624SPascal van Leeuwen 3729a9a89624SPascal van Leeuwen ret = safexcel_aead_ccm_cra_init(tfm); 3730a9a89624SPascal van Leeuwen ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; 3731098e51e5SPascal van Leeuwen ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; 3732a9a89624SPascal van Leeuwen return ret; 3733a9a89624SPascal van Leeuwen } 3734a9a89624SPascal van Leeuwen 3735a9a89624SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4309_ccm = { 3736a9a89624SPascal van Leeuwen .type = SAFEXCEL_ALG_TYPE_AEAD, 3737a9a89624SPascal van Leeuwen .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, 3738a9a89624SPascal van Leeuwen .alg.aead = { 3739a9a89624SPascal van Leeuwen .setkey = safexcel_rfc4309_ccm_setkey, 3740a9a89624SPascal van Leeuwen .setauthsize = safexcel_rfc4309_ccm_setauthsize, 3741a9a89624SPascal van Leeuwen .encrypt = safexcel_rfc4309_ccm_encrypt, 3742a9a89624SPascal van Leeuwen .decrypt = safexcel_rfc4309_ccm_decrypt, 3743a9a89624SPascal van Leeuwen .ivsize = EIP197_AEAD_IPSEC_IV_SIZE, 3744a9a89624SPascal van Leeuwen .maxauthsize = AES_BLOCK_SIZE, 3745a9a89624SPascal van Leeuwen .base = { 3746a9a89624SPascal van Leeuwen .cra_name = "rfc4309(ccm(aes))", 3747a9a89624SPascal van Leeuwen .cra_driver_name = "safexcel-rfc4309-ccm-aes", 3748a9a89624SPascal van Leeuwen .cra_priority = SAFEXCEL_CRA_PRIORITY, 3749a9a89624SPascal van Leeuwen .cra_flags = CRYPTO_ALG_ASYNC | 3750b8aa7dc5SMikulas Patocka CRYPTO_ALG_ALLOCATES_MEMORY | 3751a9a89624SPascal van Leeuwen CRYPTO_ALG_KERN_DRIVER_ONLY, 3752a9a89624SPascal van Leeuwen .cra_blocksize = 1, 3753a9a89624SPascal van Leeuwen .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), 3754a9a89624SPascal van Leeuwen .cra_alignmask = 0, 3755a9a89624SPascal van Leeuwen .cra_init = safexcel_rfc4309_ccm_cra_init, 3756a9a89624SPascal van Leeuwen .cra_exit = safexcel_aead_cra_exit, 3757a9a89624SPascal van Leeuwen .cra_module = THIS_MODULE, 3758a9a89624SPascal van Leeuwen }, 3759a9a89624SPascal van Leeuwen }, 3760a9a89624SPascal van Leeuwen }; 3761