1 /* 2 * QEMU Crypto cipher algorithms 3 * 4 * Copyright (c) 2015 Red Hat, Inc. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library 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 GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 #include "qemu/osdep.h" 22 23 #include "crypto/init.h" 24 #include "crypto/cipher.h" 25 #include "qapi/error.h" 26 27 typedef struct QCryptoCipherTestData QCryptoCipherTestData; 28 struct QCryptoCipherTestData { 29 const char *path; 30 QCryptoCipherAlgorithm alg; 31 QCryptoCipherMode mode; 32 const char *key; 33 const char *plaintext; 34 const char *ciphertext; 35 const char *iv; 36 }; 37 38 /* AES test data comes from appendix F of: 39 * 40 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf 41 */ 42 static QCryptoCipherTestData test_data[] = { 43 { 44 /* NIST F.1.1 ECB-AES128.Encrypt */ 45 .path = "/crypto/cipher/aes-ecb-128", 46 .alg = QCRYPTO_CIPHER_ALG_AES_128, 47 .mode = QCRYPTO_CIPHER_MODE_ECB, 48 .key = "2b7e151628aed2a6abf7158809cf4f3c", 49 .plaintext = 50 "6bc1bee22e409f96e93d7e117393172a" 51 "ae2d8a571e03ac9c9eb76fac45af8e51" 52 "30c81c46a35ce411e5fbc1191a0a52ef" 53 "f69f2445df4f9b17ad2b417be66c3710", 54 .ciphertext = 55 "3ad77bb40d7a3660a89ecaf32466ef97" 56 "f5d3d58503b9699de785895a96fdbaaf" 57 "43b1cd7f598ece23881b00e3ed030688" 58 "7b0c785e27e8ad3f8223207104725dd4" 59 }, 60 { 61 /* NIST F.1.3 ECB-AES192.Encrypt */ 62 .path = "/crypto/cipher/aes-ecb-192", 63 .alg = QCRYPTO_CIPHER_ALG_AES_192, 64 .mode = QCRYPTO_CIPHER_MODE_ECB, 65 .key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", 66 .plaintext = 67 "6bc1bee22e409f96e93d7e117393172a" 68 "ae2d8a571e03ac9c9eb76fac45af8e51" 69 "30c81c46a35ce411e5fbc1191a0a52ef" 70 "f69f2445df4f9b17ad2b417be66c3710", 71 .ciphertext = 72 "bd334f1d6e45f25ff712a214571fa5cc" 73 "974104846d0ad3ad7734ecb3ecee4eef" 74 "ef7afd2270e2e60adce0ba2face6444e" 75 "9a4b41ba738d6c72fb16691603c18e0e" 76 }, 77 { 78 /* NIST F.1.5 ECB-AES256.Encrypt */ 79 .path = "/crypto/cipher/aes-ecb-256", 80 .alg = QCRYPTO_CIPHER_ALG_AES_256, 81 .mode = QCRYPTO_CIPHER_MODE_ECB, 82 .key = 83 "603deb1015ca71be2b73aef0857d7781" 84 "1f352c073b6108d72d9810a30914dff4", 85 .plaintext = 86 "6bc1bee22e409f96e93d7e117393172a" 87 "ae2d8a571e03ac9c9eb76fac45af8e51" 88 "30c81c46a35ce411e5fbc1191a0a52ef" 89 "f69f2445df4f9b17ad2b417be66c3710", 90 .ciphertext = 91 "f3eed1bdb5d2a03c064b5a7e3db181f8" 92 "591ccb10d410ed26dc5ba74a31362870" 93 "b6ed21b99ca6f4f9f153e7b1beafed1d" 94 "23304b7a39f9f3ff067d8d8f9e24ecc7", 95 }, 96 { 97 /* NIST F.2.1 CBC-AES128.Encrypt */ 98 .path = "/crypto/cipher/aes-cbc-128", 99 .alg = QCRYPTO_CIPHER_ALG_AES_128, 100 .mode = QCRYPTO_CIPHER_MODE_CBC, 101 .key = "2b7e151628aed2a6abf7158809cf4f3c", 102 .iv = "000102030405060708090a0b0c0d0e0f", 103 .plaintext = 104 "6bc1bee22e409f96e93d7e117393172a" 105 "ae2d8a571e03ac9c9eb76fac45af8e51" 106 "30c81c46a35ce411e5fbc1191a0a52ef" 107 "f69f2445df4f9b17ad2b417be66c3710", 108 .ciphertext = 109 "7649abac8119b246cee98e9b12e9197d" 110 "5086cb9b507219ee95db113a917678b2" 111 "73bed6b8e3c1743b7116e69e22229516" 112 "3ff1caa1681fac09120eca307586e1a7", 113 }, 114 { 115 /* NIST F.2.3 CBC-AES128.Encrypt */ 116 .path = "/crypto/cipher/aes-cbc-192", 117 .alg = QCRYPTO_CIPHER_ALG_AES_192, 118 .mode = QCRYPTO_CIPHER_MODE_CBC, 119 .key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", 120 .iv = "000102030405060708090a0b0c0d0e0f", 121 .plaintext = 122 "6bc1bee22e409f96e93d7e117393172a" 123 "ae2d8a571e03ac9c9eb76fac45af8e51" 124 "30c81c46a35ce411e5fbc1191a0a52ef" 125 "f69f2445df4f9b17ad2b417be66c3710", 126 .ciphertext = 127 "4f021db243bc633d7178183a9fa071e8" 128 "b4d9ada9ad7dedf4e5e738763f69145a" 129 "571b242012fb7ae07fa9baac3df102e0" 130 "08b0e27988598881d920a9e64f5615cd", 131 }, 132 { 133 /* NIST F.2.5 CBC-AES128.Encrypt */ 134 .path = "/crypto/cipher/aes-cbc-256", 135 .alg = QCRYPTO_CIPHER_ALG_AES_256, 136 .mode = QCRYPTO_CIPHER_MODE_CBC, 137 .key = 138 "603deb1015ca71be2b73aef0857d7781" 139 "1f352c073b6108d72d9810a30914dff4", 140 .iv = "000102030405060708090a0b0c0d0e0f", 141 .plaintext = 142 "6bc1bee22e409f96e93d7e117393172a" 143 "ae2d8a571e03ac9c9eb76fac45af8e51" 144 "30c81c46a35ce411e5fbc1191a0a52ef" 145 "f69f2445df4f9b17ad2b417be66c3710", 146 .ciphertext = 147 "f58c4c04d6e5f1ba779eabfb5f7bfbd6" 148 "9cfc4e967edb808d679f777bc6702c7d" 149 "39f23369a9d9bacfa530e26304231461" 150 "b2eb05e2c39be9fcda6c19078c6a9d1b", 151 }, 152 { 153 /* 154 * Testing 'password' as plaintext fits 155 * in single AES block, and gives identical 156 * ciphertext in ECB and CBC modes 157 */ 158 .path = "/crypto/cipher/des-ecb-56-one-block", 159 .alg = QCRYPTO_CIPHER_ALG_DES, 160 .mode = QCRYPTO_CIPHER_MODE_ECB, 161 .key = "80c4a2e691d5b3f7", 162 .plaintext = "70617373776f7264", 163 .ciphertext = "73fa80b66134e403", 164 }, 165 { 166 /* See previous comment */ 167 .path = "/crypto/cipher/des-cbc-56-one-block", 168 .alg = QCRYPTO_CIPHER_ALG_DES, 169 .mode = QCRYPTO_CIPHER_MODE_CBC, 170 .key = "80c4a2e691d5b3f7", 171 .iv = "0000000000000000", 172 .plaintext = "70617373776f7264", 173 .ciphertext = "73fa80b66134e403", 174 }, 175 { 176 .path = "/crypto/cipher/des-ecb-56", 177 .alg = QCRYPTO_CIPHER_ALG_DES, 178 .mode = QCRYPTO_CIPHER_MODE_ECB, 179 .key = "80c4a2e691d5b3f7", 180 .plaintext = 181 "6bc1bee22e409f96e93d7e117393172a" 182 "ae2d8a571e03ac9c9eb76fac45af8e51" 183 "30c81c46a35ce411e5fbc1191a0a52ef" 184 "f69f2445df4f9b17ad2b417be66c3710", 185 .ciphertext = 186 "8f346aaf64eaf24040720d80648c52e7" 187 "aefc616be53ab1a3d301e69d91e01838" 188 "ffd29f1bb5596ad94ea2d8e6196b7f09" 189 "30d8ed0bf2773af36dd82a6280c20926", 190 }, 191 { 192 /* Borrowed from linux-kernel crypto/testmgr.h */ 193 .path = "/crypto/cipher/3des-cbc", 194 .alg = QCRYPTO_CIPHER_ALG_3DES, 195 .mode = QCRYPTO_CIPHER_MODE_CBC, 196 .key = 197 "e9c0ff2e760b6424444d995a12d640c0" 198 "eac284e81495dbe8", 199 .iv = 200 "7d3388930f93b242", 201 .plaintext = 202 "6f54206f614d796e5320636565727374" 203 "54206f6f4d206e612079655372637465" 204 "20736f54206f614d796e532063656572" 205 "737454206f6f4d206e61207965537263" 206 "746520736f54206f614d796e53206365" 207 "6572737454206f6f4d206e6120796553" 208 "7263746520736f54206f614d796e5320" 209 "63656572737454206f6f4d206e610a79", 210 .ciphertext = 211 "0e2db6973c5633f4671721c76e8ad549" 212 "74b34905c51cd0ed12565c5396b6007d" 213 "9048fcf58d2939cc8ad5351836234ed7" 214 "76d1da0c9467bb048bf2036ca8cfb6ea" 215 "226447aa8f7513bf9fc2c3f0c956c57a" 216 "71632e897b1e12cae25fafd8a4f8c97a" 217 "d6f92131624445a6d6bc5ad32d5443cc" 218 "9ddea570e942458a6bfab19113b0d919", 219 }, 220 { 221 /* Borrowed from linux-kernel crypto/testmgr.h */ 222 .path = "/crypto/cipher/3des-ecb", 223 .alg = QCRYPTO_CIPHER_ALG_3DES, 224 .mode = QCRYPTO_CIPHER_MODE_ECB, 225 .key = 226 "0123456789abcdef5555555555555555" 227 "fedcba9876543210", 228 .plaintext = 229 "736f6d6564617461", 230 .ciphertext = 231 "18d748e563620572", 232 }, 233 { 234 /* Borrowed from linux-kernel crypto/testmgr.h */ 235 .path = "/crypto/cipher/3des-ctr", 236 .alg = QCRYPTO_CIPHER_ALG_3DES, 237 .mode = QCRYPTO_CIPHER_MODE_CTR, 238 .key = 239 "9cd6f39cb95a67005a67002dceeb2dce" 240 "ebb45172b451721f", 241 .iv = 242 "ffffffffffffffff", 243 .plaintext = 244 "05ec77fb42d559208b128669f05bcf56" 245 "39ad349f66ea7dc448d3ba0db118e34a" 246 "fe41285c278e11856cf75ec2553ca00b" 247 "9265e970db4fd6b900b41fe649fd442f" 248 "533a8d149863ca5dc1a833a70e9178ec" 249 "77de42d5bc078b12e54cf05b22563980" 250 "6b9f66c950c4af36ba0d947fe34add41" 251 "28b31a8e11f843f75e21553c876e9265" 252 "cc57dba235b900eb72e649d0442fb619" 253 "8d14ff46ca5d24a8339a6d9178c377de" 254 "a108bc07ee71e54cd75b22b51c806bf2" 255 "45c9503baf369960947fc64adda40fb3" 256 "1aed74f8432a5e218813876ef158cc57" 257 "3ea2359c67eb72c549d0bb02b619e04b" 258 "ff46295d248f169a6df45fc3aa3da108" 259 "937aee71d84cd7be01b51ce74ef2452c" 260 "503b82159960cb52c6a930a40f9679ed" 261 "74df432abd048813fa4df15823573e81" 262 "689c67ce51c5ac37bb02957ce04bd246" 263 "29b01b8f16f940f45f26aa3d846f937a" 264 "cd54d8a30abe01e873e74ed1452cb71e" 265 "8215fc47cb5225a9309b629679c074df" 266 "a609bd04ef76fa4dd458238a1d8168f3" 267 "5ace5138ac379e61957cc74bd2a50cb0" 268 "1be275f9402b5f268910846ff659cd54" 269 "3fa30a9d64e873da4ed1b803b71ee148" 270 "fc472e52258c179b62f55cc0ab32a609" 271 "907bef76d94dd4bf068a1de44ff35a2d" 272 "5138836a9e61c853c7ae31a50c977ee2" 273 "75dc402bb2058910fb42f65920543f86" 274 "699d64cf56daad34b803ea7de148d347", 275 .ciphertext = 276 "07c20820721f49ef19cd6f3253052215" 277 "a2852bdb85d2d8b9dd0d1b45cb6911d4" 278 "eabeb2455d0caebea0c127ac659f537e" 279 "afc21bb5b86d360c25c0f86d0b2901da" 280 "1378dc89121243faf612ef8d87627883" 281 "e2be41204c6d351bd10c30cfe2de2b03" 282 "bf4573d4e55995d1b39b276297bdde7f" 283 "a4d23980aa5023f074883da86a18793b" 284 "c4966c8d2240926ed6ad2a1fde63c0e7" 285 "07f72df7b5f3f0cc017c2a9bc210caaa" 286 "fd2b3fc5f3f6fc9b45db53e45bf3c97b" 287 "8e52ffc802b8ac9da10039da3d2d0e01" 288 "097d8d5ebe53b9b08ee7e2966ab278ea" 289 "de238ba5fa5ce3dabf8e316a55d16ab2" 290 "b5466fa5f0eeba1f9f98b0664fd03fa9" 291 "df5f58c4f4ff755c403a097e6e1c97d4" 292 "cce7e771cf0b150871fa0797cde6ca1d" 293 "14280ccf99137af1ebfafa9207de1da1" 294 "d33669fe514d9f2e83374f1f4830ed04" 295 "4da4ef3aca76f41c418f6337782f86a6" 296 "ef417ed2af88ab675271c38ef8269372" 297 "aad60ee70b46b13ab408a9a8a0cf200c" 298 "52bc8b0556b2bc319b74b92929969a50" 299 "dc45dc1aeb0c64d4d3057e5955c3f490" 300 "c2abf89b8adacea1c3f4ad77dd44c8ac" 301 "a3f1c9d2195cb0caa234c1f76cfdac65" 302 "32dc48c4f2006b77f17d76acc031632a" 303 "a53a62c891b10365cb43d106dfc367bc" 304 "dce0cd35ce4965a0527ba70d07a91bb0" 305 "407772c2ea0e3a7846b991b6e73d5142" 306 "fd51b0c62c6313785ceefccfc4700034", 307 }, 308 { 309 /* RFC 2144, Appendix B.1 */ 310 .path = "/crypto/cipher/cast5-128", 311 .alg = QCRYPTO_CIPHER_ALG_CAST5_128, 312 .mode = QCRYPTO_CIPHER_MODE_ECB, 313 .key = "0123456712345678234567893456789A", 314 .plaintext = "0123456789abcdef", 315 .ciphertext = "238b4fe5847e44b2", 316 }, 317 { 318 /* libgcrypt serpent.c */ 319 .path = "/crypto/cipher/serpent-128", 320 .alg = QCRYPTO_CIPHER_ALG_SERPENT_128, 321 .mode = QCRYPTO_CIPHER_MODE_ECB, 322 .key = "00000000000000000000000000000000", 323 .plaintext = "d29d576fcea3a3a7ed9099f29273d78e", 324 .ciphertext = "b2288b968ae8b08648d1ce9606fd992d", 325 }, 326 { 327 /* libgcrypt serpent.c */ 328 .path = "/crypto/cipher/serpent-192", 329 .alg = QCRYPTO_CIPHER_ALG_SERPENT_192, 330 .mode = QCRYPTO_CIPHER_MODE_ECB, 331 .key = "00000000000000000000000000000000" 332 "0000000000000000", 333 .plaintext = "d29d576fceaba3a7ed9899f2927bd78e", 334 .ciphertext = "130e353e1037c22405e8faefb2c3c3e9", 335 }, 336 { 337 /* libgcrypt serpent.c */ 338 .path = "/crypto/cipher/serpent-256a", 339 .alg = QCRYPTO_CIPHER_ALG_SERPENT_256, 340 .mode = QCRYPTO_CIPHER_MODE_ECB, 341 .key = "00000000000000000000000000000000" 342 "00000000000000000000000000000000", 343 .plaintext = "d095576fcea3e3a7ed98d9f29073d78e", 344 .ciphertext = "b90ee5862de69168f2bdd5125b45472b", 345 }, 346 { 347 /* libgcrypt serpent.c */ 348 .path = "/crypto/cipher/serpent-256b", 349 .alg = QCRYPTO_CIPHER_ALG_SERPENT_256, 350 .mode = QCRYPTO_CIPHER_MODE_ECB, 351 .key = "00000000000000000000000000000000" 352 "00000000000000000000000000000000", 353 .plaintext = "00000000010000000200000003000000", 354 .ciphertext = "2061a42782bd52ec691ec383b03ba77c", 355 }, 356 { 357 /* Twofish paper "Known Answer Test" */ 358 .path = "/crypto/cipher/twofish-128", 359 .alg = QCRYPTO_CIPHER_ALG_TWOFISH_128, 360 .mode = QCRYPTO_CIPHER_MODE_ECB, 361 .key = "d491db16e7b1c39e86cb086b789f5419", 362 .plaintext = "019f9809de1711858faac3a3ba20fbc3", 363 .ciphertext = "6363977de839486297e661c6c9d668eb", 364 }, 365 { 366 /* Twofish paper "Known Answer Test", I=3 */ 367 .path = "/crypto/cipher/twofish-192", 368 .alg = QCRYPTO_CIPHER_ALG_TWOFISH_192, 369 .mode = QCRYPTO_CIPHER_MODE_ECB, 370 .key = "88b2b2706b105e36b446bb6d731a1e88" 371 "efa71f788965bd44", 372 .plaintext = "39da69d6ba4997d585b6dc073ca341b2", 373 .ciphertext = "182b02d81497ea45f9daacdc29193a65", 374 }, 375 { 376 /* Twofish paper "Known Answer Test", I=4 */ 377 .path = "/crypto/cipher/twofish-256", 378 .alg = QCRYPTO_CIPHER_ALG_TWOFISH_256, 379 .mode = QCRYPTO_CIPHER_MODE_ECB, 380 .key = "d43bb7556ea32e46f2a282b7d45b4e0d" 381 "57ff739d4dc92c1bd7fc01700cc8216f", 382 .plaintext = "90afe91bb288544f2c32dc239b2635e6", 383 .ciphertext = "6cb4561c40bf0a9705931cb6d408e7fa", 384 }, 385 #ifdef CONFIG_CRYPTO_SM4 386 { 387 /* SM4, GB/T 32907-2016, Appendix A.1 */ 388 .path = "/crypto/cipher/sm4", 389 .alg = QCRYPTO_CIPHER_ALG_SM4, 390 .mode = QCRYPTO_CIPHER_MODE_ECB, 391 .key = "0123456789abcdeffedcba9876543210", 392 .plaintext = 393 "0123456789abcdeffedcba9876543210", 394 .ciphertext = 395 "681edf34d206965e86b3e94f536e4246", 396 }, 397 #endif 398 { 399 /* #1 32 byte key, 32 byte PTX */ 400 .path = "/crypto/cipher/aes-xts-128-1", 401 .alg = QCRYPTO_CIPHER_ALG_AES_128, 402 .mode = QCRYPTO_CIPHER_MODE_XTS, 403 .key = 404 "00000000000000000000000000000000" 405 "00000000000000000000000000000000", 406 .iv = 407 "00000000000000000000000000000000", 408 .plaintext = 409 "00000000000000000000000000000000" 410 "00000000000000000000000000000000", 411 .ciphertext = 412 "917cf69ebd68b2ec9b9fe9a3eadda692" 413 "cd43d2f59598ed858c02c2652fbf922e", 414 }, 415 { 416 /* #2, 32 byte key, 32 byte PTX */ 417 .path = "/crypto/cipher/aes-xts-128-2", 418 .alg = QCRYPTO_CIPHER_ALG_AES_128, 419 .mode = QCRYPTO_CIPHER_MODE_XTS, 420 .key = 421 "11111111111111111111111111111111" 422 "22222222222222222222222222222222", 423 .iv = 424 "33333333330000000000000000000000", 425 .plaintext = 426 "44444444444444444444444444444444" 427 "44444444444444444444444444444444", 428 .ciphertext = 429 "c454185e6a16936e39334038acef838b" 430 "fb186fff7480adc4289382ecd6d394f0", 431 }, 432 { 433 /* #5 from xts.7, 32 byte key, 32 byte PTX */ 434 .path = "/crypto/cipher/aes-xts-128-3", 435 .alg = QCRYPTO_CIPHER_ALG_AES_128, 436 .mode = QCRYPTO_CIPHER_MODE_XTS, 437 .key = 438 "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0" 439 "bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0", 440 .iv = 441 "9a785634120000000000000000000000", 442 .plaintext = 443 "44444444444444444444444444444444" 444 "44444444444444444444444444444444", 445 .ciphertext = 446 "b01f86f8edc1863706fa8a4253e34f28" 447 "af319de38334870f4dd1f94cbe9832f1", 448 }, 449 { 450 /* #4, 32 byte key, 512 byte PTX */ 451 .path = "/crypto/cipher/aes-xts-128-4", 452 .alg = QCRYPTO_CIPHER_ALG_AES_128, 453 .mode = QCRYPTO_CIPHER_MODE_XTS, 454 .key = 455 "27182818284590452353602874713526" 456 "31415926535897932384626433832795", 457 .iv = 458 "00000000000000000000000000000000", 459 .plaintext = 460 "000102030405060708090a0b0c0d0e0f" 461 "101112131415161718191a1b1c1d1e1f" 462 "202122232425262728292a2b2c2d2e2f" 463 "303132333435363738393a3b3c3d3e3f" 464 "404142434445464748494a4b4c4d4e4f" 465 "505152535455565758595a5b5c5d5e5f" 466 "606162636465666768696a6b6c6d6e6f" 467 "707172737475767778797a7b7c7d7e7f" 468 "808182838485868788898a8b8c8d8e8f" 469 "909192939495969798999a9b9c9d9e9f" 470 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" 471 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" 472 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" 473 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" 474 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" 475 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" 476 "000102030405060708090a0b0c0d0e0f" 477 "101112131415161718191a1b1c1d1e1f" 478 "202122232425262728292a2b2c2d2e2f" 479 "303132333435363738393a3b3c3d3e3f" 480 "404142434445464748494a4b4c4d4e4f" 481 "505152535455565758595a5b5c5d5e5f" 482 "606162636465666768696a6b6c6d6e6f" 483 "707172737475767778797a7b7c7d7e7f" 484 "808182838485868788898a8b8c8d8e8f" 485 "909192939495969798999a9b9c9d9e9f" 486 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" 487 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" 488 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" 489 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" 490 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" 491 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", 492 .ciphertext = 493 "27a7479befa1d476489f308cd4cfa6e2" 494 "a96e4bbe3208ff25287dd3819616e89c" 495 "c78cf7f5e543445f8333d8fa7f560000" 496 "05279fa5d8b5e4ad40e736ddb4d35412" 497 "328063fd2aab53e5ea1e0a9f332500a5" 498 "df9487d07a5c92cc512c8866c7e860ce" 499 "93fdf166a24912b422976146ae20ce84" 500 "6bb7dc9ba94a767aaef20c0d61ad0265" 501 "5ea92dc4c4e41a8952c651d33174be51" 502 "a10c421110e6d81588ede82103a252d8" 503 "a750e8768defffed9122810aaeb99f91" 504 "72af82b604dc4b8e51bcb08235a6f434" 505 "1332e4ca60482a4ba1a03b3e65008fc5" 506 "da76b70bf1690db4eae29c5f1badd03c" 507 "5ccf2a55d705ddcd86d449511ceb7ec3" 508 "0bf12b1fa35b913f9f747a8afd1b130e" 509 "94bff94effd01a91735ca1726acd0b19" 510 "7c4e5b03393697e126826fb6bbde8ecc" 511 "1e08298516e2c9ed03ff3c1b7860f6de" 512 "76d4cecd94c8119855ef5297ca67e9f3" 513 "e7ff72b1e99785ca0a7e7720c5b36dc6" 514 "d72cac9574c8cbbc2f801e23e56fd344" 515 "b07f22154beba0f08ce8891e643ed995" 516 "c94d9a69c9f1b5f499027a78572aeebd" 517 "74d20cc39881c213ee770b1010e4bea7" 518 "18846977ae119f7a023ab58cca0ad752" 519 "afe656bb3c17256a9f6e9bf19fdd5a38" 520 "fc82bbe872c5539edb609ef4f79c203e" 521 "bb140f2e583cb2ad15b4aa5b655016a8" 522 "449277dbd477ef2c8d6c017db738b18d" 523 "eb4a427d1923ce3ff262735779a418f2" 524 "0a282df920147beabe421ee5319d0568", 525 }, 526 { 527 /* Bad config - cast5-128 has 8 byte block size 528 * which is incompatible with XTS 529 */ 530 .path = "/crypto/cipher/cast5-xts-128", 531 .alg = QCRYPTO_CIPHER_ALG_CAST5_128, 532 .mode = QCRYPTO_CIPHER_MODE_XTS, 533 .key = 534 "27182818284590452353602874713526" 535 "31415926535897932384626433832795", 536 }, 537 { 538 /* NIST F.5.1 CTR-AES128.Encrypt */ 539 .path = "/crypto/cipher/aes-ctr-128", 540 .alg = QCRYPTO_CIPHER_ALG_AES_128, 541 .mode = QCRYPTO_CIPHER_MODE_CTR, 542 .key = "2b7e151628aed2a6abf7158809cf4f3c", 543 .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", 544 .plaintext = 545 "6bc1bee22e409f96e93d7e117393172a" 546 "ae2d8a571e03ac9c9eb76fac45af8e51" 547 "30c81c46a35ce411e5fbc1191a0a52ef" 548 "f69f2445df4f9b17ad2b417be66c3710", 549 .ciphertext = 550 "874d6191b620e3261bef6864990db6ce" 551 "9806f66b7970fdff8617187bb9fffdff" 552 "5ae4df3edbd5d35e5b4f09020db03eab" 553 "1e031dda2fbe03d1792170a0f3009cee", 554 }, 555 { 556 /* NIST F.5.3 CTR-AES192.Encrypt */ 557 .path = "/crypto/cipher/aes-ctr-192", 558 .alg = QCRYPTO_CIPHER_ALG_AES_192, 559 .mode = QCRYPTO_CIPHER_MODE_CTR, 560 .key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", 561 .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", 562 .plaintext = 563 "6bc1bee22e409f96e93d7e117393172a" 564 "ae2d8a571e03ac9c9eb76fac45af8e51" 565 "30c81c46a35ce411e5fbc1191a0a52ef" 566 "f69f2445df4f9b17ad2b417be66c3710", 567 .ciphertext = 568 "1abc932417521ca24f2b0459fe7e6e0b" 569 "090339ec0aa6faefd5ccc2c6f4ce8e94" 570 "1e36b26bd1ebc670d1bd1d665620abf7" 571 "4f78a7f6d29809585a97daec58c6b050", 572 }, 573 { 574 /* NIST F.5.5 CTR-AES256.Encrypt */ 575 .path = "/crypto/cipher/aes-ctr-256", 576 .alg = QCRYPTO_CIPHER_ALG_AES_256, 577 .mode = QCRYPTO_CIPHER_MODE_CTR, 578 .key = "603deb1015ca71be2b73aef0857d7781" 579 "1f352c073b6108d72d9810a30914dff4", 580 .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", 581 .plaintext = 582 "6bc1bee22e409f96e93d7e117393172a" 583 "ae2d8a571e03ac9c9eb76fac45af8e51" 584 "30c81c46a35ce411e5fbc1191a0a52ef" 585 "f69f2445df4f9b17ad2b417be66c3710", 586 .ciphertext = 587 "601ec313775789a5b7a7f504bbf3d228" 588 "f443e3ca4d62b59aca84e990cacaf5c5" 589 "2b0930daa23de94ce87017ba2d84988d" 590 "dfc9c58db67aada613c2dd08457941a6", 591 } 592 }; 593 594 595 static inline int unhex(char c) 596 { 597 if (c >= 'a' && c <= 'f') { 598 return 10 + (c - 'a'); 599 } 600 if (c >= 'A' && c <= 'F') { 601 return 10 + (c - 'A'); 602 } 603 return c - '0'; 604 } 605 606 static inline char hex(int i) 607 { 608 if (i < 10) { 609 return '0' + i; 610 } 611 return 'a' + (i - 10); 612 } 613 614 static size_t unhex_string(const char *hexstr, 615 uint8_t **data) 616 { 617 size_t len; 618 size_t i; 619 620 if (!hexstr) { 621 *data = NULL; 622 return 0; 623 } 624 625 len = strlen(hexstr); 626 *data = g_new0(uint8_t, len / 2); 627 628 for (i = 0; i < len; i += 2) { 629 (*data)[i/2] = (unhex(hexstr[i]) << 4) | unhex(hexstr[i+1]); 630 } 631 return len / 2; 632 } 633 634 static char *hex_string(const uint8_t *bytes, 635 size_t len) 636 { 637 char *hexstr = g_new0(char, len * 2 + 1); 638 size_t i; 639 640 for (i = 0; i < len; i++) { 641 hexstr[i*2] = hex((bytes[i] >> 4) & 0xf); 642 hexstr[i*2+1] = hex(bytes[i] & 0xf); 643 } 644 hexstr[len*2] = '\0'; 645 646 return hexstr; 647 } 648 649 static void test_cipher(const void *opaque) 650 { 651 const QCryptoCipherTestData *data = opaque; 652 653 QCryptoCipher *cipher; 654 uint8_t *key, *iv = NULL, *ciphertext = NULL, 655 *plaintext = NULL, *outtext = NULL; 656 size_t nkey, niv = 0, nciphertext = 0, nplaintext = 0; 657 char *outtexthex = NULL; 658 size_t ivsize, keysize, blocksize; 659 Error *err = NULL; 660 661 nkey = unhex_string(data->key, &key); 662 if (data->iv) { 663 niv = unhex_string(data->iv, &iv); 664 } 665 if (data->ciphertext) { 666 nciphertext = unhex_string(data->ciphertext, &ciphertext); 667 } 668 if (data->plaintext) { 669 nplaintext = unhex_string(data->plaintext, &plaintext); 670 } 671 672 g_assert(nciphertext == nplaintext); 673 674 outtext = g_new0(uint8_t, nciphertext); 675 676 cipher = qcrypto_cipher_new( 677 data->alg, data->mode, 678 key, nkey, 679 data->plaintext ? &error_abort : &err); 680 if (data->plaintext) { 681 g_assert(cipher != NULL); 682 } else { 683 error_free_or_abort(&err); 684 g_assert(cipher == NULL); 685 goto cleanup; 686 } 687 688 keysize = qcrypto_cipher_get_key_len(data->alg); 689 blocksize = qcrypto_cipher_get_block_len(data->alg); 690 ivsize = qcrypto_cipher_get_iv_len(data->alg, data->mode); 691 692 if (data->mode == QCRYPTO_CIPHER_MODE_XTS) { 693 g_assert_cmpint(keysize * 2, ==, nkey); 694 } else { 695 g_assert_cmpint(keysize, ==, nkey); 696 } 697 g_assert_cmpint(ivsize, ==, niv); 698 if (niv) { 699 g_assert_cmpint(blocksize, ==, niv); 700 } 701 702 if (iv) { 703 g_assert(qcrypto_cipher_setiv(cipher, 704 iv, niv, 705 &error_abort) == 0); 706 } 707 g_assert(qcrypto_cipher_encrypt(cipher, 708 plaintext, 709 outtext, 710 nplaintext, 711 &error_abort) == 0); 712 713 outtexthex = hex_string(outtext, nciphertext); 714 715 g_assert_cmpstr(outtexthex, ==, data->ciphertext); 716 717 g_free(outtexthex); 718 719 if (iv) { 720 g_assert(qcrypto_cipher_setiv(cipher, 721 iv, niv, 722 &error_abort) == 0); 723 } 724 g_assert(qcrypto_cipher_decrypt(cipher, 725 ciphertext, 726 outtext, 727 nplaintext, 728 &error_abort) == 0); 729 730 outtexthex = hex_string(outtext, nplaintext); 731 732 g_assert_cmpstr(outtexthex, ==, data->plaintext); 733 734 cleanup: 735 g_free(outtext); 736 g_free(outtexthex); 737 g_free(key); 738 g_free(iv); 739 g_free(ciphertext); 740 g_free(plaintext); 741 qcrypto_cipher_free(cipher); 742 } 743 744 745 static void test_cipher_null_iv(void) 746 { 747 QCryptoCipher *cipher; 748 uint8_t key[32] = { 0 }; 749 uint8_t plaintext[32] = { 0 }; 750 uint8_t ciphertext[32] = { 0 }; 751 752 cipher = qcrypto_cipher_new( 753 QCRYPTO_CIPHER_ALG_AES_256, 754 QCRYPTO_CIPHER_MODE_CBC, 755 key, sizeof(key), 756 &error_abort); 757 g_assert(cipher != NULL); 758 759 /* Don't call qcrypto_cipher_setiv */ 760 761 qcrypto_cipher_encrypt(cipher, 762 plaintext, 763 ciphertext, 764 sizeof(plaintext), 765 &error_abort); 766 767 qcrypto_cipher_free(cipher); 768 } 769 770 static void test_cipher_short_plaintext(void) 771 { 772 Error *err = NULL; 773 QCryptoCipher *cipher; 774 uint8_t key[32] = { 0 }; 775 uint8_t plaintext1[20] = { 0 }; 776 uint8_t ciphertext1[20] = { 0 }; 777 uint8_t plaintext2[40] = { 0 }; 778 uint8_t ciphertext2[40] = { 0 }; 779 int ret; 780 781 cipher = qcrypto_cipher_new( 782 QCRYPTO_CIPHER_ALG_AES_256, 783 QCRYPTO_CIPHER_MODE_CBC, 784 key, sizeof(key), 785 &error_abort); 786 g_assert(cipher != NULL); 787 788 /* Should report an error as plaintext is shorter 789 * than block size 790 */ 791 ret = qcrypto_cipher_encrypt(cipher, 792 plaintext1, 793 ciphertext1, 794 sizeof(plaintext1), 795 &err); 796 g_assert(ret == -1); 797 error_free_or_abort(&err); 798 799 /* Should report an error as plaintext is larger than 800 * block size, but not a multiple of block size 801 */ 802 ret = qcrypto_cipher_encrypt(cipher, 803 plaintext2, 804 ciphertext2, 805 sizeof(plaintext2), 806 &err); 807 g_assert(ret == -1); 808 error_free_or_abort(&err); 809 810 qcrypto_cipher_free(cipher); 811 } 812 813 int main(int argc, char **argv) 814 { 815 size_t i; 816 817 g_test_init(&argc, &argv, NULL); 818 819 g_assert(qcrypto_init(NULL) == 0); 820 821 for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 822 if (qcrypto_cipher_supports(test_data[i].alg, test_data[i].mode)) { 823 g_test_add_data_func(test_data[i].path, &test_data[i], test_cipher); 824 } else { 825 g_printerr("# skip unsupported %s:%s\n", 826 QCryptoCipherAlgorithm_str(test_data[i].alg), 827 QCryptoCipherMode_str(test_data[i].mode)); 828 } 829 } 830 831 g_test_add_func("/crypto/cipher/null-iv", 832 test_cipher_null_iv); 833 834 g_test_add_func("/crypto/cipher/short-plaintext", 835 test_cipher_short_plaintext); 836 837 return g_test_run(); 838 } 839