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