2 * cryptsetup crypto name and hex conversion helper test vectors
4 * Copyright (C) 2022-2023 Milan Broz
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "utils_crypt.h"
26 #include "libcryptsetup.h"
29 # define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
33 * Cryptsetup/dm-crypt algorithm naming conversion test
35 struct mode_test_vector {
41 static struct mode_test_vector mode_test_vectors[] = {
42 { "aes-xts-plain", "aes", "xts-plain", 1 },
43 { "aes-xts-plain64", "aes", "xts-plain64", 1 },
44 { "aes-cbc-plain", "aes", "cbc-plain", 1 },
45 { "aes-cbc-plain64", "aes", "cbc-plain64", 1 },
46 { "aes-cbc-essiv:sha256", "aes", "cbc-essiv:sha256", 1 },
47 { "aes", "aes", "cbc-plain", 1 },
48 { "twofish", "twofish", "cbc-plain", 1 },
49 { "cipher_null", "cipher_null", "ecb", 0 },
50 { "null", "cipher_null", "ecb", 0 },
51 { "xchacha12,aes-adiantum-plain64", "xchacha12,aes", "adiantum-plain64", 1 },
52 { "xchacha20,aes-adiantum-plain64", "xchacha20,aes", "adiantum-plain64", 1 },
53 { "aes:64-cbc-lmk", "aes:64", "cbc-lmk", 64 },
54 { "des3_ede-cbc-tcw", "des3_ede" ,"cbc-tcw", 1 },
55 { "aes-lrw-benbi", "aes","lrw-benbi", 1 },
58 static int test_parse_mode(void)
60 char cipher[MAX_CIPHER_LEN], mode[MAX_CIPHER_LEN];
65 for (i = 0; i < ARRAY_SIZE(mode_test_vectors); i++) {
69 memset(cipher, 0, sizeof(cipher));
70 memset(mode, 0, sizeof(mode));
71 printf("[%s]", mode_test_vectors[i].input ?: "NULL");
72 if (crypt_parse_name_and_mode(mode_test_vectors[i].input, cipher, &keys, mode) < 0 ||
73 strcmp(mode_test_vectors[i].cipher, cipher) ||
74 strcmp(mode_test_vectors[i].mode, mode) ||
75 mode_test_vectors[i].keys != keys) {
76 printf("[FAILED (%s / %s / %i)]\n", cipher, mode, keys);
86 * Cryptsetup/dm-crypt/dm-integrity algorithm naming conversion test
88 struct integrity_test_vector {
89 bool int_mode; /* non-null if it is supported as integrity mode for LUKS2 */
91 const char *integrity;
94 static struct integrity_test_vector integrity_test_vectors[] = {
95 { true, "aead", "aead", 0 },
96 { true, "poly1305", "poly1305", 0 },
97 { true, "none", "none", 0 },
98 { false, "crc32", "crc32", 0 },
99 { true, "hmac-sha1", "hmac(sha1)", 20 },
100 { true, "hmac-sha256", "hmac(sha256)", 32 },
101 { true, "hmac-sha512", "hmac(sha512)", 64 },
102 { true, "cmac-aes", "cmac(aes)", 16 },
103 { false, "blake2b-256", "blake2b-256", 0 },
106 static int test_parse_integrity_mode(void)
108 char integrity[MAX_CIPHER_LEN];
112 printf("INTEGRITYCONV:");
113 for (i = 0; i < ARRAY_SIZE(integrity_test_vectors); i++) {
114 memset(integrity, 0, sizeof(integrity));
115 printf("[%s,%i]", integrity_test_vectors[i].input ?: "NULL", integrity_test_vectors[i].key_size);
116 if (crypt_parse_hash_integrity_mode(integrity_test_vectors[i].input, integrity) < 0 ||
117 strcmp(integrity_test_vectors[i].integrity, integrity)) {
118 printf("[FAILED (%s)]\n", integrity);
122 memset(integrity, 0, sizeof(integrity));
123 if (integrity_test_vectors[i].int_mode &&
124 (crypt_parse_integrity_mode(integrity_test_vectors[i].input, integrity, &key_size) < 0 ||
125 strcmp(integrity_test_vectors[i].integrity, integrity) ||
126 integrity_test_vectors[i].key_size != key_size)) {
127 printf("[FAILED (%s / %i)]\n", integrity, key_size);
137 * Cryptsetup null cipher bypass algorithm name
139 struct null_test_vector {
143 static struct null_test_vector null_test_vectors[] = {
144 { "cipher_null-ecb", true },
145 { "cipher_null", true },
147 { "cipher-null", false },
148 { "aes-ecb", false },
152 static int test_cipher_null(void)
157 for (i = 0; i < ARRAY_SIZE(null_test_vectors); i++) {
158 printf("[%s]", null_test_vectors[i].cipher ?: "NULL");
159 if (crypt_is_cipher_null(null_test_vectors[i].cipher) !=
160 null_test_vectors[i].ok) {
161 printf("[FAILED]\n");
170 struct hex_test_vector {
176 static struct hex_test_vector hex_test_vectors[] = {
177 { "0000000000000000", "\x00\x00\x00\x00\x00\x00\x00\x00", 8, true },
178 { "abcdef0123456789", "\xab\xcd\xef\x01\x23\x45\x67\x89", 8, true },
179 { "aBCDef0123456789", "\xab\xcd\xef\x01\x23\x45\x67\x89", 8, true },
180 { "ff", "\xff", 1, true },
181 { "f", NULL , 1, false },
182 { "a-cde", NULL, 2, false },
183 { "FAKE", NULL, 2, false },
184 { "\x01\x02\xff", NULL, 3, false },
185 { NULL, NULL, 1, false },
186 { "fff", NULL, 2, false },
187 { "fg", NULL, 1, false },
191 * Hexa conversion test (also should be constant time)
193 static int test_hex_conversion(void)
200 for (i = 0; i < ARRAY_SIZE(hex_test_vectors); i++) {
203 if (hex_test_vectors[i].hex && *hex_test_vectors[i].hex >= '0')
204 printf("[%s]", hex_test_vectors[i].hex);
206 printf("[INV:%i]", i);
207 len = crypt_hex_to_bytes(hex_test_vectors[i].hex, &bytes, 1);
208 if ((hex_test_vectors[i].ok && len != hex_test_vectors[i].bytes_size) ||
209 (!hex_test_vectors[i].ok && len >= 0)) {
210 printf("[FAILED]\n");
211 crypt_safe_free(bytes);
214 crypt_safe_free(bytes);
215 hex = crypt_bytes_to_hex(hex_test_vectors[i].bytes_size, hex_test_vectors[i].bytes);
216 if ((hex_test_vectors[i].ok && strcasecmp(hex, hex_test_vectors[i].hex)) ||
217 (!hex_test_vectors[i].ok && hex)) {
218 printf("[FAILED]\n");
219 crypt_safe_free(hex);
222 crypt_safe_free(hex);
229 static void __attribute__((noreturn)) exit_test(const char *msg, int r)
236 int main(__attribute__ ((unused)) int argc, __attribute__ ((unused))char *argv[])
238 setvbuf(stdout, NULL, _IONBF, 0);
240 #ifndef NO_CRYPTSETUP_PATH
241 if (getenv("CRYPTSETUP_PATH")) {
242 printf("Cannot run this test with CRYPTSETUP_PATH set.\n");
246 if (test_parse_mode())
247 exit_test("Parse mode test failed.", EXIT_FAILURE);
249 if (test_parse_integrity_mode())
250 exit_test("Parse integrity mode test failed.", EXIT_FAILURE);
252 if (test_cipher_null())
253 exit_test("CIPHER null test failed.", EXIT_FAILURE);
255 if (test_hex_conversion())
256 exit_test("HEX conversion test failed.", EXIT_FAILURE);
258 exit_test(NULL, EXIT_SUCCESS);