1 /* $NetBSD: xmss_hash.c,v 1.2 2018/04/06 18:59:00 christos Exp $ */ 2 /* $OpenBSD: xmss_hash.c,v 1.2 2018/02/26 03:56:44 dtucker Exp $ */ 3 /* 4 hash.c version 20160722 5 Andreas Hülsing 6 Joost Rijneveld 7 Public domain. 8 */ 9 #include "includes.h" 10 __RCSID("$NetBSD: xmss_hash.c,v 1.2 2018/04/06 18:59:00 christos Exp $"); 11 12 #include "xmss_hash_address.h" 13 #include "xmss_commons.h" 14 #include "xmss_hash.h" 15 16 #include <stddef.h> 17 #include <stdint.h> 18 #include <stdio.h> 19 #include <string.h> 20 #include <openssl/sha.h> 21 #include <openssl/hmac.h> 22 #include <openssl/evp.h> 23 24 int core_hash_SHA2(unsigned char *, const unsigned int, const unsigned char *, 25 unsigned int, const unsigned char *, unsigned long long, unsigned int); 26 27 unsigned char* addr_to_byte(unsigned char *bytes, const uint32_t addr[8]){ 28 #if IS_LITTLE_ENDIAN==1 29 int i = 0; 30 for(i=0;i<8;i++) 31 to_byte(bytes+i*4, addr[i],4); 32 return bytes; 33 #else 34 memcpy(bytes, addr, 32); 35 return bytes; 36 #endif 37 } 38 39 int core_hash_SHA2(unsigned char *out, const unsigned int type, const unsigned char *key, unsigned int keylen, const unsigned char *in, unsigned long long inlen, unsigned int n){ 40 unsigned long long i = 0; 41 unsigned char buf[inlen + n + keylen]; 42 43 // Input is (toByte(X, 32) || KEY || M) 44 45 // set toByte 46 to_byte(buf, type, n); 47 48 for (i=0; i < keylen; i++) { 49 buf[i+n] = key[i]; 50 } 51 52 for (i=0; i < inlen; i++) { 53 buf[keylen + n + i] = in[i]; 54 } 55 56 if (n == 32) { 57 SHA256(buf, inlen + keylen + n, out); 58 return 0; 59 } 60 else { 61 if (n == 64) { 62 SHA512(buf, inlen + keylen + n, out); 63 return 0; 64 } 65 } 66 return 1; 67 } 68 69 /** 70 * Implements PRF 71 */ 72 int prf(unsigned char *out, const unsigned char *in, const unsigned char *key, unsigned int keylen) 73 { 74 return core_hash_SHA2(out, 3, key, keylen, in, 32, keylen); 75 } 76 77 /* 78 * Implemts H_msg 79 */ 80 int h_msg(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *key, const unsigned int keylen, const unsigned int n) 81 { 82 if (keylen != 3*n){ 83 // H_msg takes 3n-bit keys, but n does not match the keylength of keylen 84 return -1; 85 } 86 return core_hash_SHA2(out, 2, key, keylen, in, inlen, n); 87 } 88 89 /** 90 * We assume the left half is in in[0]...in[n-1] 91 */ 92 int hash_h(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n) 93 { 94 95 unsigned char buf[2*n]; 96 unsigned char key[n]; 97 unsigned char bitmask[2*n]; 98 unsigned char byte_addr[32]; 99 unsigned int i; 100 101 setKeyAndMask(addr, 0); 102 addr_to_byte(byte_addr, addr); 103 prf(key, byte_addr, pub_seed, n); 104 // Use MSB order 105 setKeyAndMask(addr, 1); 106 addr_to_byte(byte_addr, addr); 107 prf(bitmask, byte_addr, pub_seed, n); 108 setKeyAndMask(addr, 2); 109 addr_to_byte(byte_addr, addr); 110 prf(bitmask+n, byte_addr, pub_seed, n); 111 for (i = 0; i < 2*n; i++) { 112 buf[i] = in[i] ^ bitmask[i]; 113 } 114 return core_hash_SHA2(out, 1, key, n, buf, 2*n, n); 115 } 116 117 int hash_f(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n) 118 { 119 unsigned char buf[n]; 120 unsigned char key[n]; 121 unsigned char bitmask[n]; 122 unsigned char byte_addr[32]; 123 unsigned int i; 124 125 setKeyAndMask(addr, 0); 126 addr_to_byte(byte_addr, addr); 127 prf(key, byte_addr, pub_seed, n); 128 129 setKeyAndMask(addr, 1); 130 addr_to_byte(byte_addr, addr); 131 prf(bitmask, byte_addr, pub_seed, n); 132 133 for (i = 0; i < n; i++) { 134 buf[i] = in[i] ^ bitmask[i]; 135 } 136 return core_hash_SHA2(out, 0, key, n, buf, n, n); 137 } 138