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