qemu/tests/test-crypto-cipher.c
<<
>>
Prefs
   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 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
  27typedef struct QCryptoCipherTestData QCryptoCipherTestData;
  28struct 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 */
  42static 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        .path = "/crypto/cipher/des-rfb-ecb-56",
 154        .alg = QCRYPTO_CIPHER_ALG_DES_RFB,
 155        .mode = QCRYPTO_CIPHER_MODE_ECB,
 156        .key = "0123456789abcdef",
 157        .plaintext =
 158            "6bc1bee22e409f96e93d7e117393172a"
 159            "ae2d8a571e03ac9c9eb76fac45af8e51"
 160            "30c81c46a35ce411e5fbc1191a0a52ef"
 161            "f69f2445df4f9b17ad2b417be66c3710",
 162        .ciphertext =
 163            "8f346aaf64eaf24040720d80648c52e7"
 164            "aefc616be53ab1a3d301e69d91e01838"
 165            "ffd29f1bb5596ad94ea2d8e6196b7f09"
 166            "30d8ed0bf2773af36dd82a6280c20926",
 167    },
 168#if defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT)
 169    {
 170        /* Borrowed from linux-kernel crypto/testmgr.h */
 171        .path = "/crypto/cipher/3des-cbc",
 172        .alg = QCRYPTO_CIPHER_ALG_3DES,
 173        .mode = QCRYPTO_CIPHER_MODE_CBC,
 174        .key =
 175            "e9c0ff2e760b6424444d995a12d640c0"
 176            "eac284e81495dbe8",
 177        .iv =
 178            "7d3388930f93b242",
 179        .plaintext =
 180            "6f54206f614d796e5320636565727374"
 181            "54206f6f4d206e612079655372637465"
 182            "20736f54206f614d796e532063656572"
 183            "737454206f6f4d206e61207965537263"
 184            "746520736f54206f614d796e53206365"
 185            "6572737454206f6f4d206e6120796553"
 186            "7263746520736f54206f614d796e5320"
 187            "63656572737454206f6f4d206e610a79",
 188        .ciphertext =
 189            "0e2db6973c5633f4671721c76e8ad549"
 190            "74b34905c51cd0ed12565c5396b6007d"
 191            "9048fcf58d2939cc8ad5351836234ed7"
 192            "76d1da0c9467bb048bf2036ca8cfb6ea"
 193            "226447aa8f7513bf9fc2c3f0c956c57a"
 194            "71632e897b1e12cae25fafd8a4f8c97a"
 195            "d6f92131624445a6d6bc5ad32d5443cc"
 196            "9ddea570e942458a6bfab19113b0d919",
 197    },
 198    {
 199        /* Borrowed from linux-kernel crypto/testmgr.h */
 200        .path = "/crypto/cipher/3des-ecb",
 201        .alg = QCRYPTO_CIPHER_ALG_3DES,
 202        .mode = QCRYPTO_CIPHER_MODE_ECB,
 203        .key =
 204            "0123456789abcdef5555555555555555"
 205            "fedcba9876543210",
 206        .plaintext =
 207            "736f6d6564617461",
 208        .ciphertext =
 209            "18d748e563620572",
 210    },
 211    {
 212        /* Borrowed from linux-kernel crypto/testmgr.h */
 213        .path = "/crypto/cipher/3des-ctr",
 214        .alg = QCRYPTO_CIPHER_ALG_3DES,
 215        .mode = QCRYPTO_CIPHER_MODE_CTR,
 216        .key =
 217            "9cd6f39cb95a67005a67002dceeb2dce"
 218            "ebb45172b451721f",
 219        .iv =
 220            "ffffffffffffffff",
 221        .plaintext =
 222            "05ec77fb42d559208b128669f05bcf56"
 223            "39ad349f66ea7dc448d3ba0db118e34a"
 224            "fe41285c278e11856cf75ec2553ca00b"
 225            "9265e970db4fd6b900b41fe649fd442f"
 226            "533a8d149863ca5dc1a833a70e9178ec"
 227            "77de42d5bc078b12e54cf05b22563980"
 228            "6b9f66c950c4af36ba0d947fe34add41"
 229            "28b31a8e11f843f75e21553c876e9265"
 230            "cc57dba235b900eb72e649d0442fb619"
 231            "8d14ff46ca5d24a8339a6d9178c377de"
 232            "a108bc07ee71e54cd75b22b51c806bf2"
 233            "45c9503baf369960947fc64adda40fb3"
 234            "1aed74f8432a5e218813876ef158cc57"
 235            "3ea2359c67eb72c549d0bb02b619e04b"
 236            "ff46295d248f169a6df45fc3aa3da108"
 237            "937aee71d84cd7be01b51ce74ef2452c"
 238            "503b82159960cb52c6a930a40f9679ed"
 239            "74df432abd048813fa4df15823573e81"
 240            "689c67ce51c5ac37bb02957ce04bd246"
 241            "29b01b8f16f940f45f26aa3d846f937a"
 242            "cd54d8a30abe01e873e74ed1452cb71e"
 243            "8215fc47cb5225a9309b629679c074df"
 244            "a609bd04ef76fa4dd458238a1d8168f3"
 245            "5ace5138ac379e61957cc74bd2a50cb0"
 246            "1be275f9402b5f268910846ff659cd54"
 247            "3fa30a9d64e873da4ed1b803b71ee148"
 248            "fc472e52258c179b62f55cc0ab32a609"
 249            "907bef76d94dd4bf068a1de44ff35a2d"
 250            "5138836a9e61c853c7ae31a50c977ee2"
 251            "75dc402bb2058910fb42f65920543f86"
 252            "699d64cf56daad34b803ea7de148d347",
 253        .ciphertext =
 254            "07c20820721f49ef19cd6f3253052215"
 255            "a2852bdb85d2d8b9dd0d1b45cb6911d4"
 256            "eabeb2455d0caebea0c127ac659f537e"
 257            "afc21bb5b86d360c25c0f86d0b2901da"
 258            "1378dc89121243faf612ef8d87627883"
 259            "e2be41204c6d351bd10c30cfe2de2b03"
 260            "bf4573d4e55995d1b39b276297bdde7f"
 261            "a4d23980aa5023f074883da86a18793b"
 262            "c4966c8d2240926ed6ad2a1fde63c0e7"
 263            "07f72df7b5f3f0cc017c2a9bc210caaa"
 264            "fd2b3fc5f3f6fc9b45db53e45bf3c97b"
 265            "8e52ffc802b8ac9da10039da3d2d0e01"
 266            "097d8d5ebe53b9b08ee7e2966ab278ea"
 267            "de238ba5fa5ce3dabf8e316a55d16ab2"
 268            "b5466fa5f0eeba1f9f98b0664fd03fa9"
 269            "df5f58c4f4ff755c403a097e6e1c97d4"
 270            "cce7e771cf0b150871fa0797cde6ca1d"
 271            "14280ccf99137af1ebfafa9207de1da1"
 272            "d33669fe514d9f2e83374f1f4830ed04"
 273            "4da4ef3aca76f41c418f6337782f86a6"
 274            "ef417ed2af88ab675271c38ef8269372"
 275            "aad60ee70b46b13ab408a9a8a0cf200c"
 276            "52bc8b0556b2bc319b74b92929969a50"
 277            "dc45dc1aeb0c64d4d3057e5955c3f490"
 278            "c2abf89b8adacea1c3f4ad77dd44c8ac"
 279            "a3f1c9d2195cb0caa234c1f76cfdac65"
 280            "32dc48c4f2006b77f17d76acc031632a"
 281            "a53a62c891b10365cb43d106dfc367bc"
 282            "dce0cd35ce4965a0527ba70d07a91bb0"
 283            "407772c2ea0e3a7846b991b6e73d5142"
 284            "fd51b0c62c6313785ceefccfc4700034",
 285    },
 286#endif
 287    {
 288        /* RFC 2144, Appendix B.1 */
 289        .path = "/crypto/cipher/cast5-128",
 290        .alg = QCRYPTO_CIPHER_ALG_CAST5_128,
 291        .mode = QCRYPTO_CIPHER_MODE_ECB,
 292        .key = "0123456712345678234567893456789A",
 293        .plaintext = "0123456789abcdef",
 294        .ciphertext = "238b4fe5847e44b2",
 295    },
 296    {
 297        /* libgcrypt serpent.c */
 298        .path = "/crypto/cipher/serpent-128",
 299        .alg = QCRYPTO_CIPHER_ALG_SERPENT_128,
 300        .mode = QCRYPTO_CIPHER_MODE_ECB,
 301        .key = "00000000000000000000000000000000",
 302        .plaintext = "d29d576fcea3a3a7ed9099f29273d78e",
 303        .ciphertext = "b2288b968ae8b08648d1ce9606fd992d",
 304    },
 305    {
 306        /* libgcrypt serpent.c */
 307        .path = "/crypto/cipher/serpent-192",
 308        .alg = QCRYPTO_CIPHER_ALG_SERPENT_192,
 309        .mode = QCRYPTO_CIPHER_MODE_ECB,
 310        .key = "00000000000000000000000000000000"
 311               "0000000000000000",
 312        .plaintext = "d29d576fceaba3a7ed9899f2927bd78e",
 313        .ciphertext = "130e353e1037c22405e8faefb2c3c3e9",
 314    },
 315    {
 316        /* libgcrypt serpent.c */
 317        .path = "/crypto/cipher/serpent-256a",
 318        .alg = QCRYPTO_CIPHER_ALG_SERPENT_256,
 319        .mode = QCRYPTO_CIPHER_MODE_ECB,
 320        .key = "00000000000000000000000000000000"
 321               "00000000000000000000000000000000",
 322        .plaintext = "d095576fcea3e3a7ed98d9f29073d78e",
 323        .ciphertext = "b90ee5862de69168f2bdd5125b45472b",
 324    },
 325    {
 326        /* libgcrypt serpent.c */
 327        .path = "/crypto/cipher/serpent-256b",
 328        .alg = QCRYPTO_CIPHER_ALG_SERPENT_256,
 329        .mode = QCRYPTO_CIPHER_MODE_ECB,
 330        .key = "00000000000000000000000000000000"
 331               "00000000000000000000000000000000",
 332        .plaintext = "00000000010000000200000003000000",
 333        .ciphertext = "2061a42782bd52ec691ec383b03ba77c",
 334    },
 335    {
 336        /* Twofish paper "Known Answer Test" */
 337        .path = "/crypto/cipher/twofish-128",
 338        .alg = QCRYPTO_CIPHER_ALG_TWOFISH_128,
 339        .mode = QCRYPTO_CIPHER_MODE_ECB,
 340        .key = "d491db16e7b1c39e86cb086b789f5419",
 341        .plaintext = "019f9809de1711858faac3a3ba20fbc3",
 342        .ciphertext = "6363977de839486297e661c6c9d668eb",
 343    },
 344    {
 345        /* Twofish paper "Known Answer Test", I=3 */
 346        .path = "/crypto/cipher/twofish-192",
 347        .alg = QCRYPTO_CIPHER_ALG_TWOFISH_192,
 348        .mode = QCRYPTO_CIPHER_MODE_ECB,
 349        .key = "88b2b2706b105e36b446bb6d731a1e88"
 350               "efa71f788965bd44",
 351        .plaintext = "39da69d6ba4997d585b6dc073ca341b2",
 352        .ciphertext = "182b02d81497ea45f9daacdc29193a65",
 353    },
 354    {
 355        /* Twofish paper "Known Answer Test", I=4 */
 356        .path = "/crypto/cipher/twofish-256",
 357        .alg = QCRYPTO_CIPHER_ALG_TWOFISH_256,
 358        .mode = QCRYPTO_CIPHER_MODE_ECB,
 359        .key = "d43bb7556ea32e46f2a282b7d45b4e0d"
 360               "57ff739d4dc92c1bd7fc01700cc8216f",
 361        .plaintext = "90afe91bb288544f2c32dc239b2635e6",
 362        .ciphertext = "6cb4561c40bf0a9705931cb6d408e7fa",
 363    },
 364    {
 365        /* #1 32 byte key, 32 byte PTX */
 366        .path = "/crypto/cipher/aes-xts-128-1",
 367        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 368        .mode = QCRYPTO_CIPHER_MODE_XTS,
 369        .key =
 370            "00000000000000000000000000000000"
 371            "00000000000000000000000000000000",
 372        .iv =
 373            "00000000000000000000000000000000",
 374        .plaintext =
 375            "00000000000000000000000000000000"
 376            "00000000000000000000000000000000",
 377        .ciphertext =
 378            "917cf69ebd68b2ec9b9fe9a3eadda692"
 379            "cd43d2f59598ed858c02c2652fbf922e",
 380    },
 381    {
 382        /* #2, 32 byte key, 32 byte PTX */
 383        .path = "/crypto/cipher/aes-xts-128-2",
 384        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 385        .mode = QCRYPTO_CIPHER_MODE_XTS,
 386        .key =
 387            "11111111111111111111111111111111"
 388            "22222222222222222222222222222222",
 389        .iv =
 390            "33333333330000000000000000000000",
 391        .plaintext =
 392            "44444444444444444444444444444444"
 393            "44444444444444444444444444444444",
 394        .ciphertext =
 395            "c454185e6a16936e39334038acef838b"
 396            "fb186fff7480adc4289382ecd6d394f0",
 397    },
 398    {
 399        /* #5 from xts.7, 32 byte key, 32 byte PTX */
 400        .path = "/crypto/cipher/aes-xts-128-3",
 401        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 402        .mode = QCRYPTO_CIPHER_MODE_XTS,
 403        .key =
 404            "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0"
 405            "bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0",
 406        .iv =
 407            "9a785634120000000000000000000000",
 408        .plaintext =
 409            "44444444444444444444444444444444"
 410            "44444444444444444444444444444444",
 411        .ciphertext =
 412            "b01f86f8edc1863706fa8a4253e34f28"
 413            "af319de38334870f4dd1f94cbe9832f1",
 414    },
 415    {
 416        /* #4, 32 byte key, 512 byte PTX  */
 417        .path = "/crypto/cipher/aes-xts-128-4",
 418        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 419        .mode = QCRYPTO_CIPHER_MODE_XTS,
 420        .key =
 421            "27182818284590452353602874713526"
 422            "31415926535897932384626433832795",
 423        .iv =
 424            "00000000000000000000000000000000",
 425        .plaintext =
 426            "000102030405060708090a0b0c0d0e0f"
 427            "101112131415161718191a1b1c1d1e1f"
 428            "202122232425262728292a2b2c2d2e2f"
 429            "303132333435363738393a3b3c3d3e3f"
 430            "404142434445464748494a4b4c4d4e4f"
 431            "505152535455565758595a5b5c5d5e5f"
 432            "606162636465666768696a6b6c6d6e6f"
 433            "707172737475767778797a7b7c7d7e7f"
 434            "808182838485868788898a8b8c8d8e8f"
 435            "909192939495969798999a9b9c9d9e9f"
 436            "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
 437            "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
 438            "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
 439            "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
 440            "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
 441            "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
 442            "000102030405060708090a0b0c0d0e0f"
 443            "101112131415161718191a1b1c1d1e1f"
 444            "202122232425262728292a2b2c2d2e2f"
 445            "303132333435363738393a3b3c3d3e3f"
 446            "404142434445464748494a4b4c4d4e4f"
 447            "505152535455565758595a5b5c5d5e5f"
 448            "606162636465666768696a6b6c6d6e6f"
 449            "707172737475767778797a7b7c7d7e7f"
 450            "808182838485868788898a8b8c8d8e8f"
 451            "909192939495969798999a9b9c9d9e9f"
 452            "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
 453            "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
 454            "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
 455            "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
 456            "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
 457            "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
 458        .ciphertext =
 459            "27a7479befa1d476489f308cd4cfa6e2"
 460            "a96e4bbe3208ff25287dd3819616e89c"
 461            "c78cf7f5e543445f8333d8fa7f560000"
 462            "05279fa5d8b5e4ad40e736ddb4d35412"
 463            "328063fd2aab53e5ea1e0a9f332500a5"
 464            "df9487d07a5c92cc512c8866c7e860ce"
 465            "93fdf166a24912b422976146ae20ce84"
 466            "6bb7dc9ba94a767aaef20c0d61ad0265"
 467            "5ea92dc4c4e41a8952c651d33174be51"
 468            "a10c421110e6d81588ede82103a252d8"
 469            "a750e8768defffed9122810aaeb99f91"
 470            "72af82b604dc4b8e51bcb08235a6f434"
 471            "1332e4ca60482a4ba1a03b3e65008fc5"
 472            "da76b70bf1690db4eae29c5f1badd03c"
 473            "5ccf2a55d705ddcd86d449511ceb7ec3"
 474            "0bf12b1fa35b913f9f747a8afd1b130e"
 475            "94bff94effd01a91735ca1726acd0b19"
 476            "7c4e5b03393697e126826fb6bbde8ecc"
 477            "1e08298516e2c9ed03ff3c1b7860f6de"
 478            "76d4cecd94c8119855ef5297ca67e9f3"
 479            "e7ff72b1e99785ca0a7e7720c5b36dc6"
 480            "d72cac9574c8cbbc2f801e23e56fd344"
 481            "b07f22154beba0f08ce8891e643ed995"
 482            "c94d9a69c9f1b5f499027a78572aeebd"
 483            "74d20cc39881c213ee770b1010e4bea7"
 484            "18846977ae119f7a023ab58cca0ad752"
 485            "afe656bb3c17256a9f6e9bf19fdd5a38"
 486            "fc82bbe872c5539edb609ef4f79c203e"
 487            "bb140f2e583cb2ad15b4aa5b655016a8"
 488            "449277dbd477ef2c8d6c017db738b18d"
 489            "eb4a427d1923ce3ff262735779a418f2"
 490            "0a282df920147beabe421ee5319d0568",
 491    },
 492    {
 493        /* Bad config - cast5-128 has 8 byte block size
 494         * which is incompatible with XTS
 495         */
 496        .path = "/crypto/cipher/cast5-xts-128",
 497        .alg = QCRYPTO_CIPHER_ALG_CAST5_128,
 498        .mode = QCRYPTO_CIPHER_MODE_XTS,
 499        .key =
 500            "27182818284590452353602874713526"
 501            "31415926535897932384626433832795",
 502    },
 503    {
 504        /* NIST F.5.1 CTR-AES128.Encrypt */
 505        .path = "/crypto/cipher/aes-ctr-128",
 506        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 507        .mode = QCRYPTO_CIPHER_MODE_CTR,
 508        .key = "2b7e151628aed2a6abf7158809cf4f3c",
 509        .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
 510        .plaintext  =
 511            "6bc1bee22e409f96e93d7e117393172a"
 512            "ae2d8a571e03ac9c9eb76fac45af8e51"
 513            "30c81c46a35ce411e5fbc1191a0a52ef"
 514            "f69f2445df4f9b17ad2b417be66c3710",
 515        .ciphertext =
 516            "874d6191b620e3261bef6864990db6ce"
 517            "9806f66b7970fdff8617187bb9fffdff"
 518            "5ae4df3edbd5d35e5b4f09020db03eab"
 519            "1e031dda2fbe03d1792170a0f3009cee",
 520    },
 521    {
 522        /* NIST F.5.3 CTR-AES192.Encrypt */
 523        .path = "/crypto/cipher/aes-ctr-192",
 524        .alg = QCRYPTO_CIPHER_ALG_AES_192,
 525        .mode = QCRYPTO_CIPHER_MODE_CTR,
 526        .key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
 527        .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
 528        .plaintext  =
 529            "6bc1bee22e409f96e93d7e117393172a"
 530            "ae2d8a571e03ac9c9eb76fac45af8e51"
 531            "30c81c46a35ce411e5fbc1191a0a52ef"
 532            "f69f2445df4f9b17ad2b417be66c3710",
 533        .ciphertext =
 534            "1abc932417521ca24f2b0459fe7e6e0b"
 535            "090339ec0aa6faefd5ccc2c6f4ce8e94"
 536            "1e36b26bd1ebc670d1bd1d665620abf7"
 537            "4f78a7f6d29809585a97daec58c6b050",
 538    },
 539    {
 540        /* NIST F.5.5 CTR-AES256.Encrypt */
 541        .path = "/crypto/cipher/aes-ctr-256",
 542        .alg = QCRYPTO_CIPHER_ALG_AES_256,
 543        .mode = QCRYPTO_CIPHER_MODE_CTR,
 544        .key = "603deb1015ca71be2b73aef0857d7781"
 545               "1f352c073b6108d72d9810a30914dff4",
 546        .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
 547        .plaintext  =
 548            "6bc1bee22e409f96e93d7e117393172a"
 549            "ae2d8a571e03ac9c9eb76fac45af8e51"
 550            "30c81c46a35ce411e5fbc1191a0a52ef"
 551            "f69f2445df4f9b17ad2b417be66c3710",
 552        .ciphertext =
 553            "601ec313775789a5b7a7f504bbf3d228"
 554            "f443e3ca4d62b59aca84e990cacaf5c5"
 555            "2b0930daa23de94ce87017ba2d84988d"
 556            "dfc9c58db67aada613c2dd08457941a6",
 557    }
 558};
 559
 560
 561static inline int unhex(char c)
 562{
 563    if (c >= 'a' && c <= 'f') {
 564        return 10 + (c - 'a');
 565    }
 566    if (c >= 'A' && c <= 'F') {
 567        return 10 + (c - 'A');
 568    }
 569    return c - '0';
 570}
 571
 572static inline char hex(int i)
 573{
 574    if (i < 10) {
 575        return '0' + i;
 576    }
 577    return 'a' + (i - 10);
 578}
 579
 580static size_t unhex_string(const char *hexstr,
 581                           uint8_t **data)
 582{
 583    size_t len;
 584    size_t i;
 585
 586    if (!hexstr) {
 587        *data = NULL;
 588        return 0;
 589    }
 590
 591    len = strlen(hexstr);
 592    *data = g_new0(uint8_t, len / 2);
 593
 594    for (i = 0; i < len; i += 2) {
 595        (*data)[i/2] = (unhex(hexstr[i]) << 4) | unhex(hexstr[i+1]);
 596    }
 597    return len / 2;
 598}
 599
 600static char *hex_string(const uint8_t *bytes,
 601                        size_t len)
 602{
 603    char *hexstr = g_new0(char, len * 2 + 1);
 604    size_t i;
 605
 606    for (i = 0; i < len; i++) {
 607        hexstr[i*2] = hex((bytes[i] >> 4) & 0xf);
 608        hexstr[i*2+1] = hex(bytes[i] & 0xf);
 609    }
 610    hexstr[len*2] = '\0';
 611
 612    return hexstr;
 613}
 614
 615static void test_cipher(const void *opaque)
 616{
 617    const QCryptoCipherTestData *data = opaque;
 618
 619    QCryptoCipher *cipher;
 620    uint8_t *key, *iv = NULL, *ciphertext = NULL,
 621        *plaintext = NULL, *outtext = NULL;
 622    size_t nkey, niv = 0, nciphertext = 0, nplaintext = 0;
 623    char *outtexthex = NULL;
 624    size_t ivsize, keysize, blocksize;
 625    Error *err = NULL;
 626
 627    nkey = unhex_string(data->key, &key);
 628    if (data->iv) {
 629        niv = unhex_string(data->iv, &iv);
 630    }
 631    if (data->ciphertext) {
 632        nciphertext = unhex_string(data->ciphertext, &ciphertext);
 633    }
 634    if (data->plaintext) {
 635        nplaintext = unhex_string(data->plaintext, &plaintext);
 636    }
 637
 638    g_assert(nciphertext == nplaintext);
 639
 640    outtext = g_new0(uint8_t, nciphertext);
 641
 642    cipher = qcrypto_cipher_new(
 643        data->alg, data->mode,
 644        key, nkey,
 645        &err);
 646    if (data->plaintext) {
 647        g_assert(err == NULL);
 648        g_assert(cipher != NULL);
 649    } else {
 650        error_free_or_abort(&err);
 651        g_assert(cipher == NULL);
 652        goto cleanup;
 653    }
 654
 655    keysize = qcrypto_cipher_get_key_len(data->alg);
 656    blocksize = qcrypto_cipher_get_block_len(data->alg);
 657    ivsize = qcrypto_cipher_get_iv_len(data->alg, data->mode);
 658
 659    if (data->mode == QCRYPTO_CIPHER_MODE_XTS) {
 660        g_assert_cmpint(keysize * 2, ==, nkey);
 661    } else {
 662        g_assert_cmpint(keysize, ==, nkey);
 663    }
 664    g_assert_cmpint(ivsize, ==, niv);
 665    if (niv) {
 666        g_assert_cmpint(blocksize, ==, niv);
 667    }
 668
 669    if (iv) {
 670        g_assert(qcrypto_cipher_setiv(cipher,
 671                                      iv, niv,
 672                                      &error_abort) == 0);
 673    }
 674    g_assert(qcrypto_cipher_encrypt(cipher,
 675                                    plaintext,
 676                                    outtext,
 677                                    nplaintext,
 678                                    &error_abort) == 0);
 679
 680    outtexthex = hex_string(outtext, nciphertext);
 681
 682    g_assert_cmpstr(outtexthex, ==, data->ciphertext);
 683
 684    g_free(outtexthex);
 685
 686    if (iv) {
 687        g_assert(qcrypto_cipher_setiv(cipher,
 688                                      iv, niv,
 689                                      &error_abort) == 0);
 690    }
 691    g_assert(qcrypto_cipher_decrypt(cipher,
 692                                    ciphertext,
 693                                    outtext,
 694                                    nplaintext,
 695                                    &error_abort) == 0);
 696
 697    outtexthex = hex_string(outtext, nplaintext);
 698
 699    g_assert_cmpstr(outtexthex, ==, data->plaintext);
 700
 701 cleanup:
 702    g_free(outtext);
 703    g_free(outtexthex);
 704    g_free(key);
 705    g_free(iv);
 706    g_free(ciphertext);
 707    g_free(plaintext);
 708    qcrypto_cipher_free(cipher);
 709}
 710
 711
 712static void test_cipher_null_iv(void)
 713{
 714    QCryptoCipher *cipher;
 715    uint8_t key[32] = { 0 };
 716    uint8_t plaintext[32] = { 0 };
 717    uint8_t ciphertext[32] = { 0 };
 718
 719    cipher = qcrypto_cipher_new(
 720        QCRYPTO_CIPHER_ALG_AES_256,
 721        QCRYPTO_CIPHER_MODE_CBC,
 722        key, sizeof(key),
 723        &error_abort);
 724    g_assert(cipher != NULL);
 725
 726    /* Don't call qcrypto_cipher_setiv */
 727
 728    qcrypto_cipher_encrypt(cipher,
 729                           plaintext,
 730                           ciphertext,
 731                           sizeof(plaintext),
 732                           &error_abort);
 733
 734    qcrypto_cipher_free(cipher);
 735}
 736
 737static void test_cipher_short_plaintext(void)
 738{
 739    Error *err = NULL;
 740    QCryptoCipher *cipher;
 741    uint8_t key[32] = { 0 };
 742    uint8_t plaintext1[20] = { 0 };
 743    uint8_t ciphertext1[20] = { 0 };
 744    uint8_t plaintext2[40] = { 0 };
 745    uint8_t ciphertext2[40] = { 0 };
 746    int ret;
 747
 748    cipher = qcrypto_cipher_new(
 749        QCRYPTO_CIPHER_ALG_AES_256,
 750        QCRYPTO_CIPHER_MODE_CBC,
 751        key, sizeof(key),
 752        &error_abort);
 753    g_assert(cipher != NULL);
 754
 755    /* Should report an error as plaintext is shorter
 756     * than block size
 757     */
 758    ret = qcrypto_cipher_encrypt(cipher,
 759                                 plaintext1,
 760                                 ciphertext1,
 761                                 sizeof(plaintext1),
 762                                 &err);
 763    g_assert(ret == -1);
 764    g_assert(err != NULL);
 765
 766    error_free(err);
 767    err = NULL;
 768
 769    /* Should report an error as plaintext is larger than
 770     * block size, but not a multiple of block size
 771     */
 772    ret = qcrypto_cipher_encrypt(cipher,
 773                                 plaintext2,
 774                                 ciphertext2,
 775                                 sizeof(plaintext2),
 776                                 &err);
 777    g_assert(ret == -1);
 778    g_assert(err != NULL);
 779
 780    error_free(err);
 781    qcrypto_cipher_free(cipher);
 782}
 783
 784int main(int argc, char **argv)
 785{
 786    size_t i;
 787
 788    g_test_init(&argc, &argv, NULL);
 789
 790    g_assert(qcrypto_init(NULL) == 0);
 791
 792    for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
 793        if (qcrypto_cipher_supports(test_data[i].alg, test_data[i].mode)) {
 794            g_test_add_data_func(test_data[i].path, &test_data[i], test_cipher);
 795        }
 796    }
 797
 798    g_test_add_func("/crypto/cipher/null-iv",
 799                    test_cipher_null_iv);
 800
 801    g_test_add_func("/crypto/cipher/short-plaintext",
 802                    test_cipher_short_plaintext);
 803
 804    return g_test_run();
 805}
 806