qemu/tests/test-crypto-hash.c
<<
>>
Prefs
   1/*
   2 * QEMU Crypto hash 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#include <glib.h>
  23
  24#include "crypto/init.h"
  25#include "crypto/hash.h"
  26
  27#define INPUT_TEXT "Hiss hisss Hissss hiss Hiss hisss Hiss hiss"
  28#define INPUT_TEXT1 "Hiss hisss "
  29#define INPUT_TEXT2 "Hissss hiss "
  30#define INPUT_TEXT3 "Hiss hisss Hiss hiss"
  31
  32#define OUTPUT_MD5 "628d206371563035ab8ef62f492bdec9"
  33#define OUTPUT_SHA1 "b2e74f26758a3a421e509cee045244b78753cc02"
  34#define OUTPUT_SHA256 "bc757abb0436586f392b437e5dd24096" \
  35                      "f7f224de6b74d4d86e2abc6121b160d0"
  36
  37#define OUTPUT_MD5_B64 "Yo0gY3FWMDWrjvYvSSveyQ=="
  38#define OUTPUT_SHA1_B64 "sudPJnWKOkIeUJzuBFJEt4dTzAI="
  39#define OUTPUT_SHA256_B64 "vHV6uwQ2WG85K0N+XdJAlvfyJN5rdNTYbiq8YSGxYNA="
  40
  41static const char *expected_outputs[] = {
  42    [QCRYPTO_HASH_ALG_MD5] = OUTPUT_MD5,
  43    [QCRYPTO_HASH_ALG_SHA1] = OUTPUT_SHA1,
  44    [QCRYPTO_HASH_ALG_SHA256] = OUTPUT_SHA256,
  45};
  46static const char *expected_outputs_b64[] = {
  47    [QCRYPTO_HASH_ALG_MD5] = OUTPUT_MD5_B64,
  48    [QCRYPTO_HASH_ALG_SHA1] = OUTPUT_SHA1_B64,
  49    [QCRYPTO_HASH_ALG_SHA256] = OUTPUT_SHA256_B64,
  50};
  51static const int expected_lens[] = {
  52    [QCRYPTO_HASH_ALG_MD5] = 16,
  53    [QCRYPTO_HASH_ALG_SHA1] = 20,
  54    [QCRYPTO_HASH_ALG_SHA256] = 32,
  55};
  56
  57static const char hex[] = "0123456789abcdef";
  58
  59/* Test with dynamic allocation */
  60static void test_hash_alloc(void)
  61{
  62    size_t i;
  63
  64    g_assert(qcrypto_init(NULL) == 0);
  65
  66    for (i = 0; i < G_N_ELEMENTS(expected_outputs) ; i++) {
  67        uint8_t *result = NULL;
  68        size_t resultlen = 0;
  69        int ret;
  70        size_t j;
  71
  72        ret = qcrypto_hash_bytes(i,
  73                                 INPUT_TEXT,
  74                                 strlen(INPUT_TEXT),
  75                                 &result,
  76                                 &resultlen,
  77                                 NULL);
  78        g_assert(ret == 0);
  79        g_assert(resultlen == expected_lens[i]);
  80
  81        for (j = 0; j < resultlen; j++) {
  82            g_assert(expected_outputs[i][j * 2] == hex[(result[j] >> 4) & 0xf]);
  83            g_assert(expected_outputs[i][j * 2 + 1] == hex[result[j] & 0xf]);
  84        }
  85        g_free(result);
  86    }
  87}
  88
  89/* Test with caller preallocating */
  90static void test_hash_prealloc(void)
  91{
  92    size_t i;
  93
  94    g_assert(qcrypto_init(NULL) == 0);
  95
  96    for (i = 0; i < G_N_ELEMENTS(expected_outputs) ; i++) {
  97        uint8_t *result;
  98        size_t resultlen;
  99        int ret;
 100        size_t j;
 101
 102        resultlen = expected_lens[i];
 103        result = g_new0(uint8_t, resultlen);
 104
 105        ret = qcrypto_hash_bytes(i,
 106                                 INPUT_TEXT,
 107                                 strlen(INPUT_TEXT),
 108                                 &result,
 109                                 &resultlen,
 110                                 NULL);
 111        g_assert(ret == 0);
 112
 113        g_assert(resultlen == expected_lens[i]);
 114        for (j = 0; j < resultlen; j++) {
 115            g_assert(expected_outputs[i][j * 2] == hex[(result[j] >> 4) & 0xf]);
 116            g_assert(expected_outputs[i][j * 2 + 1] == hex[result[j] & 0xf]);
 117        }
 118        g_free(result);
 119    }
 120}
 121
 122
 123/* Test with dynamic allocation */
 124static void test_hash_iov(void)
 125{
 126    size_t i;
 127
 128    g_assert(qcrypto_init(NULL) == 0);
 129
 130    for (i = 0; i < G_N_ELEMENTS(expected_outputs) ; i++) {
 131        struct iovec iov[3] = {
 132            { .iov_base = (char *)INPUT_TEXT1, .iov_len = strlen(INPUT_TEXT1) },
 133            { .iov_base = (char *)INPUT_TEXT2, .iov_len = strlen(INPUT_TEXT2) },
 134            { .iov_base = (char *)INPUT_TEXT3, .iov_len = strlen(INPUT_TEXT3) },
 135        };
 136        uint8_t *result = NULL;
 137        size_t resultlen = 0;
 138        int ret;
 139        size_t j;
 140
 141        ret = qcrypto_hash_bytesv(i,
 142                                  iov, 3,
 143                                  &result,
 144                                  &resultlen,
 145                                  NULL);
 146        g_assert(ret == 0);
 147        g_assert(resultlen == expected_lens[i]);
 148        for (j = 0; j < resultlen; j++) {
 149            g_assert(expected_outputs[i][j * 2] == hex[(result[j] >> 4) & 0xf]);
 150            g_assert(expected_outputs[i][j * 2 + 1] == hex[result[j] & 0xf]);
 151        }
 152        g_free(result);
 153    }
 154}
 155
 156
 157/* Test with printable hashing */
 158static void test_hash_digest(void)
 159{
 160    size_t i;
 161
 162    g_assert(qcrypto_init(NULL) == 0);
 163
 164    for (i = 0; i < G_N_ELEMENTS(expected_outputs) ; i++) {
 165        int ret;
 166        char *digest;
 167        size_t digestsize;
 168
 169        digestsize = qcrypto_hash_digest_len(i);
 170
 171        g_assert_cmpint(digestsize * 2, ==, strlen(expected_outputs[i]));
 172
 173        ret = qcrypto_hash_digest(i,
 174                                  INPUT_TEXT,
 175                                  strlen(INPUT_TEXT),
 176                                  &digest,
 177                                  NULL);
 178        g_assert(ret == 0);
 179        g_assert(g_str_equal(digest, expected_outputs[i]));
 180        g_free(digest);
 181    }
 182}
 183
 184/* Test with base64 encoding */
 185static void test_hash_base64(void)
 186{
 187    size_t i;
 188
 189    g_assert(qcrypto_init(NULL) == 0);
 190
 191    for (i = 0; i < G_N_ELEMENTS(expected_outputs) ; i++) {
 192        int ret;
 193        char *digest;
 194
 195        ret = qcrypto_hash_base64(i,
 196                                  INPUT_TEXT,
 197                                  strlen(INPUT_TEXT),
 198                                  &digest,
 199                                  NULL);
 200        g_assert(ret == 0);
 201        g_assert(g_str_equal(digest, expected_outputs_b64[i]));
 202        g_free(digest);
 203    }
 204}
 205
 206int main(int argc, char **argv)
 207{
 208    g_test_init(&argc, &argv, NULL);
 209    g_test_add_func("/crypto/hash/iov", test_hash_iov);
 210    g_test_add_func("/crypto/hash/alloc", test_hash_alloc);
 211    g_test_add_func("/crypto/hash/prealloc", test_hash_prealloc);
 212    g_test_add_func("/crypto/hash/digest", test_hash_digest);
 213    g_test_add_func("/crypto/hash/base64", test_hash_base64);
 214    return g_test_run();
 215}
 216