Sfoglia il codice sorgente

Support messages that exceed the stack size

Previous code allocated an array on the stack of mlen bytes, but
it should be possible to also sign heap-space messages. By relying
on the fact that sm and m fit the message + signature, we move
the message so that 4*n bytes of prefix can be added.
master
Joost Rijneveld 7 anni fa
parent
commit
384b228c58
Non sono state trovate chiavi note per questa firma nel database ID Chiave GPG: A4FE39CF49CBC553
9 ha cambiato i file con 108 aggiunte e 72 eliminazioni
  1. +45
    -15
      hash.c
  2. +5
    -0
      hash.h
  3. +11
    -3
      test/xmss.c
  4. +6
    -2
      ui/open.c
  5. +8
    -2
      ui/sign.c
  6. +5
    -20
      xmss_commons.c
  7. +0
    -8
      xmss_commons.h
  8. +9
    -7
      xmss_core.c
  9. +19
    -15
      xmss_core_fast.c

+ 45
- 15
hash.c Vedi File

@@ -1,12 +1,13 @@
#include <stdint.h>
#include <string.h>
#include <openssl/sha.h>

#include "hash_address.h"
#include "xmss_commons.h"
#include "params.h"
#include "hash.h"
#include "fips202.h"

#include <stdint.h>
#include <openssl/sha.h>

void addr_to_bytes(unsigned char *bytes, const uint32_t addr[8])
{
int i;
@@ -20,22 +21,13 @@ static int core_hash(const xmss_params *params,
const unsigned char *key, unsigned int keylen,
const unsigned char *in, unsigned long long inlen, int n)
{
unsigned long long i = 0;
unsigned char buf[inlen + n + keylen];

/* We arrange the input into the hash function to be of the form:
* toByte(X, 32) || KEY || M
*/

* toByte(X, 32) || KEY || M */
ull_to_bytes(buf, n, type);

for (i=0; i < keylen; i++) {
buf[i+n] = key[i];
}

for (i=0; i < inlen; i++) {
buf[keylen + n + i] = in[i];
}
memcpy(buf + n, key, keylen);
memcpy(buf + keylen + n, in, inlen);

if (n == 32 && params->func == XMSS_SHA2) {
SHA256(buf, inlen + keylen + n, out);
@@ -70,6 +62,44 @@ int h_msg(const xmss_params *params,
return core_hash(params, out, 2, key, keylen, in, inlen, params->n);
}

/*
* Computes the message hash using R, the public root, the index of the leaf
* node, and the message. Notably, it requires m_with_prefix to have 4*n bytes
* of space before the message, to use for the prefix. This is necessary to
* prevent having to move the message around (and thus allocate memory for it).
*/
int hash_message(const xmss_params *params, unsigned char *out,
const unsigned char *R, const unsigned char *root,
unsigned long long idx,
unsigned char *m_with_prefix, unsigned long long mlen)
{
/* We're creating a hash using input of the form:
toByte(X, 32) || R || root || index || M */
ull_to_bytes(m_with_prefix, params->n, 2);
memcpy(m_with_prefix + params->n, R, params->n);
memcpy(m_with_prefix + 2 * params->n, root, params->n);
ull_to_bytes(m_with_prefix + 3 * params->n, params->n, idx);

/* Since the message can be bigger than the stack, this cannot use the
* core_hash function. */
if (params->n == 32 && params->func == XMSS_SHA2) {
SHA256(m_with_prefix, mlen + 4*params->n, out);
}
else if (params->n == 32 && params->func == XMSS_SHAKE) {
shake128(out, 32, m_with_prefix, mlen + 4*params->n);
}
else if (params->n == 64 && params->func == XMSS_SHA2) {
SHA512(m_with_prefix, mlen + 4*params->n, out);
}
else if (params->n == 64 && params->func == XMSS_SHAKE) {
shake256(out, 64, m_with_prefix, mlen + 4*params->n);
}
else {
return 1;
}
return 0;
}

/**
* We assume the left half is in in[0]...in[n-1]
*/


+ 5
- 0
hash.h Vedi File

@@ -23,4 +23,9 @@ int hash_f(const xmss_params *params,
unsigned char *out, const unsigned char *in,
const unsigned char *pub_seed, uint32_t addr[8]);

int hash_message(const xmss_params *params, unsigned char *out,
const unsigned char *R, const unsigned char *root,
unsigned long long idx,
unsigned char *m_with_prefix, unsigned long long mlen);

#endif

+ 11
- 3
test/xmss.c Vedi File

@@ -1,9 +1,11 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

#include "../xmss.h"
#include "../params.h"
#include "../randombytes.h"

#define MLEN 32
#define SIGNATURES 16
@@ -33,12 +35,14 @@ int main()

unsigned char pk[XMSS_OID_LEN + params.pk_bytes];
unsigned char sk[XMSS_OID_LEN + params.sk_bytes];
unsigned char m[MLEN];
unsigned char sm[params.sig_bytes + MLEN];
unsigned char mout[params.sig_bytes + MLEN];
unsigned char *m = malloc(MLEN);
unsigned char *sm = malloc(params.sig_bytes + MLEN);
unsigned char *mout = malloc(params.sig_bytes + MLEN);
unsigned long long smlen;
unsigned long long mlen;

randombytes(m, MLEN);

XMSS_KEYPAIR(pk, sk, oid);

printf("Testing %d %s signatures.. \n", SIGNATURES, XMSS_VARIANT);
@@ -106,5 +110,9 @@ int main()
}
}

free(m);
free(sm);
free(mout);

return 0;
}

+ 6
- 2
ui/open.c Vedi File

@@ -1,4 +1,5 @@
#include <stdio.h>
#include <stdlib.h>

#include "../params.h"
#include "../xmss.h"
@@ -49,8 +50,8 @@ int main(int argc, char **argv) {
XMSS_PARSE_OID(&params, oid);

unsigned char pk[XMSS_OID_LEN + params.pk_bytes];
unsigned char sm[smlen];
unsigned char m[smlen];
unsigned char *sm = malloc(smlen);
unsigned char *m = malloc(smlen);
unsigned long long mlen;

fseek(keypair_file, 0, SEEK_SET);
@@ -70,5 +71,8 @@ int main(int argc, char **argv) {
fclose(keypair_file);
fclose(sm_file);

free(m);
free(sm);

return ret;
}

+ 8
- 2
ui/sign.c Vedi File

@@ -1,4 +1,5 @@
#include <stdio.h>
#include <stdlib.h>

#include "../params.h"
#include "../xmss.h"
@@ -56,8 +57,8 @@ int main(int argc, char **argv) {
XMSS_PARSE_OID(&params, oid_sk);

unsigned char sk[XMSS_OID_LEN + params.sk_bytes];
unsigned char m[mlen];
unsigned char sm[params.sig_bytes + mlen];
unsigned char *m = malloc(mlen);
unsigned char *sm = malloc(params.sig_bytes + mlen);
unsigned long long smlen;

/* fseek back to start of sk. */
@@ -74,4 +75,9 @@ int main(int argc, char **argv) {

fclose(keypair_file);
fclose(m_file);

free(m);
free(sm);

return 0;
}

+ 5
- 20
xmss_commons.c Vedi File

@@ -115,25 +115,6 @@ void l_tree(const xmss_params *params,
memcpy(leaf, wots_pk, params->n);
}

/**
* Computes the randomized message hash.
*/
void hash_message(const xmss_params *params, unsigned char *mhash,
const unsigned char *R, const unsigned char *root,
unsigned long long idx,
const unsigned char *m, unsigned long long mlen)
{
unsigned char hash_key[3*params->n];

/* Compute hash key. */
memcpy(hash_key, R, params->n);
memcpy(hash_key + params->n, root, params->n);
ull_to_bytes(hash_key + 2*params->n, params->n, idx);

/* Hash the message using the randomized hash key. */
h_msg(params, mhash, m, mlen, hash_key, 3*params->n);
}

/**
* Computes a root node given a leaf and an auth path
*/
@@ -228,9 +209,13 @@ int xmssmt_core_sign_open(const xmss_params *params,
/* Convert the index bytes from the signature to an integer. */
idx = bytes_to_ull(sm, params->index_bytes);

/* Put the message all the way at the end of the m buffer, so that we can
* prepend the required other inputs for the hash function. */
memcpy(m + params->sig_bytes, sm + params->sig_bytes, *mlen);

/* Compute the message hash. */
hash_message(params, mhash, sm + params->index_bytes, pk, idx,
sm + params->sig_bytes, *mlen);
m + params->sig_bytes - 4*params->n, *mlen);
sm += params->index_bytes + params->n;

/* For each subtree.. */


+ 0
- 8
xmss_commons.h Vedi File

@@ -41,14 +41,6 @@ void l_tree(const xmss_params *params,
unsigned char *leaf, unsigned char *wots_pk,
const unsigned char *pub_seed, uint32_t addr[8]);

/**
* Computes the randomized message hash.
*/
void hash_message(const xmss_params *params, unsigned char *mhash,
const unsigned char *R, const unsigned char *root,
unsigned long long idx,
const unsigned char *m, unsigned long long mlen);

/**
* Verifies a given message signature pair under a given public key.
* Note that this assumes a pk without an OID, i.e. [root || PUB_SEED]


+ 9
- 7
xmss_core.c Vedi File

@@ -189,10 +189,14 @@ int xmssmt_core_sign(const xmss_params *params,
uint32_t ots_addr[8] = {0};
set_type(ots_addr, XMSS_ADDR_TYPE_OTS);

/* Already put the message in the right place, to make it easier to prepend
* things when computing the hash over the message. */
memcpy(sm + params->sig_bytes, m, mlen);
*smlen = params->sig_bytes + mlen;

/* Read and use the current index from the secret key. */
idx = (unsigned long)bytes_to_ull(sk, params->index_bytes);
memcpy(sm, sk, params->index_bytes);
sm += params->index_bytes;

/*************************************************************************
* THIS IS WHERE PRODUCTION IMPLEMENTATIONS WOULD UPDATE THE SECRET KEY. *
@@ -202,11 +206,12 @@ int xmssmt_core_sign(const xmss_params *params,

/* Compute the digest randomization value. */
ull_to_bytes(idx_bytes_32, 32, idx);
prf(params, sm, idx_bytes_32, sk_prf, params->n);
prf(params, sm + params->index_bytes, idx_bytes_32, sk_prf, params->n);

/* Compute the message hash. */
hash_message(params, mhash, sm, pub_root, idx, m, mlen);
sm += params->n;
hash_message(params, mhash, sm + params->index_bytes, pub_root, idx,
sm + params->sig_bytes - 4*params->n, mlen);
sm += params->index_bytes + params->n;

set_type(ots_addr, XMSS_ADDR_TYPE_OTS);

@@ -232,8 +237,5 @@ int xmssmt_core_sign(const xmss_params *params,
sm += params->tree_height*params->n;
}

memcpy(sm, m, mlen);
*smlen = params->sig_bytes + mlen;

return 0;
}

+ 19
- 15
xmss_core_fast.c Vedi File

@@ -393,6 +393,8 @@ int xmss_core_sign(const xmss_params *params,
unsigned char *sm, unsigned long long *smlen,
const unsigned char *m, unsigned long long mlen)
{
const unsigned char *pub_root = sk + params->index_bytes + 3*params->n;

uint16_t i = 0;

// Extract SK
@@ -408,8 +410,6 @@ int xmss_core_sign(const xmss_params *params,
unsigned char idx_bytes_32[32];
ull_to_bytes(idx_bytes_32, 32, idx);

unsigned char hash_key[3*params->n];

// Update SK
sk[0] = ((idx + 1) >> 24) & 255;
sk[1] = ((idx + 1) >> 16) & 255;
@@ -432,12 +432,14 @@ int xmss_core_sign(const xmss_params *params,
// Message Hash:
// First compute pseudorandom value
prf(params, R, idx_bytes_32, sk_prf, params->n);
// Generate hash key (R || root || idx)
memcpy(hash_key, R, params->n);
memcpy(hash_key+params->n, sk+4+3*params->n, params->n);
ull_to_bytes(hash_key+2*params->n, params->n, idx);
// Then use it for message digest
h_msg(params, msg_h, m, mlen, hash_key, 3*params->n);

/* Already put the message in the right place, to make it easier to prepend
* things when computing the hash over the message. */
memcpy(sm + params->sig_bytes, m, mlen);

/* Compute the message hash. */
hash_message(params, msg_h, R, pub_root, idx,
sm + params->sig_bytes - 4*params->n, mlen);

// Start collecting signature
*smlen = 0;
@@ -554,6 +556,8 @@ int xmssmt_core_sign(const xmss_params *params,
unsigned char *sm, unsigned long long *smlen,
const unsigned char *m, unsigned long long mlen)
{
const unsigned char *pub_root = sk + params->index_bytes + 3*params->n;

uint64_t idx_tree;
uint32_t idx_leaf;
uint64_t i, j;
@@ -566,7 +570,6 @@ int xmssmt_core_sign(const xmss_params *params,
// Init working params
unsigned char R[params->n];
unsigned char msg_h[params->n];
unsigned char hash_key[3*params->n];
unsigned char ots_seed[params->n];
uint32_t addr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
@@ -599,13 +602,14 @@ int xmssmt_core_sign(const xmss_params *params,
// First compute pseudorandom value
ull_to_bytes(idx_bytes_32, 32, idx);
prf(params, R, idx_bytes_32, sk_prf, params->n);
// Generate hash key (R || root || idx)
memcpy(hash_key, R, params->n);
memcpy(hash_key+params->n, sk+params->index_bytes+3*params->n, params->n);
ull_to_bytes(hash_key+2*params->n, params->n, idx);

// Then use it for message digest
h_msg(params, msg_h, m, mlen, hash_key, 3*params->n);
/* Already put the message in the right place, to make it easier to prepend
* things when computing the hash over the message. */
memcpy(sm + params->sig_bytes, m, mlen);

/* Compute the message hash. */
hash_message(params, msg_h, R, pub_root, idx,
sm + params->sig_bytes - 4*params->n, mlen);

// Start collecting signature
*smlen = 0;


Caricamento…
Annulla
Salva