1aaf4363eSJerin Jacob /* SPDX-License-Identifier: BSD-3-Clause 2aaf4363eSJerin Jacob * Copyright(c) 2017 Cavium, Inc 3169ca3dbSZbigniew Bodek */ 4169ca3dbSZbigniew Bodek 5169ca3dbSZbigniew Bodek #include <stdbool.h> 6169ca3dbSZbigniew Bodek 7169ca3dbSZbigniew Bodek #include <rte_common.h> 8169ca3dbSZbigniew Bodek #include <rte_hexdump.h> 9169ca3dbSZbigniew Bodek #include <rte_cryptodev.h> 10af668035SAkhil Goyal #include <cryptodev_pmd.h> 114851ef2bSDavid Marchand #include <bus_vdev_driver.h> 12169ca3dbSZbigniew Bodek #include <rte_malloc.h> 13169ca3dbSZbigniew Bodek #include <rte_cpuflags.h> 14169ca3dbSZbigniew Bodek 15bde43e8aSRuifeng Wang #include "AArch64cryptolib.h" 16169ca3dbSZbigniew Bodek 17b28f28aeSDharmik Thakkar #include "armv8_pmd_private.h" 18169ca3dbSZbigniew Bodek 197a364faeSSlawomir Mrozowicz static uint8_t cryptodev_driver_id; 207a364faeSSlawomir Mrozowicz 215d2aa461SJan Blunck static int cryptodev_armv8_crypto_uninit(struct rte_vdev_device *vdev); 22169ca3dbSZbigniew Bodek 23169ca3dbSZbigniew Bodek /** 24169ca3dbSZbigniew Bodek * Pointers to the supported combined mode crypto functions are stored 25169ca3dbSZbigniew Bodek * in the static tables. Each combined (chained) cryptographic operation 26169ca3dbSZbigniew Bodek * can be described by a set of numbers: 27169ca3dbSZbigniew Bodek * - order: order of operations (cipher, auth) or (auth, cipher) 28169ca3dbSZbigniew Bodek * - direction: encryption or decryption 29169ca3dbSZbigniew Bodek * - calg: cipher algorithm such as AES_CBC, AES_CTR, etc. 30169ca3dbSZbigniew Bodek * - aalg: authentication algorithm such as SHA1, SHA256, etc. 31169ca3dbSZbigniew Bodek * - keyl: cipher key length, for example 128, 192, 256 bits 32169ca3dbSZbigniew Bodek * 33169ca3dbSZbigniew Bodek * In order to quickly acquire each function pointer based on those numbers, 34169ca3dbSZbigniew Bodek * a hierarchy of arrays is maintained. The final level, 3D array is indexed 35169ca3dbSZbigniew Bodek * by the combined mode function parameters only (cipher algorithm, 36169ca3dbSZbigniew Bodek * authentication algorithm and key length). 37169ca3dbSZbigniew Bodek * 38169ca3dbSZbigniew Bodek * This gives 3 memory accesses to obtain a function pointer instead of 39169ca3dbSZbigniew Bodek * traversing the array manually and comparing function parameters on each loop. 40169ca3dbSZbigniew Bodek * 41169ca3dbSZbigniew Bodek * +--+CRYPTO_FUNC 42169ca3dbSZbigniew Bodek * +--+ENC| 43169ca3dbSZbigniew Bodek * +--+CA| 44169ca3dbSZbigniew Bodek * | +--+DEC 45169ca3dbSZbigniew Bodek * ORDER| 46169ca3dbSZbigniew Bodek * | +--+ENC 47169ca3dbSZbigniew Bodek * +--+AC| 48169ca3dbSZbigniew Bodek * +--+DEC 49169ca3dbSZbigniew Bodek * 50169ca3dbSZbigniew Bodek */ 51169ca3dbSZbigniew Bodek 52169ca3dbSZbigniew Bodek /** 53169ca3dbSZbigniew Bodek * 3D array type for ARM Combined Mode crypto functions pointers. 54169ca3dbSZbigniew Bodek * CRYPTO_CIPHER_MAX: max cipher ID number 55169ca3dbSZbigniew Bodek * CRYPTO_AUTH_MAX: max auth ID number 56169ca3dbSZbigniew Bodek * CRYPTO_CIPHER_KEYLEN_MAX: max key length ID number 57169ca3dbSZbigniew Bodek */ 58169ca3dbSZbigniew Bodek typedef const crypto_func_t 59169ca3dbSZbigniew Bodek crypto_func_tbl_t[CRYPTO_CIPHER_MAX][CRYPTO_AUTH_MAX][CRYPTO_CIPHER_KEYLEN_MAX]; 60169ca3dbSZbigniew Bodek 61169ca3dbSZbigniew Bodek /* Evaluate to key length definition */ 62169ca3dbSZbigniew Bodek #define KEYL(keyl) (ARMV8_CRYPTO_CIPHER_KEYLEN_ ## keyl) 63169ca3dbSZbigniew Bodek 64169ca3dbSZbigniew Bodek /* Local aliases for supported ciphers */ 65169ca3dbSZbigniew Bodek #define CIPH_AES_CBC RTE_CRYPTO_CIPHER_AES_CBC 66169ca3dbSZbigniew Bodek /* Local aliases for supported hashes */ 67169ca3dbSZbigniew Bodek #define AUTH_SHA1_HMAC RTE_CRYPTO_AUTH_SHA1_HMAC 68169ca3dbSZbigniew Bodek #define AUTH_SHA256_HMAC RTE_CRYPTO_AUTH_SHA256_HMAC 69169ca3dbSZbigniew Bodek 70169ca3dbSZbigniew Bodek /** 71169ca3dbSZbigniew Bodek * Arrays containing pointers to particular cryptographic, 72169ca3dbSZbigniew Bodek * combined mode functions. 73169ca3dbSZbigniew Bodek * crypto_op_ca_encrypt: cipher (encrypt), authenticate 74169ca3dbSZbigniew Bodek * crypto_op_ca_decrypt: cipher (decrypt), authenticate 75169ca3dbSZbigniew Bodek * crypto_op_ac_encrypt: authenticate, cipher (encrypt) 76169ca3dbSZbigniew Bodek * crypto_op_ac_decrypt: authenticate, cipher (decrypt) 77169ca3dbSZbigniew Bodek */ 78169ca3dbSZbigniew Bodek static const crypto_func_tbl_t 79169ca3dbSZbigniew Bodek crypto_op_ca_encrypt = { 80169ca3dbSZbigniew Bodek /* [cipher alg][auth alg][key length] = crypto_function, */ 81bde43e8aSRuifeng Wang [CIPH_AES_CBC][AUTH_SHA1_HMAC][KEYL(128)] = 82bde43e8aSRuifeng Wang armv8_enc_aes_cbc_sha1_128, 83bde43e8aSRuifeng Wang [CIPH_AES_CBC][AUTH_SHA256_HMAC][KEYL(128)] = 84bde43e8aSRuifeng Wang armv8_enc_aes_cbc_sha256_128, 85169ca3dbSZbigniew Bodek }; 86169ca3dbSZbigniew Bodek 87169ca3dbSZbigniew Bodek static const crypto_func_tbl_t 88169ca3dbSZbigniew Bodek crypto_op_ca_decrypt = { 8994b686e5SRuifeng Wang { {NULL} } 90169ca3dbSZbigniew Bodek }; 91169ca3dbSZbigniew Bodek 92169ca3dbSZbigniew Bodek static const crypto_func_tbl_t 93169ca3dbSZbigniew Bodek crypto_op_ac_encrypt = { 9494b686e5SRuifeng Wang { {NULL} } 95169ca3dbSZbigniew Bodek }; 96169ca3dbSZbigniew Bodek 97169ca3dbSZbigniew Bodek static const crypto_func_tbl_t 98169ca3dbSZbigniew Bodek crypto_op_ac_decrypt = { 99169ca3dbSZbigniew Bodek /* [cipher alg][auth alg][key length] = crypto_function, */ 100bde43e8aSRuifeng Wang [CIPH_AES_CBC][AUTH_SHA1_HMAC][KEYL(128)] = 101bde43e8aSRuifeng Wang armv8_dec_aes_cbc_sha1_128, 102bde43e8aSRuifeng Wang [CIPH_AES_CBC][AUTH_SHA256_HMAC][KEYL(128)] = 103bde43e8aSRuifeng Wang armv8_dec_aes_cbc_sha256_128, 104169ca3dbSZbigniew Bodek }; 105169ca3dbSZbigniew Bodek 106169ca3dbSZbigniew Bodek /** 107169ca3dbSZbigniew Bodek * Arrays containing pointers to particular cryptographic function sets, 108169ca3dbSZbigniew Bodek * covering given cipher operation directions (encrypt, decrypt) 109169ca3dbSZbigniew Bodek * for each order of cipher and authentication pairs. 110169ca3dbSZbigniew Bodek */ 111169ca3dbSZbigniew Bodek static const crypto_func_tbl_t * 112169ca3dbSZbigniew Bodek crypto_cipher_auth[] = { 113169ca3dbSZbigniew Bodek &crypto_op_ca_encrypt, 114169ca3dbSZbigniew Bodek &crypto_op_ca_decrypt, 115169ca3dbSZbigniew Bodek NULL 116169ca3dbSZbigniew Bodek }; 117169ca3dbSZbigniew Bodek 118169ca3dbSZbigniew Bodek static const crypto_func_tbl_t * 119169ca3dbSZbigniew Bodek crypto_auth_cipher[] = { 120169ca3dbSZbigniew Bodek &crypto_op_ac_encrypt, 121169ca3dbSZbigniew Bodek &crypto_op_ac_decrypt, 122169ca3dbSZbigniew Bodek NULL 123169ca3dbSZbigniew Bodek }; 124169ca3dbSZbigniew Bodek 125169ca3dbSZbigniew Bodek /** 126169ca3dbSZbigniew Bodek * Top level array containing pointers to particular cryptographic 127169ca3dbSZbigniew Bodek * function sets, covering given order of chained operations. 128169ca3dbSZbigniew Bodek * crypto_cipher_auth: cipher first, authenticate after 129169ca3dbSZbigniew Bodek * crypto_auth_cipher: authenticate first, cipher after 130169ca3dbSZbigniew Bodek */ 131169ca3dbSZbigniew Bodek static const crypto_func_tbl_t ** 132169ca3dbSZbigniew Bodek crypto_chain_order[] = { 133169ca3dbSZbigniew Bodek crypto_cipher_auth, 134169ca3dbSZbigniew Bodek crypto_auth_cipher, 135169ca3dbSZbigniew Bodek NULL 136169ca3dbSZbigniew Bodek }; 137169ca3dbSZbigniew Bodek 138169ca3dbSZbigniew Bodek /** 139169ca3dbSZbigniew Bodek * Extract particular combined mode crypto function from the 3D array. 140169ca3dbSZbigniew Bodek */ 141169ca3dbSZbigniew Bodek #define CRYPTO_GET_ALGO(order, cop, calg, aalg, keyl) \ 142169ca3dbSZbigniew Bodek ({ \ 143169ca3dbSZbigniew Bodek crypto_func_tbl_t *func_tbl = \ 144169ca3dbSZbigniew Bodek (crypto_chain_order[(order)])[(cop)]; \ 145169ca3dbSZbigniew Bodek \ 146087ed975SRuifeng Wang ((calg >= CRYPTO_CIPHER_MAX) || (aalg >= CRYPTO_AUTH_MAX)) ? \ 147087ed975SRuifeng Wang NULL : ((*func_tbl)[(calg)][(aalg)][KEYL(keyl)]); \ 148169ca3dbSZbigniew Bodek }) 149169ca3dbSZbigniew Bodek 150169ca3dbSZbigniew Bodek /*----------------------------------------------------------------------------*/ 151169ca3dbSZbigniew Bodek 152169ca3dbSZbigniew Bodek /** 153169ca3dbSZbigniew Bodek * 2D array type for ARM key schedule functions pointers. 154169ca3dbSZbigniew Bodek * CRYPTO_CIPHER_MAX: max cipher ID number 155169ca3dbSZbigniew Bodek * CRYPTO_CIPHER_KEYLEN_MAX: max key length ID number 156169ca3dbSZbigniew Bodek */ 157169ca3dbSZbigniew Bodek typedef const crypto_key_sched_t 158169ca3dbSZbigniew Bodek crypto_key_sched_tbl_t[CRYPTO_CIPHER_MAX][CRYPTO_CIPHER_KEYLEN_MAX]; 159169ca3dbSZbigniew Bodek 160169ca3dbSZbigniew Bodek static const crypto_key_sched_tbl_t 161169ca3dbSZbigniew Bodek crypto_key_sched_encrypt = { 162169ca3dbSZbigniew Bodek /* [cipher alg][key length] = key_expand_func, */ 163bde43e8aSRuifeng Wang [CIPH_AES_CBC][KEYL(128)] = armv8_expandkeys_enc_aes_cbc_128, 164169ca3dbSZbigniew Bodek }; 165169ca3dbSZbigniew Bodek 166169ca3dbSZbigniew Bodek static const crypto_key_sched_tbl_t 167169ca3dbSZbigniew Bodek crypto_key_sched_decrypt = { 168169ca3dbSZbigniew Bodek /* [cipher alg][key length] = key_expand_func, */ 169bde43e8aSRuifeng Wang [CIPH_AES_CBC][KEYL(128)] = armv8_expandkeys_dec_aes_cbc_128, 170169ca3dbSZbigniew Bodek }; 171169ca3dbSZbigniew Bodek 172169ca3dbSZbigniew Bodek /** 173169ca3dbSZbigniew Bodek * Top level array containing pointers to particular key generation 174169ca3dbSZbigniew Bodek * function sets, covering given operation direction. 175169ca3dbSZbigniew Bodek * crypto_key_sched_encrypt: keys for encryption 176169ca3dbSZbigniew Bodek * crypto_key_sched_decrypt: keys for decryption 177169ca3dbSZbigniew Bodek */ 178169ca3dbSZbigniew Bodek static const crypto_key_sched_tbl_t * 179169ca3dbSZbigniew Bodek crypto_key_sched_dir[] = { 180169ca3dbSZbigniew Bodek &crypto_key_sched_encrypt, 181169ca3dbSZbigniew Bodek &crypto_key_sched_decrypt, 182169ca3dbSZbigniew Bodek NULL 183169ca3dbSZbigniew Bodek }; 184169ca3dbSZbigniew Bodek 185169ca3dbSZbigniew Bodek /** 186169ca3dbSZbigniew Bodek * Extract particular combined mode crypto function from the 3D array. 187169ca3dbSZbigniew Bodek */ 188169ca3dbSZbigniew Bodek #define CRYPTO_GET_KEY_SCHED(cop, calg, keyl) \ 189169ca3dbSZbigniew Bodek ({ \ 190169ca3dbSZbigniew Bodek crypto_key_sched_tbl_t *ks_tbl = crypto_key_sched_dir[(cop)]; \ 191169ca3dbSZbigniew Bodek \ 192087ed975SRuifeng Wang (calg >= CRYPTO_CIPHER_MAX) ? \ 193087ed975SRuifeng Wang NULL : ((*ks_tbl)[(calg)][KEYL(keyl)]); \ 194169ca3dbSZbigniew Bodek }) 195169ca3dbSZbigniew Bodek 196169ca3dbSZbigniew Bodek /*----------------------------------------------------------------------------*/ 197169ca3dbSZbigniew Bodek 198169ca3dbSZbigniew Bodek /* 199169ca3dbSZbigniew Bodek *------------------------------------------------------------------------------ 200169ca3dbSZbigniew Bodek * Session Prepare 201169ca3dbSZbigniew Bodek *------------------------------------------------------------------------------ 202169ca3dbSZbigniew Bodek */ 203169ca3dbSZbigniew Bodek 204169ca3dbSZbigniew Bodek /** Get xform chain order */ 205169ca3dbSZbigniew Bodek static enum armv8_crypto_chain_order 206169ca3dbSZbigniew Bodek armv8_crypto_get_chain_order(const struct rte_crypto_sym_xform *xform) 207169ca3dbSZbigniew Bodek { 208169ca3dbSZbigniew Bodek 209169ca3dbSZbigniew Bodek /* 210169ca3dbSZbigniew Bodek * This driver currently covers only chained operations. 211169ca3dbSZbigniew Bodek * Ignore only cipher or only authentication operations 212169ca3dbSZbigniew Bodek * or chains longer than 2 xform structures. 213169ca3dbSZbigniew Bodek */ 214169ca3dbSZbigniew Bodek if (xform->next == NULL || xform->next->next != NULL) 215169ca3dbSZbigniew Bodek return ARMV8_CRYPTO_CHAIN_NOT_SUPPORTED; 216169ca3dbSZbigniew Bodek 217169ca3dbSZbigniew Bodek if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { 218169ca3dbSZbigniew Bodek if (xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) 219169ca3dbSZbigniew Bodek return ARMV8_CRYPTO_CHAIN_AUTH_CIPHER; 220169ca3dbSZbigniew Bodek } 221169ca3dbSZbigniew Bodek 222169ca3dbSZbigniew Bodek if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { 223169ca3dbSZbigniew Bodek if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) 224169ca3dbSZbigniew Bodek return ARMV8_CRYPTO_CHAIN_CIPHER_AUTH; 225169ca3dbSZbigniew Bodek } 226169ca3dbSZbigniew Bodek 227169ca3dbSZbigniew Bodek return ARMV8_CRYPTO_CHAIN_NOT_SUPPORTED; 228169ca3dbSZbigniew Bodek } 229169ca3dbSZbigniew Bodek 230169ca3dbSZbigniew Bodek static inline void 231169ca3dbSZbigniew Bodek auth_hmac_pad_prepare(struct armv8_crypto_session *sess, 232169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *xform) 233169ca3dbSZbigniew Bodek { 234169ca3dbSZbigniew Bodek size_t i; 235169ca3dbSZbigniew Bodek 236169ca3dbSZbigniew Bodek /* Generate i_key_pad and o_key_pad */ 237169ca3dbSZbigniew Bodek memset(sess->auth.hmac.i_key_pad, 0, sizeof(sess->auth.hmac.i_key_pad)); 238169ca3dbSZbigniew Bodek rte_memcpy(sess->auth.hmac.i_key_pad, sess->auth.hmac.key, 239169ca3dbSZbigniew Bodek xform->auth.key.length); 240169ca3dbSZbigniew Bodek memset(sess->auth.hmac.o_key_pad, 0, sizeof(sess->auth.hmac.o_key_pad)); 241169ca3dbSZbigniew Bodek rte_memcpy(sess->auth.hmac.o_key_pad, sess->auth.hmac.key, 242169ca3dbSZbigniew Bodek xform->auth.key.length); 243169ca3dbSZbigniew Bodek /* 244169ca3dbSZbigniew Bodek * XOR key with IPAD/OPAD values to obtain i_key_pad 245169ca3dbSZbigniew Bodek * and o_key_pad. 246169ca3dbSZbigniew Bodek * Byte-by-byte operation may seem to be the less efficient 247169ca3dbSZbigniew Bodek * here but in fact it's the opposite. 248169ca3dbSZbigniew Bodek * The result ASM code is likely operate on NEON registers 249169ca3dbSZbigniew Bodek * (load auth key to Qx, load IPAD/OPAD to multiple 250169ca3dbSZbigniew Bodek * elements of Qy, eor 128 bits at once). 251169ca3dbSZbigniew Bodek */ 252169ca3dbSZbigniew Bodek for (i = 0; i < SHA_BLOCK_MAX; i++) { 253169ca3dbSZbigniew Bodek sess->auth.hmac.i_key_pad[i] ^= HMAC_IPAD_VALUE; 254169ca3dbSZbigniew Bodek sess->auth.hmac.o_key_pad[i] ^= HMAC_OPAD_VALUE; 255169ca3dbSZbigniew Bodek } 256169ca3dbSZbigniew Bodek } 257169ca3dbSZbigniew Bodek 258169ca3dbSZbigniew Bodek static inline int 259169ca3dbSZbigniew Bodek auth_set_prerequisites(struct armv8_crypto_session *sess, 260169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *xform) 261169ca3dbSZbigniew Bodek { 262169ca3dbSZbigniew Bodek uint8_t partial[64] = { 0 }; 263169ca3dbSZbigniew Bodek int error; 264169ca3dbSZbigniew Bodek 265169ca3dbSZbigniew Bodek switch (xform->auth.algo) { 266169ca3dbSZbigniew Bodek case RTE_CRYPTO_AUTH_SHA1_HMAC: 267169ca3dbSZbigniew Bodek /* 268169ca3dbSZbigniew Bodek * Generate authentication key, i_key_pad and o_key_pad. 269169ca3dbSZbigniew Bodek */ 270169ca3dbSZbigniew Bodek /* Zero memory under key */ 271473174a7SSrisivasubramanian S memset(sess->auth.hmac.key, 0, SHA1_BLOCK_SIZE); 272169ca3dbSZbigniew Bodek 273169ca3dbSZbigniew Bodek /* 274169ca3dbSZbigniew Bodek * Now copy the given authentication key to the session 275473174a7SSrisivasubramanian S * key. 276169ca3dbSZbigniew Bodek */ 277169ca3dbSZbigniew Bodek rte_memcpy(sess->auth.hmac.key, xform->auth.key.data, 278169ca3dbSZbigniew Bodek xform->auth.key.length); 279169ca3dbSZbigniew Bodek 280169ca3dbSZbigniew Bodek /* Prepare HMAC padding: key|pattern */ 281169ca3dbSZbigniew Bodek auth_hmac_pad_prepare(sess, xform); 282169ca3dbSZbigniew Bodek /* 283169ca3dbSZbigniew Bodek * Calculate partial hash values for i_key_pad and o_key_pad. 284169ca3dbSZbigniew Bodek * Will be used as initialization state for final HMAC. 285169ca3dbSZbigniew Bodek */ 286bde43e8aSRuifeng Wang error = armv8_sha1_block_partial(NULL, 287bde43e8aSRuifeng Wang sess->auth.hmac.i_key_pad, 288169ca3dbSZbigniew Bodek partial, SHA1_BLOCK_SIZE); 289169ca3dbSZbigniew Bodek if (error != 0) 290169ca3dbSZbigniew Bodek return -1; 291169ca3dbSZbigniew Bodek memcpy(sess->auth.hmac.i_key_pad, partial, SHA1_BLOCK_SIZE); 292169ca3dbSZbigniew Bodek 293bde43e8aSRuifeng Wang error = armv8_sha1_block_partial(NULL, 294bde43e8aSRuifeng Wang sess->auth.hmac.o_key_pad, 295169ca3dbSZbigniew Bodek partial, SHA1_BLOCK_SIZE); 296169ca3dbSZbigniew Bodek if (error != 0) 297169ca3dbSZbigniew Bodek return -1; 298169ca3dbSZbigniew Bodek memcpy(sess->auth.hmac.o_key_pad, partial, SHA1_BLOCK_SIZE); 299169ca3dbSZbigniew Bodek 300169ca3dbSZbigniew Bodek break; 301169ca3dbSZbigniew Bodek case RTE_CRYPTO_AUTH_SHA256_HMAC: 302169ca3dbSZbigniew Bodek /* 303169ca3dbSZbigniew Bodek * Generate authentication key, i_key_pad and o_key_pad. 304169ca3dbSZbigniew Bodek */ 305169ca3dbSZbigniew Bodek /* Zero memory under key */ 306473174a7SSrisivasubramanian S memset(sess->auth.hmac.key, 0, SHA256_BLOCK_SIZE); 307169ca3dbSZbigniew Bodek 308169ca3dbSZbigniew Bodek /* 309169ca3dbSZbigniew Bodek * Now copy the given authentication key to the session 310473174a7SSrisivasubramanian S * key. 311169ca3dbSZbigniew Bodek */ 312169ca3dbSZbigniew Bodek rte_memcpy(sess->auth.hmac.key, xform->auth.key.data, 313169ca3dbSZbigniew Bodek xform->auth.key.length); 314169ca3dbSZbigniew Bodek 315169ca3dbSZbigniew Bodek /* Prepare HMAC padding: key|pattern */ 316169ca3dbSZbigniew Bodek auth_hmac_pad_prepare(sess, xform); 317169ca3dbSZbigniew Bodek /* 318169ca3dbSZbigniew Bodek * Calculate partial hash values for i_key_pad and o_key_pad. 319169ca3dbSZbigniew Bodek * Will be used as initialization state for final HMAC. 320169ca3dbSZbigniew Bodek */ 321bde43e8aSRuifeng Wang error = armv8_sha256_block_partial(NULL, 322bde43e8aSRuifeng Wang sess->auth.hmac.i_key_pad, 323169ca3dbSZbigniew Bodek partial, SHA256_BLOCK_SIZE); 324169ca3dbSZbigniew Bodek if (error != 0) 325169ca3dbSZbigniew Bodek return -1; 326169ca3dbSZbigniew Bodek memcpy(sess->auth.hmac.i_key_pad, partial, SHA256_BLOCK_SIZE); 327169ca3dbSZbigniew Bodek 328bde43e8aSRuifeng Wang error = armv8_sha256_block_partial(NULL, 329bde43e8aSRuifeng Wang sess->auth.hmac.o_key_pad, 330169ca3dbSZbigniew Bodek partial, SHA256_BLOCK_SIZE); 331169ca3dbSZbigniew Bodek if (error != 0) 332169ca3dbSZbigniew Bodek return -1; 333169ca3dbSZbigniew Bodek memcpy(sess->auth.hmac.o_key_pad, partial, SHA256_BLOCK_SIZE); 334169ca3dbSZbigniew Bodek 335169ca3dbSZbigniew Bodek break; 336169ca3dbSZbigniew Bodek default: 337169ca3dbSZbigniew Bodek break; 338169ca3dbSZbigniew Bodek } 339169ca3dbSZbigniew Bodek 340169ca3dbSZbigniew Bodek return 0; 341169ca3dbSZbigniew Bodek } 342169ca3dbSZbigniew Bodek 343169ca3dbSZbigniew Bodek static inline int 344169ca3dbSZbigniew Bodek cipher_set_prerequisites(struct armv8_crypto_session *sess, 345169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *xform) 346169ca3dbSZbigniew Bodek { 347169ca3dbSZbigniew Bodek crypto_key_sched_t cipher_key_sched; 348169ca3dbSZbigniew Bodek 349169ca3dbSZbigniew Bodek cipher_key_sched = sess->cipher.key_sched; 350169ca3dbSZbigniew Bodek if (likely(cipher_key_sched != NULL)) { 351169ca3dbSZbigniew Bodek /* Set up cipher session key */ 352169ca3dbSZbigniew Bodek cipher_key_sched(sess->cipher.key.data, xform->cipher.key.data); 353169ca3dbSZbigniew Bodek } 354169ca3dbSZbigniew Bodek 355169ca3dbSZbigniew Bodek return 0; 356169ca3dbSZbigniew Bodek } 357169ca3dbSZbigniew Bodek 358169ca3dbSZbigniew Bodek static int 359169ca3dbSZbigniew Bodek armv8_crypto_set_session_chained_parameters(struct armv8_crypto_session *sess, 360169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *cipher_xform, 361169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *auth_xform) 362169ca3dbSZbigniew Bodek { 363169ca3dbSZbigniew Bodek enum armv8_crypto_chain_order order; 364169ca3dbSZbigniew Bodek enum armv8_crypto_cipher_operation cop; 365169ca3dbSZbigniew Bodek enum rte_crypto_cipher_algorithm calg; 366169ca3dbSZbigniew Bodek enum rte_crypto_auth_algorithm aalg; 367169ca3dbSZbigniew Bodek 368169ca3dbSZbigniew Bodek /* Validate and prepare scratch order of combined operations */ 369169ca3dbSZbigniew Bodek switch (sess->chain_order) { 370169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_CIPHER_AUTH: 371169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_AUTH_CIPHER: 372169ca3dbSZbigniew Bodek order = sess->chain_order; 373169ca3dbSZbigniew Bodek break; 374169ca3dbSZbigniew Bodek default: 37527391b53SPablo de Lara return -ENOTSUP; 376169ca3dbSZbigniew Bodek } 377169ca3dbSZbigniew Bodek /* Select cipher direction */ 378169ca3dbSZbigniew Bodek sess->cipher.direction = cipher_xform->cipher.op; 379169ca3dbSZbigniew Bodek /* Select cipher key */ 380169ca3dbSZbigniew Bodek sess->cipher.key.length = cipher_xform->cipher.key.length; 381169ca3dbSZbigniew Bodek /* Set cipher direction */ 38294b686e5SRuifeng Wang switch (sess->cipher.direction) { 38394b686e5SRuifeng Wang case RTE_CRYPTO_CIPHER_OP_ENCRYPT: 38494b686e5SRuifeng Wang cop = ARMV8_CRYPTO_CIPHER_OP_ENCRYPT; 38594b686e5SRuifeng Wang break; 38694b686e5SRuifeng Wang case RTE_CRYPTO_CIPHER_OP_DECRYPT: 38794b686e5SRuifeng Wang cop = ARMV8_CRYPTO_CIPHER_OP_DECRYPT; 38894b686e5SRuifeng Wang break; 38994b686e5SRuifeng Wang default: 39094b686e5SRuifeng Wang return -ENOTSUP; 39194b686e5SRuifeng Wang } 392169ca3dbSZbigniew Bodek /* Set cipher algorithm */ 393169ca3dbSZbigniew Bodek calg = cipher_xform->cipher.algo; 394169ca3dbSZbigniew Bodek 395169ca3dbSZbigniew Bodek /* Select cipher algo */ 396169ca3dbSZbigniew Bodek switch (calg) { 397169ca3dbSZbigniew Bodek /* Cover supported cipher algorithms */ 398169ca3dbSZbigniew Bodek case RTE_CRYPTO_CIPHER_AES_CBC: 399169ca3dbSZbigniew Bodek sess->cipher.algo = calg; 400169ca3dbSZbigniew Bodek /* IV len is always 16 bytes (block size) for AES CBC */ 4010fbd75a9SPablo de Lara sess->cipher.iv.length = 16; 402169ca3dbSZbigniew Bodek break; 403169ca3dbSZbigniew Bodek default: 40427391b53SPablo de Lara return -ENOTSUP; 405169ca3dbSZbigniew Bodek } 406169ca3dbSZbigniew Bodek /* Select auth generate/verify */ 407169ca3dbSZbigniew Bodek sess->auth.operation = auth_xform->auth.op; 408169ca3dbSZbigniew Bodek 409169ca3dbSZbigniew Bodek /* Select auth algo */ 410169ca3dbSZbigniew Bodek switch (auth_xform->auth.algo) { 411169ca3dbSZbigniew Bodek /* Cover supported hash algorithms */ 412169ca3dbSZbigniew Bodek case RTE_CRYPTO_AUTH_SHA1_HMAC: 413169ca3dbSZbigniew Bodek case RTE_CRYPTO_AUTH_SHA256_HMAC: /* Fall through */ 414169ca3dbSZbigniew Bodek aalg = auth_xform->auth.algo; 415169ca3dbSZbigniew Bodek sess->auth.mode = ARMV8_CRYPTO_AUTH_AS_HMAC; 416169ca3dbSZbigniew Bodek break; 417169ca3dbSZbigniew Bodek default: 41827391b53SPablo de Lara return -ENOTSUP; 419169ca3dbSZbigniew Bodek } 420169ca3dbSZbigniew Bodek 4217f003427SPablo de Lara /* Set the digest length */ 4227f003427SPablo de Lara sess->auth.digest_length = auth_xform->auth.digest_length; 4237f003427SPablo de Lara 424169ca3dbSZbigniew Bodek /* Verify supported key lengths and extract proper algorithm */ 425169ca3dbSZbigniew Bodek switch (cipher_xform->cipher.key.length << 3) { 426169ca3dbSZbigniew Bodek case 128: 427169ca3dbSZbigniew Bodek sess->crypto_func = 428169ca3dbSZbigniew Bodek CRYPTO_GET_ALGO(order, cop, calg, aalg, 128); 429169ca3dbSZbigniew Bodek sess->cipher.key_sched = 430169ca3dbSZbigniew Bodek CRYPTO_GET_KEY_SCHED(cop, calg, 128); 431169ca3dbSZbigniew Bodek break; 432169ca3dbSZbigniew Bodek case 192: 433169ca3dbSZbigniew Bodek case 256: 434169ca3dbSZbigniew Bodek /* These key lengths are not supported yet */ 435169ca3dbSZbigniew Bodek default: /* Fall through */ 436169ca3dbSZbigniew Bodek sess->crypto_func = NULL; 437169ca3dbSZbigniew Bodek sess->cipher.key_sched = NULL; 43827391b53SPablo de Lara return -ENOTSUP; 439169ca3dbSZbigniew Bodek } 440169ca3dbSZbigniew Bodek 441087ed975SRuifeng Wang if (unlikely(sess->crypto_func == NULL || 442087ed975SRuifeng Wang sess->cipher.key_sched == NULL)) { 443169ca3dbSZbigniew Bodek /* 444169ca3dbSZbigniew Bodek * If we got here that means that there must be a bug 445169ca3dbSZbigniew Bodek * in the algorithms selection above. Nevertheless keep 446169ca3dbSZbigniew Bodek * it here to catch bug immediately and avoid NULL pointer 447169ca3dbSZbigniew Bodek * dereference in OPs processing. 448169ca3dbSZbigniew Bodek */ 449169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR( 450169ca3dbSZbigniew Bodek "No appropriate crypto function for given parameters"); 451169ca3dbSZbigniew Bodek return -EINVAL; 452169ca3dbSZbigniew Bodek } 453169ca3dbSZbigniew Bodek 454169ca3dbSZbigniew Bodek /* Set up cipher session prerequisites */ 455169ca3dbSZbigniew Bodek if (cipher_set_prerequisites(sess, cipher_xform) != 0) 456169ca3dbSZbigniew Bodek return -EINVAL; 457169ca3dbSZbigniew Bodek 458169ca3dbSZbigniew Bodek /* Set up authentication session prerequisites */ 459169ca3dbSZbigniew Bodek if (auth_set_prerequisites(sess, auth_xform) != 0) 460169ca3dbSZbigniew Bodek return -EINVAL; 461169ca3dbSZbigniew Bodek 462169ca3dbSZbigniew Bodek return 0; 463169ca3dbSZbigniew Bodek } 464169ca3dbSZbigniew Bodek 465169ca3dbSZbigniew Bodek /** Parse crypto xform chain and set private session parameters */ 466169ca3dbSZbigniew Bodek int 467169ca3dbSZbigniew Bodek armv8_crypto_set_session_parameters(struct armv8_crypto_session *sess, 468169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *xform) 469169ca3dbSZbigniew Bodek { 470169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *cipher_xform = NULL; 471169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *auth_xform = NULL; 472169ca3dbSZbigniew Bodek bool is_chained_op; 473169ca3dbSZbigniew Bodek int ret; 474169ca3dbSZbigniew Bodek 475169ca3dbSZbigniew Bodek /* Filter out spurious/broken requests */ 476169ca3dbSZbigniew Bodek if (xform == NULL) 477169ca3dbSZbigniew Bodek return -EINVAL; 478169ca3dbSZbigniew Bodek 479169ca3dbSZbigniew Bodek sess->chain_order = armv8_crypto_get_chain_order(xform); 480169ca3dbSZbigniew Bodek switch (sess->chain_order) { 481169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_CIPHER_AUTH: 482169ca3dbSZbigniew Bodek cipher_xform = xform; 483169ca3dbSZbigniew Bodek auth_xform = xform->next; 484169ca3dbSZbigniew Bodek is_chained_op = true; 485169ca3dbSZbigniew Bodek break; 486169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_AUTH_CIPHER: 487169ca3dbSZbigniew Bodek auth_xform = xform; 488169ca3dbSZbigniew Bodek cipher_xform = xform->next; 489169ca3dbSZbigniew Bodek is_chained_op = true; 490169ca3dbSZbigniew Bodek break; 491169ca3dbSZbigniew Bodek default: 492169ca3dbSZbigniew Bodek is_chained_op = false; 49327391b53SPablo de Lara return -ENOTSUP; 494169ca3dbSZbigniew Bodek } 495169ca3dbSZbigniew Bodek 4960fbd75a9SPablo de Lara /* Set IV offset */ 4970fbd75a9SPablo de Lara sess->cipher.iv.offset = cipher_xform->cipher.iv.offset; 4980fbd75a9SPablo de Lara 499169ca3dbSZbigniew Bodek if (is_chained_op) { 500169ca3dbSZbigniew Bodek ret = armv8_crypto_set_session_chained_parameters(sess, 501169ca3dbSZbigniew Bodek cipher_xform, auth_xform); 502169ca3dbSZbigniew Bodek if (unlikely(ret != 0)) { 503169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR( 504169ca3dbSZbigniew Bodek "Invalid/unsupported chained (cipher/auth) parameters"); 50527391b53SPablo de Lara return ret; 506169ca3dbSZbigniew Bodek } 507169ca3dbSZbigniew Bodek } else { 508169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR("Invalid/unsupported operation"); 50927391b53SPablo de Lara return -ENOTSUP; 510169ca3dbSZbigniew Bodek } 511169ca3dbSZbigniew Bodek 512169ca3dbSZbigniew Bodek return 0; 513169ca3dbSZbigniew Bodek } 514169ca3dbSZbigniew Bodek 515169ca3dbSZbigniew Bodek /** Provide session for operation */ 516169ca3dbSZbigniew Bodek static inline struct armv8_crypto_session * 517169ca3dbSZbigniew Bodek get_session(struct armv8_crypto_qp *qp, struct rte_crypto_op *op) 518169ca3dbSZbigniew Bodek { 519169ca3dbSZbigniew Bodek struct armv8_crypto_session *sess = NULL; 520169ca3dbSZbigniew Bodek 5215209df0dSPablo de Lara if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { 522169ca3dbSZbigniew Bodek /* get existing session */ 52370c5c3d1SSlawomir Mrozowicz if (likely(op->sym->session != NULL)) { 524*bdce2564SAkhil Goyal sess = CRYPTODEV_GET_SYM_SESS_PRIV(op->sym->session); 525169ca3dbSZbigniew Bodek } 526169ca3dbSZbigniew Bodek } else { 527169ca3dbSZbigniew Bodek /* provide internal session */ 528*bdce2564SAkhil Goyal struct rte_cryptodev_sym_session *_sess = NULL; 529169ca3dbSZbigniew Bodek 530b3bbd9e5SSlawomir Mrozowicz if (rte_mempool_get(qp->sess_mp, (void **)&_sess)) 531b3bbd9e5SSlawomir Mrozowicz return NULL; 532169ca3dbSZbigniew Bodek 533*bdce2564SAkhil Goyal sess = (struct armv8_crypto_session *)_sess->driver_priv_data; 534b3bbd9e5SSlawomir Mrozowicz 535b3bbd9e5SSlawomir Mrozowicz if (unlikely(armv8_crypto_set_session_parameters(sess, 536b3bbd9e5SSlawomir Mrozowicz op->sym->xform) != 0)) { 537169ca3dbSZbigniew Bodek rte_mempool_put(qp->sess_mp, _sess); 538169ca3dbSZbigniew Bodek sess = NULL; 539169ca3dbSZbigniew Bodek } 540b3bbd9e5SSlawomir Mrozowicz op->sym->session = (struct rte_cryptodev_sym_session *)_sess; 541169ca3dbSZbigniew Bodek } 542169ca3dbSZbigniew Bodek 543169ca3dbSZbigniew Bodek if (unlikely(sess == NULL)) 544169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION; 545169ca3dbSZbigniew Bodek 546169ca3dbSZbigniew Bodek return sess; 547169ca3dbSZbigniew Bodek } 548169ca3dbSZbigniew Bodek 549169ca3dbSZbigniew Bodek /* 550169ca3dbSZbigniew Bodek *------------------------------------------------------------------------------ 551169ca3dbSZbigniew Bodek * Process Operations 552169ca3dbSZbigniew Bodek *------------------------------------------------------------------------------ 553169ca3dbSZbigniew Bodek */ 554169ca3dbSZbigniew Bodek 555169ca3dbSZbigniew Bodek /*----------------------------------------------------------------------------*/ 556169ca3dbSZbigniew Bodek 557169ca3dbSZbigniew Bodek /** Process cipher operation */ 558169ca3dbSZbigniew Bodek static inline void 55940705eb3SPablo de Lara process_armv8_chained_op(struct armv8_crypto_qp *qp, struct rte_crypto_op *op, 56040705eb3SPablo de Lara struct armv8_crypto_session *sess, 561169ca3dbSZbigniew Bodek struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) 562169ca3dbSZbigniew Bodek { 563169ca3dbSZbigniew Bodek crypto_func_t crypto_func; 564bde43e8aSRuifeng Wang armv8_cipher_digest_t arg; 565169ca3dbSZbigniew Bodek struct rte_mbuf *m_asrc, *m_adst; 566169ca3dbSZbigniew Bodek uint8_t *csrc, *cdst; 567169ca3dbSZbigniew Bodek uint8_t *adst, *asrc; 568169ca3dbSZbigniew Bodek uint64_t clen, alen; 569169ca3dbSZbigniew Bodek int error; 570169ca3dbSZbigniew Bodek 571169ca3dbSZbigniew Bodek clen = op->sym->cipher.data.length; 572169ca3dbSZbigniew Bodek alen = op->sym->auth.data.length; 573169ca3dbSZbigniew Bodek 574169ca3dbSZbigniew Bodek csrc = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, 575169ca3dbSZbigniew Bodek op->sym->cipher.data.offset); 576169ca3dbSZbigniew Bodek cdst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, 577169ca3dbSZbigniew Bodek op->sym->cipher.data.offset); 578169ca3dbSZbigniew Bodek 579169ca3dbSZbigniew Bodek switch (sess->chain_order) { 580169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_CIPHER_AUTH: 581169ca3dbSZbigniew Bodek m_asrc = m_adst = mbuf_dst; 582169ca3dbSZbigniew Bodek break; 583169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_AUTH_CIPHER: 584169ca3dbSZbigniew Bodek m_asrc = mbuf_src; 585169ca3dbSZbigniew Bodek m_adst = mbuf_dst; 586169ca3dbSZbigniew Bodek break; 587169ca3dbSZbigniew Bodek default: 588169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; 589169ca3dbSZbigniew Bodek return; 590169ca3dbSZbigniew Bodek } 591169ca3dbSZbigniew Bodek asrc = rte_pktmbuf_mtod_offset(m_asrc, uint8_t *, 592169ca3dbSZbigniew Bodek op->sym->auth.data.offset); 593169ca3dbSZbigniew Bodek 594169ca3dbSZbigniew Bodek switch (sess->auth.mode) { 595169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_AUTH_AS_AUTH: 596169ca3dbSZbigniew Bodek /* Nothing to do here, just verify correct option */ 597169ca3dbSZbigniew Bodek break; 598169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_AUTH_AS_HMAC: 599169ca3dbSZbigniew Bodek arg.digest.hmac.key = sess->auth.hmac.key; 600169ca3dbSZbigniew Bodek arg.digest.hmac.i_key_pad = sess->auth.hmac.i_key_pad; 601169ca3dbSZbigniew Bodek arg.digest.hmac.o_key_pad = sess->auth.hmac.o_key_pad; 602169ca3dbSZbigniew Bodek break; 603169ca3dbSZbigniew Bodek default: 604169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; 605169ca3dbSZbigniew Bodek return; 606169ca3dbSZbigniew Bodek } 607169ca3dbSZbigniew Bodek 608169ca3dbSZbigniew Bodek if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_GENERATE) { 609169ca3dbSZbigniew Bodek adst = op->sym->auth.digest.data; 610169ca3dbSZbigniew Bodek if (adst == NULL) { 611169ca3dbSZbigniew Bodek adst = rte_pktmbuf_mtod_offset(m_adst, 612169ca3dbSZbigniew Bodek uint8_t *, 613169ca3dbSZbigniew Bodek op->sym->auth.data.offset + 614169ca3dbSZbigniew Bodek op->sym->auth.data.length); 615169ca3dbSZbigniew Bodek } 616169ca3dbSZbigniew Bodek } else { 61740705eb3SPablo de Lara adst = qp->temp_digest; 618169ca3dbSZbigniew Bodek } 619169ca3dbSZbigniew Bodek 6205082f991SPablo de Lara arg.cipher.iv = rte_crypto_op_ctod_offset(op, uint8_t *, 6210fbd75a9SPablo de Lara sess->cipher.iv.offset); 622169ca3dbSZbigniew Bodek arg.cipher.key = sess->cipher.key.data; 623169ca3dbSZbigniew Bodek /* Acquire combined mode function */ 624169ca3dbSZbigniew Bodek crypto_func = sess->crypto_func; 6251ee3c4b4SRuifeng Wang RTE_VERIFY(crypto_func != NULL); 626169ca3dbSZbigniew Bodek error = crypto_func(csrc, cdst, clen, asrc, adst, alen, &arg); 627169ca3dbSZbigniew Bodek if (error != 0) { 628169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; 629169ca3dbSZbigniew Bodek return; 630169ca3dbSZbigniew Bodek } 631169ca3dbSZbigniew Bodek 632169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; 633169ca3dbSZbigniew Bodek if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) { 634169ca3dbSZbigniew Bodek if (memcmp(adst, op->sym->auth.digest.data, 6357f003427SPablo de Lara sess->auth.digest_length) != 0) { 636169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; 637169ca3dbSZbigniew Bodek } 638169ca3dbSZbigniew Bodek } 639169ca3dbSZbigniew Bodek } 640169ca3dbSZbigniew Bodek 641169ca3dbSZbigniew Bodek /** Process crypto operation for mbuf */ 642169ca3dbSZbigniew Bodek static inline int 64340705eb3SPablo de Lara process_op(struct armv8_crypto_qp *qp, struct rte_crypto_op *op, 644169ca3dbSZbigniew Bodek struct armv8_crypto_session *sess) 645169ca3dbSZbigniew Bodek { 646169ca3dbSZbigniew Bodek struct rte_mbuf *msrc, *mdst; 647169ca3dbSZbigniew Bodek 648169ca3dbSZbigniew Bodek msrc = op->sym->m_src; 649169ca3dbSZbigniew Bodek mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src; 650169ca3dbSZbigniew Bodek 651169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; 652169ca3dbSZbigniew Bodek 653169ca3dbSZbigniew Bodek switch (sess->chain_order) { 654169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_CIPHER_AUTH: 655169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_AUTH_CIPHER: /* Fall through */ 65640705eb3SPablo de Lara process_armv8_chained_op(qp, op, sess, msrc, mdst); 657169ca3dbSZbigniew Bodek break; 658169ca3dbSZbigniew Bodek default: 659169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_ERROR; 660169ca3dbSZbigniew Bodek break; 661169ca3dbSZbigniew Bodek } 662169ca3dbSZbigniew Bodek 663169ca3dbSZbigniew Bodek /* Free session if a session-less crypto op */ 6645209df0dSPablo de Lara if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) { 665169ca3dbSZbigniew Bodek memset(sess, 0, sizeof(struct armv8_crypto_session)); 66676a4ed5bSRuifeng Wang rte_mempool_put(qp->sess_mp, op->sym->session); 667169ca3dbSZbigniew Bodek op->sym->session = NULL; 668169ca3dbSZbigniew Bodek } 669169ca3dbSZbigniew Bodek 670169ca3dbSZbigniew Bodek if (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED) 671169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; 672169ca3dbSZbigniew Bodek 673169ca3dbSZbigniew Bodek if (unlikely(op->status == RTE_CRYPTO_OP_STATUS_ERROR)) 674169ca3dbSZbigniew Bodek return -1; 675169ca3dbSZbigniew Bodek 676169ca3dbSZbigniew Bodek return 0; 677169ca3dbSZbigniew Bodek } 678169ca3dbSZbigniew Bodek 679169ca3dbSZbigniew Bodek /* 680169ca3dbSZbigniew Bodek *------------------------------------------------------------------------------ 681169ca3dbSZbigniew Bodek * PMD Framework 682169ca3dbSZbigniew Bodek *------------------------------------------------------------------------------ 683169ca3dbSZbigniew Bodek */ 684169ca3dbSZbigniew Bodek 685169ca3dbSZbigniew Bodek /** Enqueue burst */ 686169ca3dbSZbigniew Bodek static uint16_t 687169ca3dbSZbigniew Bodek armv8_crypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops, 688169ca3dbSZbigniew Bodek uint16_t nb_ops) 689169ca3dbSZbigniew Bodek { 690169ca3dbSZbigniew Bodek struct armv8_crypto_session *sess; 691169ca3dbSZbigniew Bodek struct armv8_crypto_qp *qp = queue_pair; 692169ca3dbSZbigniew Bodek int i, retval; 693169ca3dbSZbigniew Bodek 694169ca3dbSZbigniew Bodek for (i = 0; i < nb_ops; i++) { 695169ca3dbSZbigniew Bodek sess = get_session(qp, ops[i]); 696169ca3dbSZbigniew Bodek if (unlikely(sess == NULL)) 697169ca3dbSZbigniew Bodek goto enqueue_err; 698169ca3dbSZbigniew Bodek 699169ca3dbSZbigniew Bodek retval = process_op(qp, ops[i], sess); 700169ca3dbSZbigniew Bodek if (unlikely(retval < 0)) 701169ca3dbSZbigniew Bodek goto enqueue_err; 702169ca3dbSZbigniew Bodek } 703169ca3dbSZbigniew Bodek 70414fbffb0SBruce Richardson retval = rte_ring_enqueue_burst(qp->processed_ops, (void *)ops, i, 70514fbffb0SBruce Richardson NULL); 706169ca3dbSZbigniew Bodek qp->stats.enqueued_count += retval; 707169ca3dbSZbigniew Bodek 708169ca3dbSZbigniew Bodek return retval; 709169ca3dbSZbigniew Bodek 710169ca3dbSZbigniew Bodek enqueue_err: 71114fbffb0SBruce Richardson retval = rte_ring_enqueue_burst(qp->processed_ops, (void *)ops, i, 71214fbffb0SBruce Richardson NULL); 713169ca3dbSZbigniew Bodek if (ops[i] != NULL) 714169ca3dbSZbigniew Bodek ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; 715169ca3dbSZbigniew Bodek 716169ca3dbSZbigniew Bodek qp->stats.enqueue_err_count++; 717169ca3dbSZbigniew Bodek return retval; 718169ca3dbSZbigniew Bodek } 719169ca3dbSZbigniew Bodek 720169ca3dbSZbigniew Bodek /** Dequeue burst */ 721169ca3dbSZbigniew Bodek static uint16_t 722169ca3dbSZbigniew Bodek armv8_crypto_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops, 723169ca3dbSZbigniew Bodek uint16_t nb_ops) 724169ca3dbSZbigniew Bodek { 725169ca3dbSZbigniew Bodek struct armv8_crypto_qp *qp = queue_pair; 726169ca3dbSZbigniew Bodek 727169ca3dbSZbigniew Bodek unsigned int nb_dequeued = 0; 728169ca3dbSZbigniew Bodek 729169ca3dbSZbigniew Bodek nb_dequeued = rte_ring_dequeue_burst(qp->processed_ops, 730ecaed092SBruce Richardson (void **)ops, nb_ops, NULL); 731169ca3dbSZbigniew Bodek qp->stats.dequeued_count += nb_dequeued; 732169ca3dbSZbigniew Bodek 733169ca3dbSZbigniew Bodek return nb_dequeued; 734169ca3dbSZbigniew Bodek } 735169ca3dbSZbigniew Bodek 736169ca3dbSZbigniew Bodek /** Create ARMv8 crypto device */ 737169ca3dbSZbigniew Bodek static int 738168b9e76SPablo de Lara cryptodev_armv8_crypto_create(const char *name, 739168b9e76SPablo de Lara struct rte_vdev_device *vdev, 740f2f020d2SDeclan Doherty struct rte_cryptodev_pmd_init_params *init_params) 741169ca3dbSZbigniew Bodek { 742169ca3dbSZbigniew Bodek struct rte_cryptodev *dev; 743169ca3dbSZbigniew Bodek struct armv8_crypto_private *internals; 744169ca3dbSZbigniew Bodek 745169ca3dbSZbigniew Bodek /* Check CPU for support for AES instruction set */ 746169ca3dbSZbigniew Bodek if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_AES)) { 747169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR( 748169ca3dbSZbigniew Bodek "AES instructions not supported by CPU"); 749169ca3dbSZbigniew Bodek return -EFAULT; 750169ca3dbSZbigniew Bodek } 751169ca3dbSZbigniew Bodek 752169ca3dbSZbigniew Bodek /* Check CPU for support for SHA instruction set */ 753169ca3dbSZbigniew Bodek if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_SHA1) || 754169ca3dbSZbigniew Bodek !rte_cpu_get_flag_enabled(RTE_CPUFLAG_SHA2)) { 755169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR( 756169ca3dbSZbigniew Bodek "SHA1/SHA2 instructions not supported by CPU"); 757169ca3dbSZbigniew Bodek return -EFAULT; 758169ca3dbSZbigniew Bodek } 759169ca3dbSZbigniew Bodek 760169ca3dbSZbigniew Bodek /* Check CPU for support for Advance SIMD instruction set */ 761169ca3dbSZbigniew Bodek if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON)) { 762169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR( 763169ca3dbSZbigniew Bodek "Advanced SIMD instructions not supported by CPU"); 764169ca3dbSZbigniew Bodek return -EFAULT; 765169ca3dbSZbigniew Bodek } 766169ca3dbSZbigniew Bodek 767f2f020d2SDeclan Doherty dev = rte_cryptodev_pmd_create(name, &vdev->device, init_params); 768169ca3dbSZbigniew Bodek if (dev == NULL) { 769169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR("failed to create cryptodev vdev"); 770169ca3dbSZbigniew Bodek goto init_error; 771169ca3dbSZbigniew Bodek } 772169ca3dbSZbigniew Bodek 7737a364faeSSlawomir Mrozowicz dev->driver_id = cryptodev_driver_id; 774169ca3dbSZbigniew Bodek dev->dev_ops = rte_armv8_crypto_pmd_ops; 775169ca3dbSZbigniew Bodek 776169ca3dbSZbigniew Bodek /* register rx/tx burst functions for data path */ 777169ca3dbSZbigniew Bodek dev->dequeue_burst = armv8_crypto_pmd_dequeue_burst; 778169ca3dbSZbigniew Bodek dev->enqueue_burst = armv8_crypto_pmd_enqueue_burst; 779169ca3dbSZbigniew Bodek 780169ca3dbSZbigniew Bodek dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | 781c2fec022SZbigniew Bodek RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | 782c2fec022SZbigniew Bodek RTE_CRYPTODEV_FF_CPU_NEON | 783b3aaf24dSPablo de Lara RTE_CRYPTODEV_FF_CPU_ARM_CE | 784b3aaf24dSPablo de Lara RTE_CRYPTODEV_FF_SYM_SESSIONLESS; 785169ca3dbSZbigniew Bodek 786169ca3dbSZbigniew Bodek internals = dev->data->dev_private; 787169ca3dbSZbigniew Bodek 788169ca3dbSZbigniew Bodek internals->max_nb_qpairs = init_params->max_nb_queue_pairs; 789169ca3dbSZbigniew Bodek 790d54c72ecSAkhil Goyal rte_cryptodev_pmd_probing_finish(dev); 791d54c72ecSAkhil Goyal 792169ca3dbSZbigniew Bodek return 0; 793169ca3dbSZbigniew Bodek 794169ca3dbSZbigniew Bodek init_error: 795169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR( 796169ca3dbSZbigniew Bodek "driver %s: cryptodev_armv8_crypto_create failed", 797169ca3dbSZbigniew Bodek init_params->name); 798169ca3dbSZbigniew Bodek 7995d2aa461SJan Blunck cryptodev_armv8_crypto_uninit(vdev); 800169ca3dbSZbigniew Bodek return -EFAULT; 801169ca3dbSZbigniew Bodek } 802169ca3dbSZbigniew Bodek 803169ca3dbSZbigniew Bodek /** Initialise ARMv8 crypto device */ 804169ca3dbSZbigniew Bodek static int 8055d2aa461SJan Blunck cryptodev_armv8_crypto_init(struct rte_vdev_device *vdev) 806169ca3dbSZbigniew Bodek { 807f2f020d2SDeclan Doherty struct rte_cryptodev_pmd_init_params init_params = { 808f2f020d2SDeclan Doherty "", 809f2f020d2SDeclan Doherty sizeof(struct armv8_crypto_private), 810169ca3dbSZbigniew Bodek rte_socket_id(), 811e1fc5b76SPablo de Lara RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS 812169ca3dbSZbigniew Bodek }; 8135d2aa461SJan Blunck const char *name; 8145d2aa461SJan Blunck const char *input_args; 815169ca3dbSZbigniew Bodek 8165d2aa461SJan Blunck name = rte_vdev_device_name(vdev); 8177e214771SPablo de Lara if (name == NULL) 8187e214771SPablo de Lara return -EINVAL; 8195d2aa461SJan Blunck input_args = rte_vdev_device_args(vdev); 820f2f020d2SDeclan Doherty rte_cryptodev_pmd_parse_input_args(&init_params, input_args); 821169ca3dbSZbigniew Bodek 822168b9e76SPablo de Lara return cryptodev_armv8_crypto_create(name, vdev, &init_params); 823169ca3dbSZbigniew Bodek } 824169ca3dbSZbigniew Bodek 825169ca3dbSZbigniew Bodek /** Uninitialise ARMv8 crypto device */ 826169ca3dbSZbigniew Bodek static int 8275d2aa461SJan Blunck cryptodev_armv8_crypto_uninit(struct rte_vdev_device *vdev) 828169ca3dbSZbigniew Bodek { 829f2f020d2SDeclan Doherty struct rte_cryptodev *cryptodev; 8305d2aa461SJan Blunck const char *name; 8315d2aa461SJan Blunck 8325d2aa461SJan Blunck name = rte_vdev_device_name(vdev); 833169ca3dbSZbigniew Bodek if (name == NULL) 834169ca3dbSZbigniew Bodek return -EINVAL; 835169ca3dbSZbigniew Bodek 836169ca3dbSZbigniew Bodek RTE_LOG(INFO, PMD, 837169ca3dbSZbigniew Bodek "Closing ARMv8 crypto device %s on numa socket %u\n", 838169ca3dbSZbigniew Bodek name, rte_socket_id()); 839169ca3dbSZbigniew Bodek 840f2f020d2SDeclan Doherty cryptodev = rte_cryptodev_pmd_get_named_dev(name); 841f2f020d2SDeclan Doherty if (cryptodev == NULL) 842f2f020d2SDeclan Doherty return -ENODEV; 843f2f020d2SDeclan Doherty 844f2f020d2SDeclan Doherty return rte_cryptodev_pmd_destroy(cryptodev); 845169ca3dbSZbigniew Bodek } 846169ca3dbSZbigniew Bodek 847effd3b9fSPablo de Lara static struct rte_vdev_driver armv8_crypto_pmd_drv = { 848169ca3dbSZbigniew Bodek .probe = cryptodev_armv8_crypto_init, 849169ca3dbSZbigniew Bodek .remove = cryptodev_armv8_crypto_uninit 850169ca3dbSZbigniew Bodek }; 851169ca3dbSZbigniew Bodek 852effd3b9fSPablo de Lara static struct cryptodev_driver armv8_crypto_drv; 853effd3b9fSPablo de Lara 854eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(crypto_armv8_log_type, ERR); 85528b05145SRuifeng Wang 856effd3b9fSPablo de Lara RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_ARMV8_PMD, armv8_crypto_pmd_drv); 857169ca3dbSZbigniew Bodek RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_ARMV8_PMD, cryptodev_armv8_pmd); 858169ca3dbSZbigniew Bodek RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_ARMV8_PMD, 859169ca3dbSZbigniew Bodek "max_nb_queue_pairs=<int> " 860169ca3dbSZbigniew Bodek "socket_id=<int>"); 861f737f5ceSFiona Trahe RTE_PMD_REGISTER_CRYPTO_DRIVER(armv8_crypto_drv, armv8_crypto_pmd_drv.driver, 862effd3b9fSPablo de Lara cryptodev_driver_id); 863