xmss_hash.c 3.4 KB

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