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