qemu/tests/unit/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.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
  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        /*
 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    {
 386        /* #1 32 byte key, 32 byte PTX */
 387        .path = "/crypto/cipher/aes-xts-128-1",
 388        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 389        .mode = QCRYPTO_CIPHER_MODE_XTS,
 390        .key =
 391            "00000000000000000000000000000000"
 392            "00000000000000000000000000000000",
 393        .iv =
 394            "00000000000000000000000000000000",
 395        .plaintext =
 396            "00000000000000000000000000000000"
 397            "00000000000000000000000000000000",
 398        .ciphertext =
 399            "917cf69ebd68b2ec9b9fe9a3eadda692"
 400            "cd43d2f59598ed858c02c2652fbf922e",
 401    },
 402    {
 403        /* #2, 32 byte key, 32 byte PTX */
 404        .path = "/crypto/cipher/aes-xts-128-2",
 405        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 406        .mode = QCRYPTO_CIPHER_MODE_XTS,
 407        .key =
 408            "11111111111111111111111111111111"
 409            "22222222222222222222222222222222",
 410        .iv =
 411            "33333333330000000000000000000000",
 412        .plaintext =
 413            "44444444444444444444444444444444"
 414            "44444444444444444444444444444444",
 415        .ciphertext =
 416            "c454185e6a16936e39334038acef838b"
 417            "fb186fff7480adc4289382ecd6d394f0",
 418    },
 419    {
 420        /* #5 from xts.7, 32 byte key, 32 byte PTX */
 421        .path = "/crypto/cipher/aes-xts-128-3",
 422        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 423        .mode = QCRYPTO_CIPHER_MODE_XTS,
 424        .key =
 425            "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0"
 426            "bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0",
 427        .iv =
 428            "9a785634120000000000000000000000",
 429        .plaintext =
 430            "44444444444444444444444444444444"
 431            "44444444444444444444444444444444",
 432        .ciphertext =
 433            "b01f86f8edc1863706fa8a4253e34f28"
 434            "af319de38334870f4dd1f94cbe9832f1",
 435    },
 436    {
 437        /* #4, 32 byte key, 512 byte PTX  */
 438        .path = "/crypto/cipher/aes-xts-128-4",
 439        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 440        .mode = QCRYPTO_CIPHER_MODE_XTS,
 441        .key =
 442            "27182818284590452353602874713526"
 443            "31415926535897932384626433832795",
 444        .iv =
 445            "00000000000000000000000000000000",
 446        .plaintext =
 447            "000102030405060708090a0b0c0d0e0f"
 448            "101112131415161718191a1b1c1d1e1f"
 449            "202122232425262728292a2b2c2d2e2f"
 450            "303132333435363738393a3b3c3d3e3f"
 451            "404142434445464748494a4b4c4d4e4f"
 452            "505152535455565758595a5b5c5d5e5f"
 453            "606162636465666768696a6b6c6d6e6f"
 454            "707172737475767778797a7b7c7d7e7f"
 455            "808182838485868788898a8b8c8d8e8f"
 456            "909192939495969798999a9b9c9d9e9f"
 457            "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
 458            "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
 459            "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
 460            "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
 461            "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
 462            "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
 463            "000102030405060708090a0b0c0d0e0f"
 464            "101112131415161718191a1b1c1d1e1f"
 465            "202122232425262728292a2b2c2d2e2f"
 466            "303132333435363738393a3b3c3d3e3f"
 467            "404142434445464748494a4b4c4d4e4f"
 468            "505152535455565758595a5b5c5d5e5f"
 469            "606162636465666768696a6b6c6d6e6f"
 470            "707172737475767778797a7b7c7d7e7f"
 471            "808182838485868788898a8b8c8d8e8f"
 472            "909192939495969798999a9b9c9d9e9f"
 473            "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
 474            "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
 475            "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
 476            "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
 477            "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
 478            "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
 479        .ciphertext =
 480            "27a7479befa1d476489f308cd4cfa6e2"
 481            "a96e4bbe3208ff25287dd3819616e89c"
 482            "c78cf7f5e543445f8333d8fa7f560000"
 483            "05279fa5d8b5e4ad40e736ddb4d35412"
 484            "328063fd2aab53e5ea1e0a9f332500a5"
 485            "df9487d07a5c92cc512c8866c7e860ce"
 486            "93fdf166a24912b422976146ae20ce84"
 487            "6bb7dc9ba94a767aaef20c0d61ad0265"
 488            "5ea92dc4c4e41a8952c651d33174be51"
 489            "a10c421110e6d81588ede82103a252d8"
 490            "a750e8768defffed9122810aaeb99f91"
 491            "72af82b604dc4b8e51bcb08235a6f434"
 492            "1332e4ca60482a4ba1a03b3e65008fc5"
 493            "da76b70bf1690db4eae29c5f1badd03c"
 494            "5ccf2a55d705ddcd86d449511ceb7ec3"
 495            "0bf12b1fa35b913f9f747a8afd1b130e"
 496            "94bff94effd01a91735ca1726acd0b19"
 497            "7c4e5b03393697e126826fb6bbde8ecc"
 498            "1e08298516e2c9ed03ff3c1b7860f6de"
 499            "76d4cecd94c8119855ef5297ca67e9f3"
 500            "e7ff72b1e99785ca0a7e7720c5b36dc6"
 501            "d72cac9574c8cbbc2f801e23e56fd344"
 502            "b07f22154beba0f08ce8891e643ed995"
 503            "c94d9a69c9f1b5f499027a78572aeebd"
 504            "74d20cc39881c213ee770b1010e4bea7"
 505            "18846977ae119f7a023ab58cca0ad752"
 506            "afe656bb3c17256a9f6e9bf19fdd5a38"
 507            "fc82bbe872c5539edb609ef4f79c203e"
 508            "bb140f2e583cb2ad15b4aa5b655016a8"
 509            "449277dbd477ef2c8d6c017db738b18d"
 510            "eb4a427d1923ce3ff262735779a418f2"
 511            "0a282df920147beabe421ee5319d0568",
 512    },
 513    {
 514        /* Bad config - cast5-128 has 8 byte block size
 515         * which is incompatible with XTS
 516         */
 517        .path = "/crypto/cipher/cast5-xts-128",
 518        .alg = QCRYPTO_CIPHER_ALG_CAST5_128,
 519        .mode = QCRYPTO_CIPHER_MODE_XTS,
 520        .key =
 521            "27182818284590452353602874713526"
 522            "31415926535897932384626433832795",
 523    },
 524    {
 525        /* NIST F.5.1 CTR-AES128.Encrypt */
 526        .path = "/crypto/cipher/aes-ctr-128",
 527        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 528        .mode = QCRYPTO_CIPHER_MODE_CTR,
 529        .key = "2b7e151628aed2a6abf7158809cf4f3c",
 530        .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
 531        .plaintext  =
 532            "6bc1bee22e409f96e93d7e117393172a"
 533            "ae2d8a571e03ac9c9eb76fac45af8e51"
 534            "30c81c46a35ce411e5fbc1191a0a52ef"
 535            "f69f2445df4f9b17ad2b417be66c3710",
 536        .ciphertext =
 537            "874d6191b620e3261bef6864990db6ce"
 538            "9806f66b7970fdff8617187bb9fffdff"
 539            "5ae4df3edbd5d35e5b4f09020db03eab"
 540            "1e031dda2fbe03d1792170a0f3009cee",
 541    },
 542    {
 543        /* NIST F.5.3 CTR-AES192.Encrypt */
 544        .path = "/crypto/cipher/aes-ctr-192",
 545        .alg = QCRYPTO_CIPHER_ALG_AES_192,
 546        .mode = QCRYPTO_CIPHER_MODE_CTR,
 547        .key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
 548        .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
 549        .plaintext  =
 550            "6bc1bee22e409f96e93d7e117393172a"
 551            "ae2d8a571e03ac9c9eb76fac45af8e51"
 552            "30c81c46a35ce411e5fbc1191a0a52ef"
 553            "f69f2445df4f9b17ad2b417be66c3710",
 554        .ciphertext =
 555            "1abc932417521ca24f2b0459fe7e6e0b"
 556            "090339ec0aa6faefd5ccc2c6f4ce8e94"
 557            "1e36b26bd1ebc670d1bd1d665620abf7"
 558            "4f78a7f6d29809585a97daec58c6b050",
 559    },
 560    {
 561        /* NIST F.5.5 CTR-AES256.Encrypt */
 562        .path = "/crypto/cipher/aes-ctr-256",
 563        .alg = QCRYPTO_CIPHER_ALG_AES_256,
 564        .mode = QCRYPTO_CIPHER_MODE_CTR,
 565        .key = "603deb1015ca71be2b73aef0857d7781"
 566               "1f352c073b6108d72d9810a30914dff4",
 567        .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
 568        .plaintext  =
 569            "6bc1bee22e409f96e93d7e117393172a"
 570            "ae2d8a571e03ac9c9eb76fac45af8e51"
 571            "30c81c46a35ce411e5fbc1191a0a52ef"
 572            "f69f2445df4f9b17ad2b417be66c3710",
 573        .ciphertext =
 574            "601ec313775789a5b7a7f504bbf3d228"
 575            "f443e3ca4d62b59aca84e990cacaf5c5"
 576            "2b0930daa23de94ce87017ba2d84988d"
 577            "dfc9c58db67aada613c2dd08457941a6",
 578    }
 579};
 580
 581
 582static inline int unhex(char c)
 583{
 584    if (c >= 'a' && c <= 'f') {
 585        return 10 + (c - 'a');
 586    }
 587    if (c >= 'A' && c <= 'F') {
 588        return 10 + (c - 'A');
 589    }
 590    return c - '0';
 591}
 592
 593static inline char hex(int i)
 594{
 595    if (i < 10) {
 596        return '0' + i;
 597    }
 598    return 'a' + (i - 10);
 599}
 600
 601static size_t unhex_string(const char *hexstr,
 602                           uint8_t **data)
 603{
 604    size_t len;
 605    size_t i;
 606
 607    if (!hexstr) {
 608        *data = NULL;
 609        return 0;
 610    }
 611
 612    len = strlen(hexstr);
 613    *data = g_new0(uint8_t, len / 2);
 614
 615    for (i = 0; i < len; i += 2) {
 616        (*data)[i/2] = (unhex(hexstr[i]) << 4) | unhex(hexstr[i+1]);
 617    }
 618    return len / 2;
 619}
 620
 621static char *hex_string(const uint8_t *bytes,
 622                        size_t len)
 623{
 624    char *hexstr = g_new0(char, len * 2 + 1);
 625    size_t i;
 626
 627    for (i = 0; i < len; i++) {
 628        hexstr[i*2] = hex((bytes[i] >> 4) & 0xf);
 629        hexstr[i*2+1] = hex(bytes[i] & 0xf);
 630    }
 631    hexstr[len*2] = '\0';
 632
 633    return hexstr;
 634}
 635
 636static void test_cipher(const void *opaque)
 637{
 638    const QCryptoCipherTestData *data = opaque;
 639
 640    QCryptoCipher *cipher;
 641    uint8_t *key, *iv = NULL, *ciphertext = NULL,
 642        *plaintext = NULL, *outtext = NULL;
 643    size_t nkey, niv = 0, nciphertext = 0, nplaintext = 0;
 644    char *outtexthex = NULL;
 645    size_t ivsize, keysize, blocksize;
 646    Error *err = NULL;
 647
 648    nkey = unhex_string(data->key, &key);
 649    if (data->iv) {
 650        niv = unhex_string(data->iv, &iv);
 651    }
 652    if (data->ciphertext) {
 653        nciphertext = unhex_string(data->ciphertext, &ciphertext);
 654    }
 655    if (data->plaintext) {
 656        nplaintext = unhex_string(data->plaintext, &plaintext);
 657    }
 658
 659    g_assert(nciphertext == nplaintext);
 660
 661    outtext = g_new0(uint8_t, nciphertext);
 662
 663    cipher = qcrypto_cipher_new(
 664        data->alg, data->mode,
 665        key, nkey,
 666        &err);
 667    if (data->plaintext) {
 668        g_assert(err == NULL);
 669        g_assert(cipher != NULL);
 670    } else {
 671        error_free_or_abort(&err);
 672        g_assert(cipher == NULL);
 673        goto cleanup;
 674    }
 675
 676    keysize = qcrypto_cipher_get_key_len(data->alg);
 677    blocksize = qcrypto_cipher_get_block_len(data->alg);
 678    ivsize = qcrypto_cipher_get_iv_len(data->alg, data->mode);
 679
 680    if (data->mode == QCRYPTO_CIPHER_MODE_XTS) {
 681        g_assert_cmpint(keysize * 2, ==, nkey);
 682    } else {
 683        g_assert_cmpint(keysize, ==, nkey);
 684    }
 685    g_assert_cmpint(ivsize, ==, niv);
 686    if (niv) {
 687        g_assert_cmpint(blocksize, ==, niv);
 688    }
 689
 690    if (iv) {
 691        g_assert(qcrypto_cipher_setiv(cipher,
 692                                      iv, niv,
 693                                      &error_abort) == 0);
 694    }
 695    g_assert(qcrypto_cipher_encrypt(cipher,
 696                                    plaintext,
 697                                    outtext,
 698                                    nplaintext,
 699                                    &error_abort) == 0);
 700
 701    outtexthex = hex_string(outtext, nciphertext);
 702
 703    g_assert_cmpstr(outtexthex, ==, data->ciphertext);
 704
 705    g_free(outtexthex);
 706
 707    if (iv) {
 708        g_assert(qcrypto_cipher_setiv(cipher,
 709                                      iv, niv,
 710                                      &error_abort) == 0);
 711    }
 712    g_assert(qcrypto_cipher_decrypt(cipher,
 713                                    ciphertext,
 714                                    outtext,
 715                                    nplaintext,
 716                                    &error_abort) == 0);
 717
 718    outtexthex = hex_string(outtext, nplaintext);
 719
 720    g_assert_cmpstr(outtexthex, ==, data->plaintext);
 721
 722 cleanup:
 723    g_free(outtext);
 724    g_free(outtexthex);
 725    g_free(key);
 726    g_free(iv);
 727    g_free(ciphertext);
 728    g_free(plaintext);
 729    qcrypto_cipher_free(cipher);
 730}
 731
 732
 733static void test_cipher_null_iv(void)
 734{
 735    QCryptoCipher *cipher;
 736    uint8_t key[32] = { 0 };
 737    uint8_t plaintext[32] = { 0 };
 738    uint8_t ciphertext[32] = { 0 };
 739
 740    cipher = qcrypto_cipher_new(
 741        QCRYPTO_CIPHER_ALG_AES_256,
 742        QCRYPTO_CIPHER_MODE_CBC,
 743        key, sizeof(key),
 744        &error_abort);
 745    g_assert(cipher != NULL);
 746
 747    /* Don't call qcrypto_cipher_setiv */
 748
 749    qcrypto_cipher_encrypt(cipher,
 750                           plaintext,
 751                           ciphertext,
 752                           sizeof(plaintext),
 753                           &error_abort);
 754
 755    qcrypto_cipher_free(cipher);
 756}
 757
 758static void test_cipher_short_plaintext(void)
 759{
 760    Error *err = NULL;
 761    QCryptoCipher *cipher;
 762    uint8_t key[32] = { 0 };
 763    uint8_t plaintext1[20] = { 0 };
 764    uint8_t ciphertext1[20] = { 0 };
 765    uint8_t plaintext2[40] = { 0 };
 766    uint8_t ciphertext2[40] = { 0 };
 767    int ret;
 768
 769    cipher = qcrypto_cipher_new(
 770        QCRYPTO_CIPHER_ALG_AES_256,
 771        QCRYPTO_CIPHER_MODE_CBC,
 772        key, sizeof(key),
 773        &error_abort);
 774    g_assert(cipher != NULL);
 775
 776    /* Should report an error as plaintext is shorter
 777     * than block size
 778     */
 779    ret = qcrypto_cipher_encrypt(cipher,
 780                                 plaintext1,
 781                                 ciphertext1,
 782                                 sizeof(plaintext1),
 783                                 &err);
 784    g_assert(ret == -1);
 785    error_free_or_abort(&err);
 786
 787    /* Should report an error as plaintext is larger than
 788     * block size, but not a multiple of block size
 789     */
 790    ret = qcrypto_cipher_encrypt(cipher,
 791                                 plaintext2,
 792                                 ciphertext2,
 793                                 sizeof(plaintext2),
 794                                 &err);
 795    g_assert(ret == -1);
 796    error_free_or_abort(&err);
 797
 798    qcrypto_cipher_free(cipher);
 799}
 800
 801int main(int argc, char **argv)
 802{
 803    size_t i;
 804
 805    g_test_init(&argc, &argv, NULL);
 806
 807    g_assert(qcrypto_init(NULL) == 0);
 808
 809    for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
 810        if (qcrypto_cipher_supports(test_data[i].alg, test_data[i].mode)) {
 811            g_test_add_data_func(test_data[i].path, &test_data[i], test_cipher);
 812        }
 813    }
 814
 815    g_test_add_func("/crypto/cipher/null-iv",
 816                    test_cipher_null_iv);
 817
 818    g_test_add_func("/crypto/cipher/short-plaintext",
 819                    test_cipher_short_plaintext);
 820
 821    return g_test_run();
 822}
 823