1 /** @file
2   BaseCrypto SM3 hash instance library.
3   It can be registered to BaseCrypto router, to serve as hash engine.
4 
5   Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.<BR>
6   SPDX-License-Identifier: BSD-2-Clause-Patent
7 **/
8 
9 #include <PiPei.h>
10 #include <Library/BaseLib.h>
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/Tpm2CommandLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/BaseCryptLib.h>
15 #include <Library/MemoryAllocationLib.h>
16 #include <Library/HashLib.h>
17 
18 /**
19   The function set SM3 to digest list.
20 
21   @param DigestList   digest list
22   @param Sm3Digest    SM3 digest
23 **/
24 VOID
Tpm2SetSm3ToDigestList(IN TPML_DIGEST_VALUES * DigestList,IN UINT8 * Sm3Digest)25 Tpm2SetSm3ToDigestList (
26   IN TPML_DIGEST_VALUES *DigestList,
27   IN UINT8              *Sm3Digest
28   )
29 {
30   DigestList->count = 1;
31   DigestList->digests[0].hashAlg = TPM_ALG_SM3_256;
32   CopyMem (
33     DigestList->digests[0].digest.sm3_256,
34     Sm3Digest,
35     SM3_256_DIGEST_SIZE
36     );
37 }
38 
39 /**
40   Start hash sequence.
41 
42   @param HashHandle Hash handle.
43 
44   @retval EFI_SUCCESS          Hash sequence start and HandleHandle returned.
45   @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
46 **/
47 EFI_STATUS
48 EFIAPI
Sm3HashInit(OUT HASH_HANDLE * HashHandle)49 Sm3HashInit (
50   OUT HASH_HANDLE    *HashHandle
51   )
52 {
53   VOID     *Sm3Ctx;
54   UINTN    CtxSize;
55 
56   CtxSize = Sm3GetContextSize ();
57   Sm3Ctx = AllocatePool (CtxSize);
58   if (Sm3Ctx == NULL) {
59     return EFI_OUT_OF_RESOURCES;
60   }
61 
62   Sm3Init (Sm3Ctx);
63 
64   *HashHandle = (HASH_HANDLE)Sm3Ctx;
65 
66   return EFI_SUCCESS;
67 }
68 
69 /**
70   Update hash sequence data.
71 
72   @param HashHandle    Hash handle.
73   @param DataToHash    Data to be hashed.
74   @param DataToHashLen Data size.
75 
76   @retval EFI_SUCCESS     Hash sequence updated.
77 **/
78 EFI_STATUS
79 EFIAPI
Sm3HashUpdate(IN HASH_HANDLE HashHandle,IN VOID * DataToHash,IN UINTN DataToHashLen)80 Sm3HashUpdate (
81   IN HASH_HANDLE    HashHandle,
82   IN VOID           *DataToHash,
83   IN UINTN          DataToHashLen
84   )
85 {
86   VOID     *Sm3Ctx;
87 
88   Sm3Ctx = (VOID *)HashHandle;
89   Sm3Update (Sm3Ctx, DataToHash, DataToHashLen);
90 
91   return EFI_SUCCESS;
92 }
93 
94 /**
95   Complete hash sequence complete.
96 
97   @param HashHandle    Hash handle.
98   @param DigestList    Digest list.
99 
100   @retval EFI_SUCCESS     Hash sequence complete and DigestList is returned.
101 **/
102 EFI_STATUS
103 EFIAPI
Sm3HashFinal(IN HASH_HANDLE HashHandle,OUT TPML_DIGEST_VALUES * DigestList)104 Sm3HashFinal (
105   IN HASH_HANDLE         HashHandle,
106   OUT TPML_DIGEST_VALUES *DigestList
107   )
108 {
109   UINT8         Digest[SM3_256_DIGEST_SIZE];
110   VOID          *Sm3Ctx;
111 
112   Sm3Ctx = (VOID *)HashHandle;
113   Sm3Final (Sm3Ctx, Digest);
114 
115   FreePool (Sm3Ctx);
116 
117   Tpm2SetSm3ToDigestList (DigestList, Digest);
118 
119   return EFI_SUCCESS;
120 }
121 
122 HASH_INTERFACE  mSm3InternalHashInstance = {
123   HASH_ALGORITHM_SM3_256_GUID,
124   Sm3HashInit,
125   Sm3HashUpdate,
126   Sm3HashFinal,
127 };
128 
129 /**
130   The function register SM3 instance.
131 
132   @retval EFI_SUCCESS   SM3 instance is registered, or system dose not support register SM3 instance
133 **/
134 EFI_STATUS
135 EFIAPI
HashInstanceLibSm3Constructor(VOID)136 HashInstanceLibSm3Constructor (
137   VOID
138   )
139 {
140   EFI_STATUS  Status;
141 
142   Status = RegisterHashInterfaceLib (&mSm3InternalHashInstance);
143   if ((Status == EFI_SUCCESS) || (Status == EFI_UNSUPPORTED)) {
144     //
145     // Unsupported means platform policy does not need this instance enabled.
146     //
147     return EFI_SUCCESS;
148   }
149   return Status;
150 }
151