1 /**************************** usha.c ***************************/
2 /***************** See RFC 6234 for details. *******************/
3 /* Copyright (c) 2011 IETF Trust and the persons identified as */
4 /* authors of the code.  All rights reserved.                  */
5 /* See sha.h for terms of use and redistribution.              */
6 
7 /*
8  *  Description:
9  *     This file implements a unified interface to the SHA algorithms.
10  */
11 
12 #include "sha.h"
13 
14 /*
15  *  USHAReset
16  *
17  *  Description:
18  *      This function will initialize the SHA Context in preparation
19  *      for computing a new SHA message digest.
20  *
21  *  Parameters:
22  *      context: [in/out]
23  *          The context to reset.
24  *      whichSha: [in]
25  *          Selects which SHA reset to call
26  *
27  *  Returns:
28  *      sha Error Code.
29  *
30  */
USHAReset(USHAContext * context,enum SHAversion whichSha)31 int USHAReset(USHAContext *context, enum SHAversion whichSha)
32 {
33   if (!context) return shaNull;
34   context->whichSha = whichSha;
35   switch (whichSha) {
36     case SHA1:   return SHA1Reset((SHA1Context*)&context->ctx);
37     case SHA224: return SHA224Reset((SHA224Context*)&context->ctx);
38     case SHA256: return SHA256Reset((SHA256Context*)&context->ctx);
39     case SHA384: return SHA384Reset((SHA384Context*)&context->ctx);
40     case SHA512: return SHA512Reset((SHA512Context*)&context->ctx);
41     default: return shaBadParam;
42   }
43 }
44 
45 /*
46  *  USHAInput
47  *
48  *  Description:
49  *      This function accepts an array of octets as the next portion
50  *      of the message.
51  *
52  *  Parameters:
53  *      context: [in/out]
54  *          The SHA context to update.
55  *      message_array: [in]
56  *          An array of octets representing the next portion of
57  *          the message.
58  *      length: [in]
59  *          The length of the message in message_array.
60  *
61  *  Returns:
62  *      sha Error Code.
63  *
64  */
USHAInput(USHAContext * context,const uint8_t * bytes,unsigned int bytecount)65 int USHAInput(USHAContext *context,
66               const uint8_t *bytes, unsigned int bytecount)
67 {
68   if (!context) return shaNull;
69   switch (context->whichSha) {
70     case SHA1:
71       return SHA1Input((SHA1Context*)&context->ctx, bytes,
72                        bytecount);
73     case SHA224:
74       return SHA224Input((SHA224Context*)&context->ctx, bytes,
75           bytecount);
76     case SHA256:
77       return SHA256Input((SHA256Context*)&context->ctx, bytes,
78           bytecount);
79     case SHA384:
80       return SHA384Input((SHA384Context*)&context->ctx, bytes,
81           bytecount);
82     case SHA512:
83       return SHA512Input((SHA512Context*)&context->ctx, bytes,
84           bytecount);
85     default: return shaBadParam;
86   }
87 }
88 
89 /*
90  * USHAFinalBits
91  *
92  * Description:
93  *   This function will add in any final bits of the message.
94  *
95  * Parameters:
96  *   context: [in/out]
97  *     The SHA context to update.
98  *   message_bits: [in]
99  *     The final bits of the message, in the upper portion of the
100  *     byte.  (Use 0b###00000 instead of 0b00000### to input the
101  *     three bits ###.)
102  *   length: [in]
103  *     The number of bits in message_bits, between 1 and 7.
104  *
105  * Returns:
106  *   sha Error Code.
107  */
USHAFinalBits(USHAContext * context,uint8_t bits,unsigned int bit_count)108 int USHAFinalBits(USHAContext *context,
109                   uint8_t bits, unsigned int bit_count)
110 {
111   if (!context) return shaNull;
112   switch (context->whichSha) {
113     case SHA1:
114       return SHA1FinalBits((SHA1Context*)&context->ctx, bits,
115                            bit_count);
116     case SHA224:
117       return SHA224FinalBits((SHA224Context*)&context->ctx, bits,
118           bit_count);
119     case SHA256:
120       return SHA256FinalBits((SHA256Context*)&context->ctx, bits,
121           bit_count);
122     case SHA384:
123       return SHA384FinalBits((SHA384Context*)&context->ctx, bits,
124           bit_count);
125     case SHA512:
126       return SHA512FinalBits((SHA512Context*)&context->ctx, bits,
127           bit_count);
128     default: return shaBadParam;
129   }
130 }
131 
132 /*
133  * USHAResult
134  *
135  * Description:
136  *   This function will return the message digest of the appropriate
137  *   bit size, as returned by USHAHashSizeBits(whichSHA) for the
138  *   'whichSHA' value used in the preceding call to USHAReset,
139  *   into the Message_Digest array provided by the caller.
140  *
141  * Parameters:
142  *   context: [in/out]
143  *     The context to use to calculate the SHA-1 hash.
144  *   Message_Digest: [out]
145  *     Where the digest is returned.
146  *
147  * Returns:
148  *   sha Error Code.
149  *
150  */
USHAResult(USHAContext * context,uint8_t Message_Digest[USHAMaxHashSize])151 int USHAResult(USHAContext *context,
152                uint8_t Message_Digest[USHAMaxHashSize])
153 {
154   if (!context) return shaNull;
155   switch (context->whichSha) {
156     case SHA1:
157       return SHA1Result((SHA1Context*)&context->ctx, Message_Digest);
158     case SHA224:
159       return SHA224Result((SHA224Context*)&context->ctx,
160                           Message_Digest);
161     case SHA256:
162       return SHA256Result((SHA256Context*)&context->ctx,
163                           Message_Digest);
164     case SHA384:
165       return SHA384Result((SHA384Context*)&context->ctx,
166                           Message_Digest);
167     case SHA512:
168       return SHA512Result((SHA512Context*)&context->ctx,
169                           Message_Digest);
170     default: return shaBadParam;
171   }
172 }
173 
174 /*
175  * USHABlockSize
176  *
177  * Description:
178  *   This function will return the blocksize for the given SHA
179  *   algorithm.
180  *
181  * Parameters:
182  *   whichSha:
183  *     which SHA algorithm to query
184  *
185  * Returns:
186  *   block size
187  *
188  */
USHABlockSize(enum SHAversion whichSha)189 int USHABlockSize(enum SHAversion whichSha)
190 {
191   switch (whichSha) {
192     case SHA1:   return SHA1_Message_Block_Size;
193     case SHA224: return SHA224_Message_Block_Size;
194     case SHA256: return SHA256_Message_Block_Size;
195     case SHA384: return SHA384_Message_Block_Size;
196     default:
197     case SHA512: return SHA512_Message_Block_Size;
198   }
199 }
200 
201 /*
202  * USHAHashSize
203  *
204  * Description:
205  *   This function will return the hashsize for the given SHA
206  *   algorithm.
207  *
208  * Parameters:
209  *   whichSha:
210  *     which SHA algorithm to query
211  *
212  * Returns:
213  *   hash size
214  *
215  */
USHAHashSize(enum SHAversion whichSha)216 int USHAHashSize(enum SHAversion whichSha)
217 {
218   switch (whichSha) {
219     case SHA1:   return SHA1HashSize;
220     case SHA224: return SHA224HashSize;
221     case SHA256: return SHA256HashSize;
222     case SHA384: return SHA384HashSize;
223     default:
224     case SHA512: return SHA512HashSize;
225   }
226 }
227 
228 #if 0 /* not used */
229 /*
230  * USHAHashSizeBits
231  *
232  * Description:
233  *   This function will return the hashsize for the given SHA
234  *   algorithm, expressed in bits.
235  *
236  * Parameters:
237  *   whichSha:
238  *     which SHA algorithm to query
239  *
240  * Returns:
241  *   hash size in bits
242  *
243  */
244 int USHAHashSizeBits(enum SHAversion whichSha)
245 {
246   switch (whichSha) {
247     case SHA1:   return SHA1HashSizeBits;
248     case SHA224: return SHA224HashSizeBits;
249     case SHA256: return SHA256HashSizeBits;
250     case SHA384: return SHA384HashSizeBits;
251     default:
252     case SHA512: return SHA512HashSizeBits;
253   }
254 }
255 #endif /* 0 */
256 
257 /*
258  * USHAHashName
259  *
260  * Description:
261  *   This function will return the name of the given SHA algorithm
262  *   as a string.
263  *
264  * Parameters:
265  *   whichSha:
266  *     which SHA algorithm to query
267  *
268  * Returns:
269  *   character string with the name in it
270  *
271  */
USHAHashName(enum SHAversion whichSha)272 const char *USHAHashName(enum SHAversion whichSha)
273 {
274   switch (whichSha) {
275     case SHA1:   return "SHA1";
276     case SHA224: return "SHA224";
277     case SHA256: return "SHA256";
278     case SHA384: return "SHA384";
279     default:
280     case SHA512: return "SHA512";
281   }
282 }
283