2 * QEMU Crypto hash algorithms
4 * Copyright (c) 2015 Red Hat, Inc.
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.
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.
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/>.
21 #include "qemu/osdep.h"
23 #include "crypto/init.h"
24 #include "crypto/hash.h"
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"
31 #define OUTPUT_MD5 "628d206371563035ab8ef62f492bdec9"
32 #define OUTPUT_SHA1 "b2e74f26758a3a421e509cee045244b78753cc02"
33 #define OUTPUT_SHA224 "e2f7415aad33ef79f6516b0986d7175f" \
34 "9ca3389a85bf6cfed078737b"
35 #define OUTPUT_SHA256 "bc757abb0436586f392b437e5dd24096" \
36 "f7f224de6b74d4d86e2abc6121b160d0"
37 #define OUTPUT_SHA384 "887ce52efb4f46700376356583b7e279" \
38 "4f612bd024e4495087ddb946c448c69d" \
39 "56dbf7152a94a5e63a80f3ba9f0eed78"
40 #define OUTPUT_SHA512 "3a90d79638235ec6c4c11bebd84d83c0" \
41 "549bc1e84edc4b6ec7086487641256cb" \
42 "63b54e4cb2d2032b393994aa263c0dbb" \
43 "e00a9f2fe9ef6037352232a1eec55ee7"
44 #define OUTPUT_RIPEMD160 "f3d658fad3fdfb2b52c9369cf0d441249ddfa8a0"
46 #define OUTPUT_MD5_B64 "Yo0gY3FWMDWrjvYvSSveyQ=="
47 #define OUTPUT_SHA1_B64 "sudPJnWKOkIeUJzuBFJEt4dTzAI="
48 #define OUTPUT_SHA224_B64 "4vdBWq0z73n2UWsJhtcXX5yjOJqFv2z+0Hhzew=="
49 #define OUTPUT_SHA256_B64 "vHV6uwQ2WG85K0N+XdJAlvfyJN5rdNTYbiq8YSGxYNA="
50 #define OUTPUT_SHA384_B64 "iHzlLvtPRnADdjVlg7fieU9hK9Ak5ElQh925RsRI" \
51 "xp1W2/cVKpSl5jqA87qfDu14"
52 #define OUTPUT_SHA512_B64 "OpDXljgjXsbEwRvr2E2DwFSbwehO3Etuxwhkh2QS" \
53 "VstjtU5MstIDKzk5lKomPA274AqfL+nvYDc1IjKh" \
55 #define OUTPUT_RIPEMD160_B64 "89ZY+tP9+ytSyTac8NRBJJ3fqKA="
57 static const char *expected_outputs
[] = {
58 [QCRYPTO_HASH_ALG_MD5
] = OUTPUT_MD5
,
59 [QCRYPTO_HASH_ALG_SHA1
] = OUTPUT_SHA1
,
60 [QCRYPTO_HASH_ALG_SHA224
] = OUTPUT_SHA224
,
61 [QCRYPTO_HASH_ALG_SHA256
] = OUTPUT_SHA256
,
62 [QCRYPTO_HASH_ALG_SHA384
] = OUTPUT_SHA384
,
63 [QCRYPTO_HASH_ALG_SHA512
] = OUTPUT_SHA512
,
64 [QCRYPTO_HASH_ALG_RIPEMD160
] = OUTPUT_RIPEMD160
,
66 static const char *expected_outputs_b64
[] = {
67 [QCRYPTO_HASH_ALG_MD5
] = OUTPUT_MD5_B64
,
68 [QCRYPTO_HASH_ALG_SHA1
] = OUTPUT_SHA1_B64
,
69 [QCRYPTO_HASH_ALG_SHA224
] = OUTPUT_SHA224_B64
,
70 [QCRYPTO_HASH_ALG_SHA256
] = OUTPUT_SHA256_B64
,
71 [QCRYPTO_HASH_ALG_SHA384
] = OUTPUT_SHA384_B64
,
72 [QCRYPTO_HASH_ALG_SHA512
] = OUTPUT_SHA512_B64
,
73 [QCRYPTO_HASH_ALG_RIPEMD160
] = OUTPUT_RIPEMD160_B64
,
75 static const int expected_lens
[] = {
76 [QCRYPTO_HASH_ALG_MD5
] = 16,
77 [QCRYPTO_HASH_ALG_SHA1
] = 20,
78 [QCRYPTO_HASH_ALG_SHA224
] = 28,
79 [QCRYPTO_HASH_ALG_SHA256
] = 32,
80 [QCRYPTO_HASH_ALG_SHA384
] = 48,
81 [QCRYPTO_HASH_ALG_SHA512
] = 64,
82 [QCRYPTO_HASH_ALG_RIPEMD160
] = 20,
85 static const char hex
[] = "0123456789abcdef";
87 /* Test with dynamic allocation */
88 static void test_hash_alloc(void)
92 for (i
= 0; i
< G_N_ELEMENTS(expected_outputs
) ; i
++) {
93 uint8_t *result
= NULL
;
98 if (!qcrypto_hash_supports(i
)) {
102 ret
= qcrypto_hash_bytes(i
,
109 g_assert(resultlen
== expected_lens
[i
]);
111 for (j
= 0; j
< resultlen
; j
++) {
112 g_assert(expected_outputs
[i
][j
* 2] == hex
[(result
[j
] >> 4) & 0xf]);
113 g_assert(expected_outputs
[i
][j
* 2 + 1] == hex
[result
[j
] & 0xf]);
119 /* Test with caller preallocating */
120 static void test_hash_prealloc(void)
124 for (i
= 0; i
< G_N_ELEMENTS(expected_outputs
) ; i
++) {
130 if (!qcrypto_hash_supports(i
)) {
134 resultlen
= expected_lens
[i
];
135 result
= g_new0(uint8_t, resultlen
);
137 ret
= qcrypto_hash_bytes(i
,
145 g_assert(resultlen
== expected_lens
[i
]);
146 for (j
= 0; j
< resultlen
; j
++) {
147 g_assert(expected_outputs
[i
][j
* 2] == hex
[(result
[j
] >> 4) & 0xf]);
148 g_assert(expected_outputs
[i
][j
* 2 + 1] == hex
[result
[j
] & 0xf]);
155 /* Test with dynamic allocation */
156 static void test_hash_iov(void)
160 for (i
= 0; i
< G_N_ELEMENTS(expected_outputs
) ; i
++) {
161 struct iovec iov
[3] = {
162 { .iov_base
= (char *)INPUT_TEXT1
, .iov_len
= strlen(INPUT_TEXT1
) },
163 { .iov_base
= (char *)INPUT_TEXT2
, .iov_len
= strlen(INPUT_TEXT2
) },
164 { .iov_base
= (char *)INPUT_TEXT3
, .iov_len
= strlen(INPUT_TEXT3
) },
166 uint8_t *result
= NULL
;
167 size_t resultlen
= 0;
171 if (!qcrypto_hash_supports(i
)) {
175 ret
= qcrypto_hash_bytesv(i
,
181 g_assert(resultlen
== expected_lens
[i
]);
182 for (j
= 0; j
< resultlen
; j
++) {
183 g_assert(expected_outputs
[i
][j
* 2] == hex
[(result
[j
] >> 4) & 0xf]);
184 g_assert(expected_outputs
[i
][j
* 2 + 1] == hex
[result
[j
] & 0xf]);
191 /* Test with printable hashing */
192 static void test_hash_digest(void)
196 for (i
= 0; i
< G_N_ELEMENTS(expected_outputs
) ; i
++) {
201 if (!qcrypto_hash_supports(i
)) {
205 digestsize
= qcrypto_hash_digest_len(i
);
207 g_assert_cmpint(digestsize
* 2, ==, strlen(expected_outputs
[i
]));
209 ret
= qcrypto_hash_digest(i
,
215 g_assert_cmpstr(digest
, ==, expected_outputs
[i
]);
220 /* Test with base64 encoding */
221 static void test_hash_base64(void)
225 for (i
= 0; i
< G_N_ELEMENTS(expected_outputs
) ; i
++) {
229 if (!qcrypto_hash_supports(i
)) {
233 ret
= qcrypto_hash_base64(i
,
239 g_assert_cmpstr(digest
, ==, expected_outputs_b64
[i
]);
244 int main(int argc
, char **argv
)
246 g_assert(qcrypto_init(NULL
) == 0);
248 g_test_init(&argc
, &argv
, NULL
);
249 g_test_add_func("/crypto/hash/iov", test_hash_iov
);
250 g_test_add_func("/crypto/hash/alloc", test_hash_alloc
);
251 g_test_add_func("/crypto/hash/prealloc", test_hash_prealloc
);
252 g_test_add_func("/crypto/hash/digest", test_hash_digest
);
253 g_test_add_func("/crypto/hash/base64", test_hash_base64
);