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