xref: /freebsd-src/crypto/openssh/xmss_hash.c (revision a91a246563dffa876a52f53a98de4af9fa364c52)
1*a91a2465SEd Maste /* $OpenBSD: xmss_hash.c,v 1.4 2023/12/20 00:06:25 jsg Exp $ */
247dd1d1bSDag-Erling Smørgrav /*
347dd1d1bSDag-Erling Smørgrav hash.c version 20160722
447dd1d1bSDag-Erling Smørgrav Andreas Hülsing
547dd1d1bSDag-Erling Smørgrav Joost Rijneveld
647dd1d1bSDag-Erling Smørgrav Public domain.
747dd1d1bSDag-Erling Smørgrav */
847dd1d1bSDag-Erling Smørgrav 
947dd1d1bSDag-Erling Smørgrav #include "includes.h"
1047dd1d1bSDag-Erling Smørgrav #ifdef WITH_XMSS
1147dd1d1bSDag-Erling Smørgrav 
1247dd1d1bSDag-Erling Smørgrav #include "xmss_hash_address.h"
1347dd1d1bSDag-Erling Smørgrav #include "xmss_commons.h"
1447dd1d1bSDag-Erling Smørgrav #include "xmss_hash.h"
1547dd1d1bSDag-Erling Smørgrav 
1647dd1d1bSDag-Erling Smørgrav #include <stddef.h>
1747dd1d1bSDag-Erling Smørgrav #ifdef HAVE_STDINT_H
1847dd1d1bSDag-Erling Smørgrav # include <stdint.h>
1947dd1d1bSDag-Erling Smørgrav #endif
2047dd1d1bSDag-Erling Smørgrav #include <stdio.h>
2147dd1d1bSDag-Erling Smørgrav #include <string.h>
2247dd1d1bSDag-Erling Smørgrav 
2347dd1d1bSDag-Erling Smørgrav int core_hash_SHA2(unsigned char *, const unsigned int, const unsigned char *,
2447dd1d1bSDag-Erling Smørgrav     unsigned int, const unsigned char *, unsigned long long, unsigned int);
2547dd1d1bSDag-Erling Smørgrav 
addr_to_byte(unsigned char * bytes,const uint32_t addr[8])2647dd1d1bSDag-Erling Smørgrav unsigned char* addr_to_byte(unsigned char *bytes, const uint32_t addr[8]){
2747dd1d1bSDag-Erling Smørgrav #if IS_LITTLE_ENDIAN==1
2847dd1d1bSDag-Erling Smørgrav   int i = 0;
2947dd1d1bSDag-Erling Smørgrav   for(i=0;i<8;i++)
3047dd1d1bSDag-Erling Smørgrav     to_byte(bytes+i*4, addr[i],4);
3147dd1d1bSDag-Erling Smørgrav   return bytes;
3247dd1d1bSDag-Erling Smørgrav #else
3347dd1d1bSDag-Erling Smørgrav   memcpy(bytes, addr, 32);
3447dd1d1bSDag-Erling Smørgrav   return bytes;
3547dd1d1bSDag-Erling Smørgrav #endif
3647dd1d1bSDag-Erling Smørgrav }
3747dd1d1bSDag-Erling Smørgrav 
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)3847dd1d1bSDag-Erling Smørgrav 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){
3947dd1d1bSDag-Erling Smørgrav   unsigned long long i = 0;
4047dd1d1bSDag-Erling Smørgrav   unsigned char buf[inlen + n + keylen];
4147dd1d1bSDag-Erling Smørgrav 
4247dd1d1bSDag-Erling Smørgrav   // Input is (toByte(X, 32) || KEY || M)
4347dd1d1bSDag-Erling Smørgrav 
4447dd1d1bSDag-Erling Smørgrav   // set toByte
4547dd1d1bSDag-Erling Smørgrav   to_byte(buf, type, n);
4647dd1d1bSDag-Erling Smørgrav 
4747dd1d1bSDag-Erling Smørgrav   for (i=0; i < keylen; i++) {
4847dd1d1bSDag-Erling Smørgrav     buf[i+n] = key[i];
4947dd1d1bSDag-Erling Smørgrav   }
5047dd1d1bSDag-Erling Smørgrav 
5147dd1d1bSDag-Erling Smørgrav   for (i=0; i < inlen; i++) {
5247dd1d1bSDag-Erling Smørgrav     buf[keylen + n + i] = in[i];
5347dd1d1bSDag-Erling Smørgrav   }
5447dd1d1bSDag-Erling Smørgrav 
5547dd1d1bSDag-Erling Smørgrav   if (n == 32) {
5647dd1d1bSDag-Erling Smørgrav     SHA256(buf, inlen + keylen + n, out);
5747dd1d1bSDag-Erling Smørgrav     return 0;
5847dd1d1bSDag-Erling Smørgrav   }
5947dd1d1bSDag-Erling Smørgrav   else {
6047dd1d1bSDag-Erling Smørgrav     if (n == 64) {
6147dd1d1bSDag-Erling Smørgrav       SHA512(buf, inlen + keylen + n, out);
6247dd1d1bSDag-Erling Smørgrav       return 0;
6347dd1d1bSDag-Erling Smørgrav     }
6447dd1d1bSDag-Erling Smørgrav   }
6547dd1d1bSDag-Erling Smørgrav   return 1;
6647dd1d1bSDag-Erling Smørgrav }
6747dd1d1bSDag-Erling Smørgrav 
6847dd1d1bSDag-Erling Smørgrav /**
6947dd1d1bSDag-Erling Smørgrav  * Implements PRF
7047dd1d1bSDag-Erling Smørgrav  */
prf(unsigned char * out,const unsigned char * in,const unsigned char * key,unsigned int keylen)7147dd1d1bSDag-Erling Smørgrav int prf(unsigned char *out, const unsigned char *in, const unsigned char *key, unsigned int keylen)
7247dd1d1bSDag-Erling Smørgrav {
7347dd1d1bSDag-Erling Smørgrav   return core_hash_SHA2(out, 3, key, keylen, in, 32, keylen);
7447dd1d1bSDag-Erling Smørgrav }
7547dd1d1bSDag-Erling Smørgrav 
7647dd1d1bSDag-Erling Smørgrav /*
77*a91a2465SEd Maste  * Implements H_msg
7847dd1d1bSDag-Erling Smørgrav  */
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)7947dd1d1bSDag-Erling Smørgrav 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)
8047dd1d1bSDag-Erling Smørgrav {
8147dd1d1bSDag-Erling Smørgrav   if (keylen != 3*n){
8247dd1d1bSDag-Erling Smørgrav     // H_msg takes 3n-bit keys, but n does not match the keylength of keylen
8347dd1d1bSDag-Erling Smørgrav     return -1;
8447dd1d1bSDag-Erling Smørgrav   }
8547dd1d1bSDag-Erling Smørgrav   return core_hash_SHA2(out, 2, key, keylen, in, inlen, n);
8647dd1d1bSDag-Erling Smørgrav }
8747dd1d1bSDag-Erling Smørgrav 
8847dd1d1bSDag-Erling Smørgrav /**
8947dd1d1bSDag-Erling Smørgrav  * We assume the left half is in in[0]...in[n-1]
9047dd1d1bSDag-Erling Smørgrav  */
hash_h(unsigned char * out,const unsigned char * in,const unsigned char * pub_seed,uint32_t addr[8],const unsigned int n)9147dd1d1bSDag-Erling Smørgrav int hash_h(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n)
9247dd1d1bSDag-Erling Smørgrav {
9347dd1d1bSDag-Erling Smørgrav 
9447dd1d1bSDag-Erling Smørgrav   unsigned char buf[2*n];
9547dd1d1bSDag-Erling Smørgrav   unsigned char key[n];
9647dd1d1bSDag-Erling Smørgrav   unsigned char bitmask[2*n];
9747dd1d1bSDag-Erling Smørgrav   unsigned char byte_addr[32];
9847dd1d1bSDag-Erling Smørgrav   unsigned int i;
9947dd1d1bSDag-Erling Smørgrav 
10047dd1d1bSDag-Erling Smørgrav   setKeyAndMask(addr, 0);
10147dd1d1bSDag-Erling Smørgrav   addr_to_byte(byte_addr, addr);
10247dd1d1bSDag-Erling Smørgrav   prf(key, byte_addr, pub_seed, n);
10347dd1d1bSDag-Erling Smørgrav   // Use MSB order
10447dd1d1bSDag-Erling Smørgrav   setKeyAndMask(addr, 1);
10547dd1d1bSDag-Erling Smørgrav   addr_to_byte(byte_addr, addr);
10647dd1d1bSDag-Erling Smørgrav   prf(bitmask, byte_addr, pub_seed, n);
10747dd1d1bSDag-Erling Smørgrav   setKeyAndMask(addr, 2);
10847dd1d1bSDag-Erling Smørgrav   addr_to_byte(byte_addr, addr);
10947dd1d1bSDag-Erling Smørgrav   prf(bitmask+n, byte_addr, pub_seed, n);
11047dd1d1bSDag-Erling Smørgrav   for (i = 0; i < 2*n; i++) {
11147dd1d1bSDag-Erling Smørgrav     buf[i] = in[i] ^ bitmask[i];
11247dd1d1bSDag-Erling Smørgrav   }
11347dd1d1bSDag-Erling Smørgrav   return core_hash_SHA2(out, 1, key, n, buf, 2*n, n);
11447dd1d1bSDag-Erling Smørgrav }
11547dd1d1bSDag-Erling Smørgrav 
hash_f(unsigned char * out,const unsigned char * in,const unsigned char * pub_seed,uint32_t addr[8],const unsigned int n)11647dd1d1bSDag-Erling Smørgrav int hash_f(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n)
11747dd1d1bSDag-Erling Smørgrav {
11847dd1d1bSDag-Erling Smørgrav   unsigned char buf[n];
11947dd1d1bSDag-Erling Smørgrav   unsigned char key[n];
12047dd1d1bSDag-Erling Smørgrav   unsigned char bitmask[n];
12147dd1d1bSDag-Erling Smørgrav   unsigned char byte_addr[32];
12247dd1d1bSDag-Erling Smørgrav   unsigned int i;
12347dd1d1bSDag-Erling Smørgrav 
12447dd1d1bSDag-Erling Smørgrav   setKeyAndMask(addr, 0);
12547dd1d1bSDag-Erling Smørgrav   addr_to_byte(byte_addr, addr);
12647dd1d1bSDag-Erling Smørgrav   prf(key, byte_addr, pub_seed, n);
12747dd1d1bSDag-Erling Smørgrav 
12847dd1d1bSDag-Erling Smørgrav   setKeyAndMask(addr, 1);
12947dd1d1bSDag-Erling Smørgrav   addr_to_byte(byte_addr, addr);
13047dd1d1bSDag-Erling Smørgrav   prf(bitmask, byte_addr, pub_seed, n);
13147dd1d1bSDag-Erling Smørgrav 
13247dd1d1bSDag-Erling Smørgrav   for (i = 0; i < n; i++) {
13347dd1d1bSDag-Erling Smørgrav     buf[i] = in[i] ^ bitmask[i];
13447dd1d1bSDag-Erling Smørgrav   }
13547dd1d1bSDag-Erling Smørgrav   return core_hash_SHA2(out, 0, key, n, buf, n, n);
13647dd1d1bSDag-Erling Smørgrav }
13747dd1d1bSDag-Erling Smørgrav #endif /* WITH_XMSS */
138