Updage from NeuG 0.11

This commit is contained in:
NIIBE Yutaka
2013-09-25 13:39:33 +09:00
parent fae8c726b1
commit 8dc4022944
5 changed files with 329 additions and 178 deletions

View File

@@ -1,5 +1,8 @@
2013-09-25 Niibe Yutaka <gniibe@fsij.org>
* src/sha256.h, src/adc.h
* src/neug.c, src/adc_stm32f103.c: Update from NeuG 0.11.
* chopstx: Upgrade to new Chopstx 0.00.
* VERSION: New file.

View File

@@ -8,6 +8,9 @@ void adc_start (void);
void adc_stop (void);
#define ADC_SAMPLE_MODE 0
#define ADC_CRC32_MODE 1
void adc_start_conversion (int mode, uint32_t *p, int size);
void adc_wait (chopstx_intr_t *intr);
#define ADC_CRC32_MODE 1
extern uint32_t adc_buf[64];
void adc_start_conversion (int offset, int count);
int adc_wait_completion (chopstx_intr_t *intr);

View File

@@ -1,5 +1,7 @@
/*
* adc_stm32f103.c - ADC driver for STM32F103
* In this ADC driver, there are NeuG specific parts.
* You need to modify to use this as generic ADC driver.
*
* Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
@@ -75,17 +77,11 @@
#endif
#define NEUG_DMA_CHANNEL STM32_DMA1_STREAM1
#define NEUG_DMA_MODE_SAMPLE \
#define NEUG_DMA_MODE \
( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
| STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
| STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE \
| STM32_DMA_CR_TEIE)
#define NEUG_DMA_MODE_CRC32 \
( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
| STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
| STM32_DMA_CR_MINC \
| STM32_DMA_CR_TCIE | STM32_DMA_CR_TEIE)
| STM32_DMA_CR_TEIE )
#define NEUG_ADC_SETTING1_SMPR1 ADC_SMPR1_SMP_VREF(ADC_SAMPLE_VREF) \
| ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_SENSOR)
@@ -167,71 +163,54 @@ void adc_start (void)
ADC2->SQR3 = NEUG_ADC_SETTING2_SQR3;
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
/*
* We could just let ADC run continuously always and only enable DMA
* to receive stable data from ADC. But our purpose is not to get
* correct data but noise. In fact, we can get more noise when we
* start/stop ADC each time.
*/
ADC2->CR2 = 0;
ADC1->CR2 = 0;
#else
/* Start conversion. */
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
#endif
}
static int adc_mode;
static uint32_t *adc_ptr;
static int adc_size;
static uint32_t adc_buf[64];
uint32_t adc_buf[64];
static void adc_start_conversion_internal (void)
void adc_start_conversion (int offset, int count)
{
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
DMA1_Channel1->CMAR = (uint32_t)&adc_buf[offset]; /* SetMemory0 */
DMA1_Channel1->CNDTR = count; /* Counter */
DMA1_Channel1->CCR = NEUG_DMA_MODE | DMA_CCR1_EN; /* Mode */
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
/* Power on */
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
/* Start conversion. tSTAB is 1uS, but we don't follow the spec. */
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
#else
/*
* Start conversion. tSTAB is 1uS, but we don't follow the spec, to
* get more noise.
*/
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
#endif
}
void adc_start_conversion (int mode, uint32_t *p, int size)
{
adc_mode = mode;
adc_ptr = p;
adc_size = size;
if (mode == ADC_SAMPLE_MODE)
{
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
DMA1_Channel1->CMAR = (uint32_t)p; /* SetMemory0 */
DMA1_Channel1->CNDTR = (uint32_t)size / 4; /* counter */
DMA1_Channel1->CCR = NEUG_DMA_MODE_SAMPLE; /*mode*/
DMA1_Channel1->CCR |= DMA_CCR1_EN; /* Enable */
}
else
{
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
DMA1_Channel1->CMAR = (uint32_t)adc_buf; /* SetMemory0 */
DMA1_Channel1->CNDTR = size; /* counter */
DMA1_Channel1->CCR = NEUG_DMA_MODE_CRC32; /*mode*/
DMA1_Channel1->CCR |= DMA_CCR1_EN; /* Enable */
}
adc_start_conversion_internal ();
}
static void adc_stop_conversion (void)
{
DMA1_Channel1->CCR &= ~DMA_CCR1_EN;
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
ADC1->CR2 = 0;
ADC2->CR2 = 0;
#else
ADC2->CR2 &= ~ADC_CR2_CONT;
ADC1->CR2 &= ~ADC_CR2_CONT;
ADC1->CR2 = 0;
#endif
}
@@ -248,43 +227,46 @@ void adc_stop (void)
}
static void adc_lld_serve_rx_interrupt (uint32_t flags)
{
if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */
{
/* Should never happened. If any, it's coding error. */
/* Access an unmapped address space or alignment violation. */
adc_stop_conversion ();
}
else
{
if ((flags & STM32_DMA_ISR_TCIF) != 0) /* Transfer complete */
{
adc_stop_conversion ();
static uint32_t adc_err;
if (adc_mode != ADC_SAMPLE_MODE)
{
int i;
for (i = 0; i < adc_size;)
{
CRC->DR = adc_buf[i++];
CRC->DR = adc_buf[i++];
CRC->DR = adc_buf[i++];
CRC->DR = adc_buf[i++];
*adc_ptr++ = CRC->DR;
}
}
}
}
}
void adc_wait (chopstx_intr_t *intr)
/*
* Return 0 on success.
* Return 1 on error.
*/
int adc_wait_completion (chopstx_intr_t *intr)
{
uint32_t flags;
chopstx_intr_wait (intr);
flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause. */
DMA1->IFCR = STM32_DMA_ISR_MASK; /* Clear interrupt of channel 1. */
adc_lld_serve_rx_interrupt (flags);
while (1)
{
chopstx_intr_wait (intr);
flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause. */
/*
* Clear interrupt cause of channel 1.
*
* Note that CGIFx=0, as CGIFx=1 clears all of GIF, HTIF, TCIF
* and TEIF.
*/
DMA1->IFCR = (flags & ~1);
if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */
{
/* Should never happened. If any, it's coding error. */
/* Access an unmapped address space or alignment violation. */
adc_err++;
adc_stop_conversion ();
return 1;
}
else if ((flags & STM32_DMA_ISR_TCIF) != 0) /* Transfer complete */
{
adc_stop_conversion ();
return 0;
}
/*
* Even if STM32_DMA_CR_HTIE is unset, we come here with HTIF=1,
* with unknown reason. Just ignore the interrupt by HTIF to
* continue more data.
*/
}
}

View File

@@ -41,8 +41,6 @@ static chopstx_cond_t mode_cond;
#define INTR_REQ_DMA1_Channel1 11
static uint32_t adc_buf[SHA256_BLOCK_SIZE/sizeof (uint32_t)];
static sha256_context sha256_ctx_data;
static uint32_t sha256_output[SHA256_DIGEST_SIZE/sizeof (uint32_t)];
@@ -87,16 +85,37 @@ static uint32_t sha256_output[SHA256_DIGEST_SIZE/sizeof (uint32_t)];
static uint8_t ep_round;
static void noise_source_continuous_test (uint8_t noise);
static void noise_source_continuous_test_word (uint8_t b0, uint8_t b1,
uint8_t b2, uint8_t b3);
/*
* Hash_df initial string:
*
* 1, : counter = 1
* 0, 0, 1, 0 : no_of_bits_returned (in big endian)
* Initial five bytes are:
* 1, : counter = 1
* 0, 0, 1, 0 : no_of_bits_returned (in big endian)
*
* Then, three-byte from noise source follows.
*
* One-byte was used in the previous turn, and we have three bytes in
* CRC->DR.
*/
static void ep_fill_initial_string (void)
{
adc_buf[0] = 0x01000001; /* Regardless of endian */
adc_buf[1] = (CRC->DR & 0xffffff00);
uint32_t v = CRC->DR;
uint8_t b1, b2, b3;
b3 = v >> 24;
b2 = v >> 16;
b1 = v >> 8;
noise_source_continuous_test (b1);
noise_source_continuous_test (b2);
noise_source_continuous_test (b3);
adc_buf[0] = 0x01000001;
adc_buf[1] = (v & 0xffffff00);
}
static void ep_init (int mode)
@@ -104,28 +123,24 @@ static void ep_init (int mode)
if (mode == NEUG_MODE_RAW)
{
ep_round = EP_ROUND_RAW;
adc_start_conversion (ADC_CRC32_MODE, adc_buf, EP_ROUND_RAW_INPUTS);
adc_start_conversion (0, EP_ROUND_RAW_INPUTS);
}
else if (mode == NEUG_MODE_RAW_DATA)
{
ep_round = EP_ROUND_RAW_DATA;
adc_start_conversion (ADC_SAMPLE_MODE, adc_buf, EP_ROUND_RAW_DATA_INPUTS);
adc_start_conversion (0, EP_ROUND_RAW_DATA_INPUTS / 4);
}
else
{
ep_round = EP_ROUND_0;
ep_fill_initial_string ();
adc_start_conversion (ADC_CRC32_MODE,
&adc_buf[2], EP_ROUND_0_INPUTS);
adc_start_conversion (2, EP_ROUND_0_INPUTS);
}
}
static void noise_source_continuous_test (uint8_t noise);
static void ep_fill_wbuf (int i, int flip, int test)
static void ep_fill_wbuf_v (int i, int test, uint32_t v)
{
uint32_t v = adc_buf[i];
if (test)
{
uint8_t b0, b1, b2, b3;
@@ -135,27 +150,94 @@ static void ep_fill_wbuf (int i, int flip, int test)
b1 = v >> 8;
b0 = v;
noise_source_continuous_test (b0);
noise_source_continuous_test (b1);
noise_source_continuous_test (b2);
noise_source_continuous_test (b3);
noise_source_continuous_test_word (b0, b1, b2, b3);
}
if (flip)
v = __builtin_bswap32 (v);
sha256_ctx_data.wbuf[i] = v;
}
/* Here assumes little endian architecture. */
/* Here, we assume a little endian architecture. */
static int ep_process (int mode)
{
int i, n;
uint32_t v;
if (ep_round == EP_ROUND_RAW)
if (ep_round == EP_ROUND_0)
{
sha256_start (&sha256_ctx_data);
sha256_ctx_data.wbuf[0] = adc_buf[0];
sha256_ctx_data.wbuf[1] = adc_buf[1];
for (i = 0; i < EP_ROUND_0_INPUTS / 4; i++)
{
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
CRC->DR = adc_buf[i*4 + 4];
CRC->DR = adc_buf[i*4 + 5];
v = CRC->DR;
ep_fill_wbuf_v (i+2, 1, v);
}
adc_start_conversion (0, EP_ROUND_1_INPUTS);
sha256_process (&sha256_ctx_data);
ep_round++;
return 0;
}
else if (ep_round == EP_ROUND_1)
{
for (i = 0; i < EP_ROUND_1_INPUTS / 4; i++)
{
CRC->DR = adc_buf[i*4];
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR;
ep_fill_wbuf_v (i, 1, v);
}
adc_start_conversion (0, EP_ROUND_2_INPUTS + 3);
sha256_process (&sha256_ctx_data);
ep_round++;
return 0;
}
else if (ep_round == EP_ROUND_2)
{
for (i = 0; i < EP_ROUND_2_INPUTS / 4; i++)
{
CRC->DR = adc_buf[i*4];
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR;
ep_fill_wbuf_v (i, 1, v);
}
CRC->DR = adc_buf[i*4];
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR & 0xff;
noise_source_continuous_test (v);
sha256_ctx_data.wbuf[i] = v;
ep_init (NEUG_MODE_CONDITIONED); /* The rest three-byte of
CRC->DR is used here. */
n = SHA256_DIGEST_SIZE / 2;
memcpy (((uint8_t *)sha256_ctx_data.wbuf) + EP_ROUND_2_INPUTS,
sha256_output, n);
sha256_ctx_data.total[0] = 5 + NUM_NOISE_INPUTS + n;
sha256_finish (&sha256_ctx_data, (uint8_t *)sha256_output);
return SHA256_DIGEST_SIZE / sizeof (uint32_t);
}
else if (ep_round == EP_ROUND_RAW)
{
for (i = 0; i < EP_ROUND_RAW_INPUTS / 4; i++)
ep_fill_wbuf (i, 0, 1);
{
CRC->DR = adc_buf[i*4];
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR;
ep_fill_wbuf_v (i, 1, v);
}
ep_init (mode);
return EP_ROUND_RAW_INPUTS / 4;
@@ -163,47 +245,16 @@ static int ep_process (int mode)
else if (ep_round == EP_ROUND_RAW_DATA)
{
for (i = 0; i < EP_ROUND_RAW_DATA_INPUTS / 4; i++)
ep_fill_wbuf (i, 0, 0);
{
v = adc_buf[i];
ep_fill_wbuf_v (i, 0, v);
}
ep_init (mode);
return EP_ROUND_RAW_DATA_INPUTS / 4;
}
if (ep_round == EP_ROUND_0)
{
for (i = 0; i < 64 / 4; i++)
ep_fill_wbuf (i, 1, 1);
adc_start_conversion (ADC_CRC32_MODE, adc_buf, EP_ROUND_1_INPUTS);
sha256_start (&sha256_ctx_data);
sha256_process (&sha256_ctx_data);
ep_round++;
return 0;
}
else if (ep_round == EP_ROUND_1)
{
for (i = 0; i < 64 / 4; i++)
ep_fill_wbuf (i, 1, 1);
adc_start_conversion (ADC_CRC32_MODE, adc_buf, EP_ROUND_2_INPUTS);
sha256_process (&sha256_ctx_data);
ep_round++;
return 0;
}
else
{
for (i = 0; i < (EP_ROUND_2_INPUTS + 3) / 4; i++)
ep_fill_wbuf (i, 0, 1);
n = SHA256_DIGEST_SIZE / 2;
ep_init (NEUG_MODE_CONDITIONED); /* The three-byte is used here. */
memcpy (((uint8_t *)sha256_ctx_data.wbuf)
+ ((NUM_NOISE_INPUTS+5)%SHA256_BLOCK_SIZE),
sha256_output, n); /* Don't use the last three-byte. */
sha256_ctx_data.total[0] = 5 + NUM_NOISE_INPUTS + n;
sha256_finish (&sha256_ctx_data, (uint8_t *)sha256_output);
return SHA256_DIGEST_SIZE / sizeof (uint32_t);
}
return 0;
}
@@ -289,6 +340,47 @@ static void repetition_count_test (uint8_t sample)
}
}
static void repetition_count_test_word (uint8_t b0, uint8_t b1,
uint8_t b2, uint8_t b3)
{
if (rct_a == b0)
rct_b++;
else
{
rct_a = b0;
rct_b = 1;
}
if (rct_a == b1)
rct_b++;
else
{
rct_a = b1;
rct_b = 1;
}
if (rct_a == b2)
rct_b++;
else
{
rct_a = b2;
rct_b = 1;
}
if (rct_a == b3)
rct_b++;
else
{
rct_a = b3;
rct_b = 1;
}
if (rct_b >= REPITITION_COUNT_TEST_CUTOFF)
noise_source_error (REPETITION_COUNT);
if (rct_b > neug_rc_max)
neug_rc_max = rct_b;
}
/* Cuttoff = 18, when min-entropy = 4.2, W= 2^-30 */
/* With R, qbinom(1-2^-30,64,2^-4.2) */
#define ADAPTIVE_PROPORTION_64_TEST_CUTOFF 18
@@ -299,24 +391,53 @@ static uint8_t ap64t_s;
static void adaptive_proportion_64_test (uint8_t sample)
{
if (ap64t_s >= 64)
if (ap64t_s++ >= 64)
{
ap64t_a = sample;
ap64t_s = 0;
ap64t_s = 1;
ap64t_b = 0;
}
else
if (ap64t_a == sample)
{
ap64t_b++;
if (ap64t_b > ADAPTIVE_PROPORTION_64_TEST_CUTOFF)
noise_source_error (ADAPTIVE_PROPORTION_64);
if (ap64t_b > neug_p64_max)
neug_p64_max = ap64t_b;
}
}
static void adaptive_proportion_64_test_word (uint8_t b0, uint8_t b1,
uint8_t b2, uint8_t b3)
{
if (ap64t_s >= 64)
{
ap64t_a = b0;
ap64t_s = 4;
ap64t_b = 0;
}
else
{
ap64t_s++;
if (ap64t_a == sample)
{
ap64t_b++;
if (ap64t_b > ADAPTIVE_PROPORTION_64_TEST_CUTOFF)
noise_source_error (ADAPTIVE_PROPORTION_64);
if (ap64t_b > neug_p64_max)
neug_p64_max = ap64t_b;
}
ap64t_s += 4;
if (ap64t_a == b0)
ap64t_b++;
}
if (ap64t_a == b1)
ap64t_b++;
if (ap64t_a == b2)
ap64t_b++;
if (ap64t_a == b3)
ap64t_b++;
if (ap64t_b > ADAPTIVE_PROPORTION_64_TEST_CUTOFF)
noise_source_error (ADAPTIVE_PROPORTION_64);
if (ap64t_b > neug_p64_max)
neug_p64_max = ap64t_b;
}
/* Cuttoff = 315, when min-entropy = 4.2, W= 2^-30 */
@@ -329,32 +450,70 @@ static uint16_t ap4096t_s;
static void adaptive_proportion_4096_test (uint8_t sample)
{
if (ap4096t_s >= 4096)
if (ap4096t_s++ >= 4096)
{
ap4096t_a = sample;
ap4096t_s = 0;
ap4096t_s = 1;
ap4096t_b = 0;
}
else
if (ap4096t_a == sample)
{
ap4096t_b++;
if (ap4096t_b > ADAPTIVE_PROPORTION_4096_TEST_CUTOFF)
noise_source_error (ADAPTIVE_PROPORTION_4096);
if (ap4096t_b > neug_p4k_max)
neug_p4k_max = ap4096t_b;
}
}
static void adaptive_proportion_4096_test_word (uint8_t b0, uint8_t b1,
uint8_t b2, uint8_t b3)
{
if (ap4096t_s >= 4096)
{
ap4096t_a = b0;
ap4096t_s = 4;
ap4096t_b = 0;
}
else
{
ap4096t_s++;
if (ap4096t_a == sample)
{
ap4096t_b++;
if (ap4096t_b > ADAPTIVE_PROPORTION_4096_TEST_CUTOFF)
noise_source_error (ADAPTIVE_PROPORTION_4096);
if (ap4096t_b > neug_p4k_max)
neug_p4k_max = ap4096t_b;
}
ap4096t_s += 4;
if (ap4096t_a == b0)
ap4096t_b++;
}
if (ap4096t_a == b1)
ap4096t_b++;
if (ap4096t_a == b2)
ap4096t_b++;
if (ap4096t_a == b3)
ap4096t_b++;
if (ap4096t_b > ADAPTIVE_PROPORTION_4096_TEST_CUTOFF)
noise_source_error (ADAPTIVE_PROPORTION_4096);
if (ap4096t_b > neug_p4k_max)
neug_p4k_max = ap4096t_b;
}
static void noise_source_continuous_test (uint8_t noise)
{
repetition_count_test (noise);
adaptive_proportion_64_test (noise);
adaptive_proportion_4096_test (noise);
}
static void noise_source_continuous_test_word (uint8_t b0, uint8_t b1,
uint8_t b2, uint8_t b3)
{
repetition_count_test_word (b0, b1, b2, b3);
adaptive_proportion_64_test_word (b0, b1, b2, b3);
adaptive_proportion_4096_test_word (b0, b1, b2, b3);
}
/*
* Ring buffer, filled by generator, consumed by neug_get routine.
@@ -431,12 +590,13 @@ rng (void *arg)
ep_init (mode);
while (!rng_should_terminate)
{
int err;
int n;
adc_wait (&adc_intr);
err = adc_wait_completion (&adc_intr);
chopstx_mutex_lock (&mode_mtx);
if (mode != neug_mode)
if (err || mode != neug_mode)
{
mode = neug_mode;
@@ -445,8 +605,11 @@ rng (void *arg)
/* Discarding data available, re-initiate from the start. */
ep_init (mode);
chopstx_cond_signal (&mode_cond);
chopstx_mutex_unlock (&mode_mtx);
continue;
}
chopstx_mutex_unlock (&mode_mtx);
else
chopstx_mutex_unlock (&mode_mtx);
if ((n = ep_process (mode)))
{

View File

@@ -8,10 +8,10 @@ typedef struct
uint32_t wbuf[16];
} sha256_context;
extern void sha256 (const unsigned char *input, unsigned int ilen,
unsigned char output[32]);
extern void sha256_start (sha256_context *ctx);
extern void sha256_finish (sha256_context *ctx, unsigned char output[32]);
extern void sha256_update (sha256_context *ctx, const unsigned char *input,
unsigned int ilen);
extern void sha256_process (sha256_context *ctx);
void sha256 (const unsigned char *input, unsigned int ilen,
unsigned char output[32]);
void sha256_start (sha256_context *ctx);
void sha256_finish (sha256_context *ctx, unsigned char output[32]);
void sha256_update (sha256_context *ctx, const unsigned char *input,
unsigned int ilen);
void sha256_process (sha256_context *ctx);