xref: /spdk/module/bdev/crypto/vbdev_crypto.h (revision 0098e636761237b77c12c30c2408263a5d2260cc)
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