cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

test-crypto-cipher.c (28757B)


      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}