1 /** @file
2   SHA-384 and SHA-512 Digest Wrapper Implementations over OpenSSL.
3 
4 Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution.  The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include "InternalCryptLib.h"
16 #include <openssl/sha.h>
17 
18 /**
19   Retrieves the size, in bytes, of the context buffer required for SHA-384 hash operations.
20 
21   @return  The size, in bytes, of the context buffer required for SHA-384 hash operations.
22 
23 **/
24 UINTN
25 EFIAPI
Sha384GetContextSize(VOID)26 Sha384GetContextSize (
27   VOID
28   )
29 {
30   //
31   // Retrieves OpenSSL SHA-384 Context Size
32   //
33   return (UINTN) (sizeof (SHA512_CTX));
34 }
35 
36 /**
37   Initializes user-supplied memory pointed by Sha384Context as SHA-384 hash context for
38   subsequent use.
39 
40   If Sha384Context is NULL, then return FALSE.
41 
42   @param[out]  Sha384Context  Pointer to SHA-384 context being initialized.
43 
44   @retval TRUE   SHA-384 context initialization succeeded.
45   @retval FALSE  SHA-384 context initialization failed.
46 
47 **/
48 BOOLEAN
49 EFIAPI
Sha384Init(OUT VOID * Sha384Context)50 Sha384Init (
51   OUT  VOID  *Sha384Context
52   )
53 {
54   //
55   // Check input parameters.
56   //
57   if (Sha384Context == NULL) {
58     return FALSE;
59   }
60 
61   //
62   // OpenSSL SHA-384 Context Initialization
63   //
64   return (BOOLEAN) (SHA384_Init ((SHA512_CTX *) Sha384Context));
65 }
66 
67 /**
68   Makes a copy of an existing SHA-384 context.
69 
70   If Sha384Context is NULL, then return FALSE.
71   If NewSha384Context is NULL, then return FALSE.
72   If this interface is not supported, then return FALSE.
73 
74   @param[in]  Sha384Context     Pointer to SHA-384 context being copied.
75   @param[out] NewSha384Context  Pointer to new SHA-384 context.
76 
77   @retval TRUE   SHA-384 context copy succeeded.
78   @retval FALSE  SHA-384 context copy failed.
79   @retval FALSE  This interface is not supported.
80 
81 **/
82 BOOLEAN
83 EFIAPI
Sha384Duplicate(IN CONST VOID * Sha384Context,OUT VOID * NewSha384Context)84 Sha384Duplicate (
85   IN   CONST VOID  *Sha384Context,
86   OUT  VOID        *NewSha384Context
87   )
88 {
89   //
90   // Check input parameters.
91   //
92   if (Sha384Context == NULL || NewSha384Context == NULL) {
93     return FALSE;
94   }
95 
96   CopyMem (NewSha384Context, Sha384Context, sizeof (SHA512_CTX));
97 
98   return TRUE;
99 }
100 
101 /**
102   Digests the input data and updates SHA-384 context.
103 
104   This function performs SHA-384 digest on a data buffer of the specified size.
105   It can be called multiple times to compute the digest of long or discontinuous data streams.
106   SHA-384 context should be already correctly initialized by Sha384Init(), and should not be finalized
107   by Sha384Final(). Behavior with invalid context is undefined.
108 
109   If Sha384Context is NULL, then return FALSE.
110 
111   @param[in, out]  Sha384Context  Pointer to the SHA-384 context.
112   @param[in]       Data           Pointer to the buffer containing the data to be hashed.
113   @param[in]       DataSize       Size of Data buffer in bytes.
114 
115   @retval TRUE   SHA-384 data digest succeeded.
116   @retval FALSE  SHA-384 data digest failed.
117 
118 **/
119 BOOLEAN
120 EFIAPI
Sha384Update(IN OUT VOID * Sha384Context,IN CONST VOID * Data,IN UINTN DataSize)121 Sha384Update (
122   IN OUT  VOID        *Sha384Context,
123   IN      CONST VOID  *Data,
124   IN      UINTN       DataSize
125   )
126 {
127   //
128   // Check input parameters.
129   //
130   if (Sha384Context == NULL) {
131     return FALSE;
132   }
133 
134   //
135   // Check invalid parameters, in case that only DataLength was checked in OpenSSL
136   //
137   if (Data == NULL && DataSize != 0) {
138     return FALSE;
139   }
140 
141   //
142   // OpenSSL SHA-384 Hash Update
143   //
144   return (BOOLEAN) (SHA384_Update ((SHA512_CTX *) Sha384Context, Data, DataSize));
145 }
146 
147 /**
148   Completes computation of the SHA-384 digest value.
149 
150   This function completes SHA-384 hash computation and retrieves the digest value into
151   the specified memory. After this function has been called, the SHA-384 context cannot
152   be used again.
153   SHA-384 context should be already correctly initialized by Sha384Init(), and should not be
154   finalized by Sha384Final(). Behavior with invalid SHA-384 context is undefined.
155 
156   If Sha384Context is NULL, then return FALSE.
157   If HashValue is NULL, then return FALSE.
158 
159   @param[in, out]  Sha384Context  Pointer to the SHA-384 context.
160   @param[out]      HashValue      Pointer to a buffer that receives the SHA-384 digest
161                                   value (48 bytes).
162 
163   @retval TRUE   SHA-384 digest computation succeeded.
164   @retval FALSE  SHA-384 digest computation failed.
165 
166 **/
167 BOOLEAN
168 EFIAPI
Sha384Final(IN OUT VOID * Sha384Context,OUT UINT8 * HashValue)169 Sha384Final (
170   IN OUT  VOID   *Sha384Context,
171   OUT     UINT8  *HashValue
172   )
173 {
174   //
175   // Check input parameters.
176   //
177   if (Sha384Context == NULL || HashValue == NULL) {
178     return FALSE;
179   }
180 
181   //
182   // OpenSSL SHA-384 Hash Finalization
183   //
184   return (BOOLEAN) (SHA384_Final (HashValue, (SHA512_CTX *) Sha384Context));
185 }
186 
187 /**
188   Computes the SHA-384 message digest of a input data buffer.
189 
190   This function performs the SHA-384 message digest of a given data buffer, and places
191   the digest value into the specified memory.
192 
193   If this interface is not supported, then return FALSE.
194 
195   @param[in]   Data        Pointer to the buffer containing the data to be hashed.
196   @param[in]   DataSize    Size of Data buffer in bytes.
197   @param[out]  HashValue   Pointer to a buffer that receives the SHA-384 digest
198                            value (48 bytes).
199 
200   @retval TRUE   SHA-384 digest computation succeeded.
201   @retval FALSE  SHA-384 digest computation failed.
202   @retval FALSE  This interface is not supported.
203 
204 **/
205 BOOLEAN
206 EFIAPI
Sha384HashAll(IN CONST VOID * Data,IN UINTN DataSize,OUT UINT8 * HashValue)207 Sha384HashAll (
208   IN   CONST VOID  *Data,
209   IN   UINTN       DataSize,
210   OUT  UINT8       *HashValue
211   )
212 {
213   //
214   // Check input parameters.
215   //
216   if (HashValue == NULL) {
217     return FALSE;
218   }
219   if (Data == NULL && DataSize != 0) {
220     return FALSE;
221   }
222 
223   //
224   // OpenSSL SHA-384 Hash Computation.
225   //
226   if (SHA384 (Data, DataSize, HashValue) == NULL) {
227     return FALSE;
228   } else {
229     return TRUE;
230   }
231 }
232 
233 /**
234   Retrieves the size, in bytes, of the context buffer required for SHA-512 hash operations.
235 
236   @return  The size, in bytes, of the context buffer required for SHA-512 hash operations.
237 
238 **/
239 UINTN
240 EFIAPI
Sha512GetContextSize(VOID)241 Sha512GetContextSize (
242   VOID
243   )
244 {
245   //
246   // Retrieves OpenSSL SHA-512 Context Size
247   //
248   return (UINTN) (sizeof (SHA512_CTX));
249 }
250 
251 /**
252   Initializes user-supplied memory pointed by Sha512Context as SHA-512 hash context for
253   subsequent use.
254 
255   If Sha512Context is NULL, then return FALSE.
256 
257   @param[out]  Sha512Context  Pointer to SHA-512 context being initialized.
258 
259   @retval TRUE   SHA-512 context initialization succeeded.
260   @retval FALSE  SHA-512 context initialization failed.
261 
262 **/
263 BOOLEAN
264 EFIAPI
Sha512Init(OUT VOID * Sha512Context)265 Sha512Init (
266   OUT  VOID  *Sha512Context
267   )
268 {
269   //
270   // Check input parameters.
271   //
272   if (Sha512Context == NULL) {
273     return FALSE;
274   }
275 
276   //
277   // OpenSSL SHA-512 Context Initialization
278   //
279   return (BOOLEAN) (SHA512_Init ((SHA512_CTX *) Sha512Context));
280 }
281 
282 /**
283   Makes a copy of an existing SHA-512 context.
284 
285   If Sha512Context is NULL, then return FALSE.
286   If NewSha512Context is NULL, then return FALSE.
287   If this interface is not supported, then return FALSE.
288 
289   @param[in]  Sha512Context     Pointer to SHA-512 context being copied.
290   @param[out] NewSha512Context  Pointer to new SHA-512 context.
291 
292   @retval TRUE   SHA-512 context copy succeeded.
293   @retval FALSE  SHA-512 context copy failed.
294   @retval FALSE  This interface is not supported.
295 
296 **/
297 BOOLEAN
298 EFIAPI
Sha512Duplicate(IN CONST VOID * Sha512Context,OUT VOID * NewSha512Context)299 Sha512Duplicate (
300   IN   CONST VOID  *Sha512Context,
301   OUT  VOID        *NewSha512Context
302   )
303 {
304   //
305   // Check input parameters.
306   //
307   if (Sha512Context == NULL || NewSha512Context == NULL) {
308     return FALSE;
309   }
310 
311   CopyMem (NewSha512Context, Sha512Context, sizeof (SHA512_CTX));
312 
313   return TRUE;
314 }
315 
316 /**
317   Digests the input data and updates SHA-512 context.
318 
319   This function performs SHA-512 digest on a data buffer of the specified size.
320   It can be called multiple times to compute the digest of long or discontinuous data streams.
321   SHA-512 context should be already correctly initialized by Sha512Init(), and should not be finalized
322   by Sha512Final(). Behavior with invalid context is undefined.
323 
324   If Sha512Context is NULL, then return FALSE.
325 
326   @param[in, out]  Sha512Context  Pointer to the SHA-512 context.
327   @param[in]       Data           Pointer to the buffer containing the data to be hashed.
328   @param[in]       DataSize       Size of Data buffer in bytes.
329 
330   @retval TRUE   SHA-512 data digest succeeded.
331   @retval FALSE  SHA-512 data digest failed.
332 
333 **/
334 BOOLEAN
335 EFIAPI
Sha512Update(IN OUT VOID * Sha512Context,IN CONST VOID * Data,IN UINTN DataSize)336 Sha512Update (
337   IN OUT  VOID        *Sha512Context,
338   IN      CONST VOID  *Data,
339   IN      UINTN       DataSize
340   )
341 {
342   //
343   // Check input parameters.
344   //
345   if (Sha512Context == NULL) {
346     return FALSE;
347   }
348 
349   //
350   // Check invalid parameters, in case that only DataLength was checked in OpenSSL
351   //
352   if (Data == NULL && DataSize != 0) {
353     return FALSE;
354   }
355 
356   //
357   // OpenSSL SHA-512 Hash Update
358   //
359   return (BOOLEAN) (SHA512_Update ((SHA512_CTX *) Sha512Context, Data, DataSize));
360 }
361 
362 /**
363   Completes computation of the SHA-512 digest value.
364 
365   This function completes SHA-512 hash computation and retrieves the digest value into
366   the specified memory. After this function has been called, the SHA-512 context cannot
367   be used again.
368   SHA-512 context should be already correctly initialized by Sha512Init(), and should not be
369   finalized by Sha512Final(). Behavior with invalid SHA-512 context is undefined.
370 
371   If Sha512Context is NULL, then return FALSE.
372   If HashValue is NULL, then return FALSE.
373 
374   @param[in, out]  Sha512Context  Pointer to the SHA-512 context.
375   @param[out]      HashValue      Pointer to a buffer that receives the SHA-512 digest
376                                   value (64 bytes).
377 
378   @retval TRUE   SHA-512 digest computation succeeded.
379   @retval FALSE  SHA-512 digest computation failed.
380 
381 **/
382 BOOLEAN
383 EFIAPI
Sha512Final(IN OUT VOID * Sha512Context,OUT UINT8 * HashValue)384 Sha512Final (
385   IN OUT  VOID   *Sha512Context,
386   OUT     UINT8  *HashValue
387   )
388 {
389   //
390   // Check input parameters.
391   //
392   if (Sha512Context == NULL || HashValue == NULL) {
393     return FALSE;
394   }
395 
396   //
397   // OpenSSL SHA-512 Hash Finalization
398   //
399   return (BOOLEAN) (SHA384_Final (HashValue, (SHA512_CTX *) Sha512Context));
400 }
401 
402 /**
403   Computes the SHA-512 message digest of a input data buffer.
404 
405   This function performs the SHA-512 message digest of a given data buffer, and places
406   the digest value into the specified memory.
407 
408   If this interface is not supported, then return FALSE.
409 
410   @param[in]   Data        Pointer to the buffer containing the data to be hashed.
411   @param[in]   DataSize    Size of Data buffer in bytes.
412   @param[out]  HashValue   Pointer to a buffer that receives the SHA-512 digest
413                            value (64 bytes).
414 
415   @retval TRUE   SHA-512 digest computation succeeded.
416   @retval FALSE  SHA-512 digest computation failed.
417   @retval FALSE  This interface is not supported.
418 
419 **/
420 BOOLEAN
421 EFIAPI
Sha512HashAll(IN CONST VOID * Data,IN UINTN DataSize,OUT UINT8 * HashValue)422 Sha512HashAll (
423   IN   CONST VOID  *Data,
424   IN   UINTN       DataSize,
425   OUT  UINT8       *HashValue
426   )
427 {
428   //
429   // Check input parameters.
430   //
431   if (HashValue == NULL) {
432     return FALSE;
433   }
434   if (Data == NULL && DataSize != 0) {
435     return FALSE;
436   }
437 
438   //
439   // OpenSSL SHA-512 Hash Computation.
440   //
441   if (SHA512 (Data, DataSize, HashValue) == NULL) {
442     return FALSE;
443   } else {
444     return TRUE;
445   }
446 }
447