1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 
8 /************* Include Files ****************/
9 
10 #include "cc_pal_mem.h"
11 #include "cc_common.h"
12 #include "cc_common_math.h"
13 #include "cc_ecpki_error.h"
14 #include "cc_ecpki_local.h"
15 #include "cc_fips_defs.h"
16 #include "ec_wrst.h"
17 
18 /************************ Defines ***************************************/
19 
20 /************************ Enums *****************************************/
21 
22 /************************ Typedefs **************************************/
23 
24 /************************ Global Data ***********************************/
25 
26 /************* Private function prototype *******************************/
27 
28 /************************ Public Functions ******************************/
29 
30 /**********************************************************************************
31  *                    CC_EcpkiPrivKeyBuild function                            *
32  **********************************************************************************/
33 /**
34  * The function checks and imports (builds) private key and EC domain into
35  * structure of defined type.
36  *
37  *  This function should be called before using of the private key. Input
38  *  domain structure must be initialized by EC parameters and auxiliary
39  *  values, using CC_EcpkiGetDomain or CC_EcpkiSetDomain functions.
40  *
41  *  The function does the following:
42  *      - Checks validity of incoming variables and pointers;
43  *      - Converts private key to words arrays with little endian order
44  *        of the words and copies it in the UserPrivKey buffer.
45  *      - Copies EC domain into UserPrivKey  buffer.
46  *
47  * @author reuvenl (8/11/2014)
48  * @param pDomain - The pointer to EC domain structure.
49  * @param pPrivKeyIn - The pointer to private key data.
50  * @param PrivKeySizeInBytes - The size of private key data in bytes.
51  * @param pUserPrivKey - The pointer to private key structure.
52  *
53  * @return CEXPORT_C CCError_t
54  */
CC_EcpkiPrivKeyBuild(const CCEcpkiDomain_t * pDomain,const uint8_t * pPrivKeyIn,size_t privKeySizeInBytes,CCEcpkiUserPrivKey_t * pUserPrivKey)55 CEXPORT_C CCError_t CC_EcpkiPrivKeyBuild(
56                                              const CCEcpkiDomain_t *pDomain,        /*in */
57                                              const uint8_t             *pPrivKeyIn,     /*in*/
58                                              size_t                    privKeySizeInBytes,/*in*/
59                                              CCEcpkiUserPrivKey_t  *pUserPrivKey    /*out*/)
60 {
61         /* FUNCTION DECLARATIONS */
62 
63         /* the private key structure pointer */
64         CCEcpkiPrivKey_t *pPrivKey;
65         /*  EC domain info structure and parameters */
66         uint32_t  orderSizeInBytes;
67         /* the err return code identifier */
68         CCError_t err = CC_OK;
69 
70         /* FUNCTION LOGIC */
71         CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
72 
73         /* checking the validity of arguments */
74         if (pPrivKeyIn == NULL)
75                 return  CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_IN_PTR_ERROR;
76         if (pUserPrivKey == NULL)
77                 return  CC_ECPKI_BUILD_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR;
78         if (pDomain == NULL)
79                 return  CC_ECPKI_DOMAIN_PTR_ERROR;
80 
81         /* check EC domain parameters sizes */
82         if ((pDomain->modSizeInBits > (CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS * 32)) ||
83             (pDomain->ordSizeInBits > (pDomain->modSizeInBits + 1))) {
84                 return CC_ECPKI_INVALID_DATA_IN_PASSED_STRUCT_ERROR;
85         }
86 
87 
88         /****************  FUNCTION LOGIC  **************************************/
89 
90         /* the pointer to the key database */
91         pPrivKey = (CCEcpkiPrivKey_t *)((void*)pUserPrivKey->PrivKeyDbBuff);
92 
93         /* check key size */
94         orderSizeInBytes = CALC_FULL_BYTES(pDomain->ordSizeInBits);
95         if (privKeySizeInBytes == 0 || privKeySizeInBytes > orderSizeInBytes)
96                 return  CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_SIZE_ERROR;
97 
98         /* loading the private key (little endian)*/
99         err = CC_CommonConvertMsbLsbBytesToLswMswWords(
100                                                          pPrivKey->PrivKey, sizeof(pPrivKey->PrivKey),
101                                                          pPrivKeyIn, privKeySizeInBytes);
102         if (err != CC_OK) {
103                 err = CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR;
104                 goto End;
105         }
106 
107         /* check the value of the private key */
108         if (privKeySizeInBytes == orderSizeInBytes) {
109                 if (CC_CommonCmpLsWordsUnsignedCounters(
110                                                           pPrivKey->PrivKey, (uint16_t)(privKeySizeInBytes+3)/sizeof(uint32_t),
111                                                           pDomain->ecR, (uint16_t)(privKeySizeInBytes+3)/sizeof(uint32_t)) !=
112                     CC_COMMON_CmpCounter2GreaterThenCounter1) {
113                         err = CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR;
114                         goto End;
115                 }
116         }
117 
118         /* compare to 0 */
119         if (CC_CommonGetWordsCounterEffectiveSizeInBits(pPrivKey->PrivKey,
120                                                            (privKeySizeInBytes+3)/sizeof(uint32_t)) == 0) {
121                 err = CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR;
122                 goto End;
123         }
124 
125 
126         /* copy EC domain */
127         CC_PalMemCopy(&pPrivKey->domain, pDomain, sizeof(CCEcpkiDomain_t));
128 
129         /* ................ set the private key validation tag ................... */
130         pUserPrivKey->valid_tag = CC_ECPKI_PRIV_KEY_VALIDATION_TAG;
131 
132         End:
133         /* if the created structure is not valid - clear it */
134         if (err != CC_OK) {
135                 CC_PalMemSetZero(pUserPrivKey, sizeof(CCEcpkiUserPrivKey_t));
136         }
137 
138         return err;
139 
140 } /* End of CC_EcpkiPrivKeyBuild() */
141 
142 
143