/* * Copyright (C) 2016 Nikos Mavrogiannopoulos * Copyright (C) 2017 Red Hat, Inc. * * This file is part of GnuTLS. * * GnuTLS is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * GnuTLS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "utils.h" #if defined(__FreeBSD__) || !defined(HAVE_MMAP) void doit(void) { exit(77); } #else /* working test */ /* Test hashing on very large buffers >= 2^31 */ #if !defined(_WIN32) # include # include static void exit_77(int signo) { _exit(77); } #endif #define MIN(x,y) ((x)<(y))?(x):(y) #include static size_t _mmap_size; static void *get_mem(size_t size) { void *p; _mmap_size = size; p = mmap(NULL, size, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (p == MAP_FAILED) return NULL; return p; } static void put_mem(void *mem) { munmap(mem, _mmap_size); } void doit(void) { unsigned char digest[32]; int err; char *buf, *p; ssize_t size, left, size2; gnutls_hash_hd_t td; if (sizeof(size) <= 4) exit(77); #if !defined(_WIN32) signal(SIGSEGV, exit_77); signal(SIGBUS, exit_77); #endif global_init(); size = (ssize_t)UINT_MAX + (ssize_t)64*1024; buf = get_mem(size); if (buf == NULL) exit(77); if (size < (ssize_t)UINT_MAX) exit(77); err = gnutls_hash_fast(GNUTLS_DIG_SHA256, buf, size, digest); if (err < 0) fail("gnutls_hash_fast(SHA256) failed: %d\n", err); else { #define SHA256_HASH "\x80\x92\xd9\xbe\x54\xa0\xe9\xd7\x7c\xb8\xe4\x2d\xd3\x7c\x19\xfe\x4e\x68\x84\x33\x71\xef\x1c\x81\xd6\x44\x36\x52\x06\xd8\x4b\x8a" if (memcmp(digest, SHA256_HASH, 32) == 0) { if (debug) success("gnutls_hash_fast(SHA256) %lu OK\n", (unsigned long)size); } else { hexprint(digest, 32); fail("gnutls_hash_fast(SHA256) failure\n"); } } err = gnutls_hash_init(&td, GNUTLS_DIG_SHA256); if (err < 0) { fail("failed in %d\n", __LINE__); } size2 = size; p = buf; while(size2 > 0) { left = MIN(64*1024, size2); gnutls_hash(td, p, left); size2 -= left; p += left; } gnutls_hash_output(td, digest); gnutls_hash_deinit(td, NULL); if (memcmp(digest, SHA256_HASH, 32) == 0) { if (debug) success("gnutls_hash_fast(SHA256) %lu OK\n", (unsigned long)size); } else { hexprint(digest, 32); fail("gnutls_hash(SHA256) failure\n"); } /* SHA1 */ err = gnutls_hash_fast(GNUTLS_MAC_SHA1, buf, size, digest); if (err < 0) fail("gnutls_hash_fast(SHA1) failed: %d\n", err); else { #define SHA1_HASH "\x75\xd2\x67\x3f\xec\x73\xe4\x57\xb8\x40\xb3\xb5\xf1\xc7\xa8\x1a\x2d\x11\x7e\xd9" if (memcmp(digest, SHA1_HASH, 20) == 0) { if (debug) success("gnutls_hash_fast(SHA1) OK\n"); } else { hexprint(digest, 20); fail("gnutls_hash_fast(SHA1) failure\n"); } } err = gnutls_hmac_fast(GNUTLS_MAC_SHA1, "keykeykey", 9, buf, size, digest); if (err < 0) fail("gnutls_hmac_fast(SHA1) failed: %d\n", err); else { #define SHA1_MAC "\xe2\xe9\x84\x48\x53\xe3\x0b\xfe\x45\x04\xf6\x6b\x5b\x6d\x4d\x2c\xa3\x0f\xcf\x23" if (memcmp(digest, SHA1_MAC, 20) == 0) { if (debug) success("gnutls_hmac_fast(SHA1) OK\n"); } else { hexprint(digest, 20); fail("gnutls_hmac_fast(SHA1) failure\n"); } } put_mem(buf); gnutls_global_deinit(); } #endif