1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. 5 * All rights reserved. 6 */ 7 8 #ifndef SPDK_VBDEV_CRYPTO_H 9 #define SPDK_VBDEV_CRYPTO_H 10 11 #include "spdk/rpc.h" 12 #include "spdk/util.h" 13 #include "spdk/string.h" 14 #include "spdk/log.h" 15 16 #include "spdk/bdev.h" 17 18 #define AESNI_MB "crypto_aesni_mb" 19 #define QAT "crypto_qat" 20 #define QAT_ASYM "crypto_qat_asym" 21 #define MLX5 "mlx5_pci" 22 23 /* Supported ciphers */ 24 #define AES_CBC "AES_CBC" /* QAT and AESNI_MB */ 25 #define AES_XTS "AES_XTS" /* QAT and MLX5 */ 26 27 /* Specific to AES_CBC. */ 28 #define AES_CBC_KEY_LENGTH 16 29 30 #define AES_XTS_128_BLOCK_KEY_LENGTH 16 /* AES-XTS-128 block key size. */ 31 #define AES_XTS_256_BLOCK_KEY_LENGTH 32 /* AES-XTS-256 block key size. */ 32 #define AES_XTS_512_BLOCK_KEY_LENGTH 64 /* AES-XTS-512 block key size. */ 33 34 #define AES_XTS_TWEAK_KEY_LENGTH 16 /* XTS part key size is always 128 bit. */ 35 36 /* Structure to hold crypto options for crypto pmd setup. */ 37 struct vbdev_crypto_opts { 38 char *vbdev_name; /* name of the vbdev to create */ 39 char *bdev_name; /* base bdev name */ 40 41 char *drv_name; /* name of the crypto device driver */ 42 char *cipher; /* AES_CBC or AES_XTS */ 43 44 /* Note, for dev/test we allow use of key in the config file, for production 45 * use, you must use an RPC to specify the key for security reasons. 46 */ 47 uint8_t *key; /* key per bdev */ 48 uint8_t key_size; /* key size */ 49 uint8_t *key2; /* key #2 for AES_XTS, per bdev */ 50 uint8_t key2_size; /* key #2 size */ 51 uint8_t *xts_key; /* key + key 2 */ 52 }; 53 54 typedef void (*spdk_delete_crypto_complete)(void *cb_arg, int bdeverrno); 55 56 /** 57 * Create new crypto bdev. 58 * 59 * \param opts Crypto options populated by create_crypto_opts() 60 * \return 0 on success, other on failure. 61 */ 62 int create_crypto_disk(struct vbdev_crypto_opts *opts); 63 64 /** 65 * Delete crypto bdev. 66 * 67 * \param bdev_name Crypto bdev name. 68 * \param cb_fn Function to call after deletion. 69 * \param cb_arg Argument to pass to cb_fn. 70 */ 71 void delete_crypto_disk(const char *bdev_name, spdk_delete_crypto_complete cb_fn, 72 void *cb_arg); 73 74 /** 75 * Release crypto opts created with create_crypto_opts() 76 * 77 * \param opts Crypto opts to release 78 */ 79 void free_crypto_opts(struct vbdev_crypto_opts *opts); 80 81 static inline int 82 __c2v(char c) 83 { 84 if ((c >= '0') && (c <= '9')) { 85 return c - '0'; 86 } 87 if ((c >= 'a') && (c <= 'f')) { 88 return c - 'a' + 10; 89 } 90 if ((c >= 'A') && (c <= 'F')) { 91 return c - 'A' + 10; 92 } 93 return -1; 94 } 95 96 static inline char 97 __v2c(int c) 98 { 99 const char hexchar[] = "0123456789abcdef"; 100 if (c < 0 || c > 15) { 101 return -1; 102 } 103 return hexchar[c]; 104 } 105 106 /** 107 * Convert a binary array to hexlified string terminated by zero. 108 * 109 * \param bin A binary array pointer. 110 * \param len Length of the binary array. 111 * \return Pointer to hexlified version of @bin or NULL on failure. 112 */ 113 static inline char * 114 hexlify(const char *bin, size_t len) 115 { 116 char *hex, *phex; 117 118 hex = malloc((len * 2) + 1); 119 if (hex == NULL) { 120 return NULL; 121 } 122 phex = hex; 123 for (size_t i = 0; i < len; i++) { 124 char c0 = __v2c((bin[i] >> 4) & 0x0f); 125 char c1 = __v2c((bin[i]) & 0x0f); 126 if (c0 < 0 || c1 < 0) { 127 assert(false); 128 free(hex); 129 return NULL; 130 } 131 *phex++ = c0; 132 *phex++ = c1; 133 } 134 *phex = '\0'; 135 return hex; 136 } 137 138 /** 139 * Convert hexlified string to binary array of size strlen(hex) / 2. 140 * 141 * \param hex A hexlified string terminated by zero. 142 * \return Binary array pointer or NULL on failure. 143 */ 144 static inline char * 145 unhexlify(const char *hex) 146 { 147 char *res, *pres; 148 size_t len = strlen(hex); 149 150 if (len % 2 != 0) { 151 SPDK_ERRLOG("Invalid hex string len %d. It must be mod of 2.\n", (int)len); 152 return NULL; 153 } 154 res = malloc(len / 2); 155 if (res == NULL) { 156 return NULL; 157 } 158 pres = res; 159 for (size_t i = 0; i < len; i += 2) { 160 int v0 = __c2v(hex[i]); 161 int v1 = __c2v(hex[i + 1]); 162 if (v0 < 0 || v1 < 0) { 163 SPDK_ERRLOG("Invalid hex string \"%s\"\n", hex); 164 free(res); 165 return NULL; 166 } 167 *pres++ = (v0 << 4) + v1; 168 } 169 return res; 170 } 171 172 #endif /* SPDK_VBDEV_CRYPTO_H */ 173