ARMEBS4  revision-26.06.2015
hash_stm32_md5.c
1 /**
2  * \file heivs/hash_md5.c
3  * \see heivs/hash.h
4  *
5  * Reference code from RFC1321
6  */
7 
8 #include "heivs/hash_stm32_md5.h"
9 #include <stdint.h>
10 #include <string.h>
11 #include <stm32/stm32f4xx_hash.h>
12 #include <stm32/stm32f4xx_rcc.h>
13 #include <heivs/time.h>
14 
15 struct md5_state_t
16 {
17  uint32_t bytes_left;
18  uint8_t buffer[3];
19 };
20 
21 static status_e init(struct heivs_hash_t *hash, void *_state, size_t state_size)
22 {
23  struct md5_state_t *state = (struct md5_state_t *)_state;
24  HASH_InitTypeDef MD5_HASH_InitStructure;
25 
26  (void)hash;
27  (void)state_size;
28  memset(state, 0x0, sizeof(*state));
29 
30  RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE);
31 
32  /**
33  * Check if the HASH device is functional.
34  *
35  * This device is not part of the whole family
36  */
37  HASH->DIN = 0xdeadbeaf;
38  if (HASH->DIN != 0xdeadbeaf)
39  {
40  return ERROR_HW_FAILED;
41  }
42 
43  /* HASH peripheral initialization */
44  HASH_DeInit();
45 
46  /* HASH Configuration */
47  MD5_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_MD5;
48  MD5_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH;
49  MD5_HASH_InitStructure.HASH_DataType = HASH_DataType_8b;
50  HASH_Init(&MD5_HASH_InitStructure);
51 
52  return NO_ERROR;
53 }
54 
55 static status_e run(struct heivs_hash_t *hash, void *_state, const void *_data, size_t size)
56 {
57  struct md5_state_t *state = (struct md5_state_t *)_state;
58  uint32_t i;
59  uint8_t *inputaddr = (uint8_t *)_data;
60 
61  (void)hash;
62  if (state->bytes_left)
63  {
64  /* FIXME : manage the case where data is not input in words... */
65  return ERROR_NOT_YET_IMPLEMENTED;
66  }
67 
68  /* Write the Input block in the IN FIFO */
69  for( i = 0; i < size/4; i++)
70  {
71  HASH_DataIn(*(uint32_t*)inputaddr);
72  inputaddr+=4;
73  }
74 
75  state->bytes_left = size % 4;
76  memcpy(state->buffer, inputaddr, state->bytes_left);
77 
78  return NO_ERROR;
79 }
80 
81 static status_e finish(struct heivs_hash_t *hash, void *_state)
82 {
83  status_e status = NO_ERROR;
84  struct md5_state_t *state = (struct md5_state_t *)_state;
85  uint32_t nbvalidbitsdata;
86  timeout_t timeout;
87  HASH_MsgDigest MD5_MessageDigest;
88  uint32_t outputaddr = (uint32_t)_state;
89 
90  (void)hash;
91  /* Number of valid bits in last word of the Input data */
92  nbvalidbitsdata = 8 * (state->bytes_left % 4);
93 
94  if (state->bytes_left)
95  {
96  uint32_t *data = (uint32_t *)state->buffer;
97  HASH_DataIn(*data);
98  }
99 
100  /* Configure the number of valid bits in last word of the data */
101  HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
102 
103  /* Start the HASH processor */
104  HASH_StartDigest();
105 
106  timeout = time_set_timeout_ms(10);
107  while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET)
108  {
109  if (time_elapsed(timeout))
110  {
111  status = ERROR_TIMEOUT;
112  goto end;
113  }
114  }
115 
116  memset(state, 0x0, sizeof(*state));
117 
118  /* Read the message digest */
119  HASH_GetDigest(&MD5_MessageDigest);
120  *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[0]);
121  outputaddr+=4;
122  *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[1]);
123  outputaddr+=4;
124  *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[2]);
125  outputaddr+=4;
126  *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[3]);
127 
128 end:
129  RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, DISABLE);
130 
131  return status;
132 }
133 
134 
135 struct heivs_hash_t hash_stm32_md5 =
136 {
137  .name = "hash_stm32_md5",
138  .init = init,
139  .run = run,
140  .finish = finish,
141 
142  .state_size = 128/8,
143  .hash_size = 128/8,
144 };
This file contains all the functions prototypes for the RCC firmware library.
No comment.
Definition: error.h:64
#define HASH_FLAG_BUSY
simple time abstraction
void * memcpy(void *dest, const void *src, size_t n)
void * memset(void *dest, int n, size_t n)
uint32_t HASH_AlgoSelection
static uint32_t time_elapsed(timeout_t timeout)
Is this time passed?
Definition: time.h:71
This file contains all the functions prototypes for the HASH firmware library.
#define HASH_AlgoSelection_MD5
#define HASH_AlgoMode_HASH
uint32_t Data[5]
You should check your solder/cables.
Definition: error.h:66
HASH message digest result structure definition.
uint32_t HASH_DataType
Timeout structure.
Definition: time.h:34
timeout_t time_set_timeout_ms(uint32_t ms)
Set an obscure time at least ms milliseconds in the future.
Definition: time.c:15
status_e
Known errors.
Definition: error.h:21
No error.
Definition: error.h:28
HASH Init structure definition.
uint32_t HASH_AlgoMode