xref: /spdk/module/bdev/crypto/vbdev_crypto.h (revision 7506a7aa53d239f533af3bc768f0d2af55e735fe)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *   Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
7  *   All rights reserved.
8  *
9  *   Redistribution and use in source and binary forms, with or without
10  *   modification, are permitted provided that the following conditions
11  *   are met:
12  *
13  *     * Redistributions of source code must retain the above copyright
14  *       notice, this list of conditions and the following disclaimer.
15  *     * Redistributions in binary form must reproduce the above copyright
16  *       notice, this list of conditions and the following disclaimer in
17  *       the documentation and/or other materials provided with the
18  *       distribution.
19  *     * Neither the name of Intel Corporation nor the names of its
20  *       contributors may be used to endorse or promote products derived
21  *       from this software without specific prior written permission.
22  *
23  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #ifndef SPDK_VBDEV_CRYPTO_H
37 #define SPDK_VBDEV_CRYPTO_H
38 
39 #include "spdk/rpc.h"
40 #include "spdk/util.h"
41 #include "spdk/string.h"
42 #include "spdk/log.h"
43 
44 #include "spdk/bdev.h"
45 
46 #define AESNI_MB "crypto_aesni_mb"
47 #define QAT "crypto_qat"
48 #define QAT_ASYM "crypto_qat_asym"
49 #define MLX5 "mlx5_pci"
50 
51 /* Supported ciphers */
52 #define AES_CBC "AES_CBC" /* QAT and AESNI_MB */
53 #define AES_XTS "AES_XTS" /* QAT and MLX5 */
54 
55 /* Specific to AES_CBC. */
56 #define AES_CBC_KEY_LENGTH	     16
57 
58 #define AES_XTS_128_BLOCK_KEY_LENGTH 16 /* AES-XTS-128 block key size. */
59 #define AES_XTS_256_BLOCK_KEY_LENGTH 32 /* AES-XTS-256 block key size. */
60 #define AES_XTS_512_BLOCK_KEY_LENGTH 64 /* AES-XTS-512 block key size. */
61 
62 #define AES_XTS_TWEAK_KEY_LENGTH     16 /* XTS part key size is always 128 bit. */
63 
64 /* Structure to hold crypto options for crypto pmd setup. */
65 struct vbdev_crypto_opts {
66 	char				*vbdev_name;	/* name of the vbdev to create */
67 	char				*bdev_name;	/* base bdev name */
68 
69 	char				*drv_name;	/* name of the crypto device driver */
70 	char				*cipher;	/* AES_CBC or AES_XTS */
71 
72 	/* Note, for dev/test we allow use of key in the config file, for production
73 	 * use, you must use an RPC to specify the key for security reasons.
74 	 */
75 	uint8_t				*key;		/* key per bdev */
76 	uint8_t				key_size;	/* key size */
77 	uint8_t				*key2;		/* key #2 for AES_XTS, per bdev */
78 	uint8_t				key2_size;	/* key #2 size */
79 	uint8_t				*xts_key;	/* key + key 2 */
80 };
81 
82 typedef void (*spdk_delete_crypto_complete)(void *cb_arg, int bdeverrno);
83 
84 /**
85  * Create new crypto bdev.
86  *
87  * \param opts Crypto options populated by create_crypto_opts()
88  * \return 0 on success, other on failure.
89  */
90 int create_crypto_disk(struct vbdev_crypto_opts *opts);
91 
92 /**
93  * Delete crypto bdev.
94  *
95  * \param bdev_name Crypto bdev name.
96  * \param cb_fn Function to call after deletion.
97  * \param cb_arg Argument to pass to cb_fn.
98  */
99 void delete_crypto_disk(const char *bdev_name, spdk_delete_crypto_complete cb_fn,
100 			void *cb_arg);
101 
102 /**
103  * Release crypto opts created with create_crypto_opts()
104  *
105  * \param opts Crypto opts to release
106  */
107 void free_crypto_opts(struct vbdev_crypto_opts *opts);
108 
109 static inline int
110 __c2v(char c)
111 {
112 	if ((c >= '0') && (c <= '9')) {
113 		return c - '0';
114 	}
115 	if ((c >= 'a') && (c <= 'f')) {
116 		return c - 'a' + 10;
117 	}
118 	if ((c >= 'A') && (c <= 'F')) {
119 		return c - 'A' + 10;
120 	}
121 	return -1;
122 }
123 
124 static inline char
125 __v2c(int c)
126 {
127 	const char hexchar[] = "0123456789abcdef";
128 	if (c < 0 || c > 15) {
129 		return -1;
130 	}
131 	return hexchar[c];
132 }
133 
134 /**
135  * Convert a binary array to hexlified string terminated by zero.
136  *
137  * \param bin A binary array pointer.
138  * \param len Length of the binary array.
139  * \return Pointer to hexlified version of @bin or NULL on failure.
140  */
141 static inline char *
142 hexlify(const char *bin, size_t len)
143 {
144 	char *hex, *phex;
145 
146 	hex = malloc((len * 2) + 1);
147 	if (hex == NULL) {
148 		return NULL;
149 	}
150 	phex = hex;
151 	for (size_t i = 0; i < len; i++) {
152 		char c0 = __v2c((bin[i] >> 4) & 0x0f);
153 		char c1 = __v2c((bin[i]) & 0x0f);
154 		if (c0 < 0 || c1 < 0) {
155 			assert(false);
156 			free(hex);
157 			return NULL;
158 		}
159 		*phex++ = c0;
160 		*phex++ = c1;
161 	}
162 	*phex = '\0';
163 	return hex;
164 }
165 
166 /**
167  * Convert hexlified string to binary array of size strlen(hex) / 2.
168  *
169  * \param hex A hexlified string terminated by zero.
170  * \return Binary array pointer or NULL on failure.
171  */
172 static inline char *
173 unhexlify(const char *hex)
174 {
175 	char *res, *pres;
176 	size_t len = strlen(hex);
177 
178 	if (len % 2 != 0) {
179 		SPDK_ERRLOG("Invalid hex string len %d. It must be mod of 2.\n", (int)len);
180 		return NULL;
181 	}
182 	res = malloc(len / 2);
183 	if (res == NULL) {
184 		return NULL;
185 	}
186 	pres = res;
187 	for (size_t i = 0; i < len; i += 2) {
188 		int v0 = __c2v(hex[i]);
189 		int v1 = __c2v(hex[i + 1]);
190 		if (v0 < 0 || v1 < 0) {
191 			SPDK_ERRLOG("Invalid hex string \"%s\"\n", hex);
192 			free(res);
193 			return NULL;
194 		}
195 		*pres++ = (v0 << 4) + v1;
196 	}
197 	return res;
198 }
199 
200 #endif /* SPDK_VBDEV_CRYPTO_H */
201