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