1 /*
2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 #include "cc_pal_mem.h"
7 #include "cc_pal_mutex.h"
8 #include "cc_pal_abort.h"
9 #include "cc_common.h"
10 #include "cc_common_math.h"
11 #include "cc_ecpki_types.h"
12 #include "cc_ecpki_error.h"
13 #include "cc_ecpki_local.h"
14 #include "pka_hw_defs.h"
15 #include "pki.h"
16 #include "pka.h"
17 #include "pka_ec_wrst.h"
18 #include "ec_wrst_error.h"
19 #include "pka_ec_wrst_dsa_verify_regs.h"
20 #include "pka_ec_wrst_glob_regs.h"
21
22 extern const CCEcpkiDomain_t gEcDomans[];
23
24 /*********** PkaEcdsaVerify function **********************/
25 /**
26 * @brief This function performs verification of ECDSA signature using PKA.
27 *
28 * 1. Compute h = d^-1, h1 = f*h mod r, h2 = c*h mod r.
29 * 2. Compute P(Xp,Yp) = h1*G + h2*W; c1 = Px mod r
30 * 3. Compare If c1 != c, then output "Invalid", else - "valid".
31 *
32 * Assuming: - PKA is initialized, all data is set into SRAM.
33 *
34 * @author reuvenl (8/7/2014)
35 *
36 * @return - On success CC_OK is returned, on failure an error code.
37 */
PkaEcdsaVerify(void)38 CCError_t PkaEcdsaVerify(void)
39 {
40 CCError_t err = CC_OK;
41 int32_t modSizeInBits, ordSizeInBits;
42 uint32_t status1, status2;
43
44 /* Get sizes */
45 ordSizeInBits = CC_HAL_READ_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L0));
46 modSizeInBits = CC_HAL_READ_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L2));
47
48 /* 1. If C or D are not in interval [1,r-1] then output "invalid" */
49 /* temporary set ECC_REG_N = ECC_REG_N - 1 for the following checking */
50 PKA_FLIP_BIT0(LEN_ID_N_PKA_REG_BITS, ECC_REG_N, ECC_REG_N);
51
52 /* check C */
53 PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS, RES_DISCARD, EC_VERIFY_REG_C, 1/*imm*/);
54 PKA_GET_STATUS_CARRY(status1); /* if EC_VERIFY_REG_C >= 1, then status = 0 */
55 PKA_SUB(LEN_ID_N_PKA_REG_BITS, RES_DISCARD, ECC_REG_N, EC_VERIFY_REG_C);
56 PKA_GET_STATUS_CARRY(status2); /* if EC_VERIFY_REG_C <= ECC_REG_N, then status = 1 */
57 if (status1 == 0 || status2 == 0) {
58 err = ECWRST_DSA_VERIFY_CALC_SIGN_C_INVALID_ERROR;
59 goto End;
60 }
61
62 /* check D */
63 PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS, RES_DISCARD, EC_VERIFY_REG_D, 1/*imm*/);
64 PKA_GET_STATUS_CARRY(status1); /* if EC_VERIFY_REG_D >= 1, then status = 0 */
65 PKA_SUB(LEN_ID_N_PKA_REG_BITS, RES_DISCARD, ECC_REG_N, EC_VERIFY_REG_D);
66 PKA_GET_STATUS_CARRY(status2); /* if EC_VERIFY_REG_D <= EC_VERIFY_REG_R, then status = 1 */
67 if (status1 == 0 || status2 == 0) {
68 err = ECWRST_DSA_VERIFY_CALC_SIGN_D_INVALID_ERROR;
69 goto End;
70 }
71
72 /* restore ECC_REG_N */
73 PKA_FLIP_BIT0(LEN_ID_N_PKA_REG_BITS, ECC_REG_N, ECC_REG_N);
74
75 /* 2. Calculate h, h1, h2 and normalize EC_VERIFY_REG_F */
76 /* 2.1. h = d^-1 mod r */
77 PKA_MOD_INV_W_EXP(EC_VERIFY_REG_H, EC_VERIFY_REG_D, EC_VERIFY_REG_TMP);
78
79 PKA_DIV(LEN_ID_N_PKA_REG_BITS, EC_VERIFY_REG_TMP, EC_VERIFY_REG_F/*rem*/, ECC_REG_N/*div*/);
80 /* 2.2. h1 = f*h mod r */
81 PKA_MOD_MUL(LEN_ID_N_BITS, EC_VERIFY_REG_H1/*Res*/, EC_VERIFY_REG_F/*OpA*/, EC_VERIFY_REG_H/*OpB*/);
82 /* 2.3. h2 = c*h mod r */
83 PKA_MOD_MUL(LEN_ID_N_BITS, EC_VERIFY_REG_H2/*Res*/, EC_VERIFY_REG_C/*OpA*/, EC_VERIFY_REG_H/*OpB*/);
84
85 /* set PKA for operations according to ECC modulus */
86 PKA_CLEAR(LEN_ID_N_PKA_REG_BITS, PKA_REG_T0);
87 PKA_CLEAR(LEN_ID_N_PKA_REG_BITS, PKA_REG_T1);
88 PKA_WAIT_ON_PKA_DONE();
89 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L0), modSizeInBits);
90 PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_VERIFY_REG_TMP, ECC_REG_N);
91 PKA_COPY(LEN_ID_N_PKA_REG_BITS, ECC_REG_N, EC_VERIFY_REG_TMP_N);
92 PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_VERIFY_REG_TMP_N, EC_VERIFY_REG_TMP); //swap mod<->ord
93 PKA_COPY(LEN_ID_N_PKA_REG_BITS, ECC_REG_NP, EC_VERIFY_REG_TMP_NP);
94
95 /* Auxiliary values: rn_X = X*ECC_REG_N */
96 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N4 , ECC_REG_N, ECC_REG_N );
97 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N4 , ECC_REG_N4, ECC_REG_N4);
98 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N8 , ECC_REG_N4, ECC_REG_N4);
99 PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N12, ECC_REG_N8, ECC_REG_N4);
100
101 /* 3. Compute EC point P1 = h1*G + h2*W by mod P */
102 err = PkaSum2ScalarMullt(EC_VERIFY_REG_P_RX,
103 EC_VERIFY_REG_P_RY,
104 EC_VERIFY_REG_H1,
105 EC_VERIFY_REG_P_GX,
106 EC_VERIFY_REG_P_GY,
107 EC_VERIFY_REG_H2,
108 EC_VERIFY_REG_P_WX,
109 EC_VERIFY_REG_P_WY);
110 if(err)
111 goto End;
112
113 /* 4. Normalize: C' = pRx mod r. Compare C' == C */
114 PKA_WAIT_ON_PKA_DONE();
115 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L0), ordSizeInBits);
116 PKA_DIV(LEN_ID_N_PKA_REG_BITS, EC_VERIFY_REG_TMP, EC_VERIFY_REG_P_RX/*rem*/, EC_VERIFY_REG_TMP_N/*div*/);
117 PKA_COMPARE_STATUS(LEN_ID_N_PKA_REG_BITS, EC_VERIFY_REG_P_RX, EC_VERIFY_REG_C, status1);
118 if (status1 != 1) {
119 err = ECWRST_DSA_VERIFY_CALC_SIGNATURE_IS_INVALID;
120 }
121 End:
122 return err;
123
124 }
125
126
127