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