bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi#include "test-lib.h"
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi#include "hash-method.h"
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi#include "hmac.h"
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi#include "sha-common.h"
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi#include "buffer.h"
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvistruct test_vector {
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi const char *prf;
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi const unsigned char *key;
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi size_t key_len;
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi const unsigned char *data;
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi size_t data_len;
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi const unsigned char *res;
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi size_t res_len;
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi};
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi#define TEST_BUF(x) (const unsigned char*)x, sizeof(x)-1
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi/* RFC 4231 test vectors */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvistatic const struct test_vector test_vectors[] = {
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi /* Test Case 1 */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi { "sha256",
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"),
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("Hi There"),
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7")
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi },
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi /* Test Case 2 */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi { "sha256",
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\x4a\x65\x66\x65"), /* "Jefe" */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("what do ya want for nothing?"),
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7\x5a\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43")
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi },
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi /* Test Case 3 */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi { "sha256",
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"),
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe")
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi },
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi /* Test Case 4 */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi { "sha256",
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"),
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08\x3a\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b")
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi },
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi /* Test Case 5 */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi { "sha256",
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"),
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\x54\x65\x73\x74\x20\x57\x69\x74\x68\x20\x54\x72\x75\x6e\x63\x61\x74\x69\x6f\x6e"), /* "Test With Truncation" */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\xa3\xb6\x16\x74\x73\x10\x0e\xe0\x6e\x0c\x79\x6c\x29\x55\x55\x2b")
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi },
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi /* Test Case 6 */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi { "sha256",
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74"), /* "Test Using Larger Than Block-Size Key - Hash Key First" */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54")
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi },
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi /* Test Case 7 */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi { "sha256",
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e"),
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi /* "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." */
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi TEST_BUF("\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2")
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi }
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi};
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvistatic void test_hmac_rfc(void)
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi{
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi test_begin("hmac sha256 rfc4231 vectors");
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi for(size_t i = 0; i < N_ELEMENTS(test_vectors); i++) {
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi const struct test_vector *vec = &(test_vectors[i]);
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi struct hmac_context ctx;
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi hmac_init(&ctx, vec->key, vec->key_len, hash_method_lookup(vec->prf));
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi hmac_update(&ctx, vec->data, vec->data_len);
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi unsigned char res[SHA256_RESULTLEN];
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi hmac_final(&ctx, res);
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi test_assert_idx(memcmp(res, vec->res, vec->res_len) == 0, i);
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi }
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi test_end();
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi}
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomistatic void test_hmac_buffer(void)
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi{
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi const struct test_vector *vec = &(test_vectors[0]);
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi test_begin("hmac temporary buffer");
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi buffer_t *tmp;
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi tmp = t_hmac_data(hash_method_lookup(vec->prf), vec->key, vec->key_len,
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi vec->data, vec->data_len);
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi test_assert(tmp->used == vec->res_len &&
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi memcmp(tmp->data, vec->res, vec->res_len) == 0);
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi test_end();
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi}
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvivoid test_hmac(void)
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi{
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi test_hmac_rfc();
a62b4fb5f0b1577535fa20fc88f4d1ade72070a3Aki Tuomi test_hmac_buffer();
134b5022c0549daef243e2c3220bd0238f396868Martti Rannanjärvi}