blob: c4cac47fdd67142c8da344184dad751628f5a53f [file] [log] [blame]
markus@openbsd.org1b11ea72018-02-23 15:58:37 +00001/*
2hash.c version 20160722
3Andreas Hülsing
4Joost Rijneveld
5Public domain.
6*/
7
Damien Millerf8854742018-02-26 12:18:14 +11008#include "includes.h"
9
markus@openbsd.org1b11ea72018-02-23 15:58:37 +000010#include "xmss_hash_address.h"
11#include "xmss_commons.h"
12#include "xmss_hash.h"
13
14#include <stddef.h>
Darren Tuckerc7ef4a32018-02-26 17:42:56 +110015#ifdef HAVE_STDINT_H
markus@openbsd.org1b11ea72018-02-23 15:58:37 +000016#include <stdint.h>
Darren Tuckerc7ef4a32018-02-26 17:42:56 +110017#endif
markus@openbsd.org1b11ea72018-02-23 15:58:37 +000018#include <stdio.h>
19#include <string.h>
20#include <openssl/sha.h>
21#include <openssl/hmac.h>
22#include <openssl/evp.h>
23
24int core_hash_SHA2(unsigned char *, const unsigned int, const unsigned char *,
25 unsigned int, const unsigned char *, unsigned long long, unsigned int);
26
27unsigned 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
39int 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 */
72int 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 */
80int 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 */
92int 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
117int 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}