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