• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "hvb_sm2.h"
16 #include "hvb_sm3.h"
17 #include "hvb_sm2_bn.h"
18 #include "hvb_sysdeps.h"
19 #include "hvb_util.h"
20 #include <stdio.h>
21 #include <stdlib.h>
22 
23 #define SM2_POINT_LEN   (SM2_KEY_LEN << 1)
24 /* user ID's max bits */
25 #define SM2_MAX_ID_BITS      65535
26 /* user ID's max len */
27 #define SM2_MAX_ID_LENGTH (SM2_MAX_ID_BITS / 8)
28 
sm2_verify_check_param(const struct sm2_pubkey * pkey,const uint8_t * pid,uint32_t idlen,const uint8_t * pmsg,uint32_t msglen,const uint8_t * psign,uint32_t signlen)29 static int sm2_verify_check_param(const struct sm2_pubkey *pkey, const uint8_t *pid, uint32_t idlen,
30                 const uint8_t *pmsg, uint32_t msglen, const uint8_t *psign, uint32_t signlen)
31 {
32     if (hvb_check(!pkey || !pid || !pmsg || !psign))
33         return SM2_POINTER_NULL;
34 
35     if (hvb_check(signlen != SM2_POINT_LEN || idlen == 0 || msglen == 0 || idlen > SM2_MAX_ID_LENGTH))
36         return SM2_PARAM_LEN_ERROR;
37 
38     return SM2_VERIFY_OK;
39 }
40 
sm2_compute_z(const struct sm2_pubkey * pkey,const uint8_t * pid,uint32_t idlen,uint8_t * pz,uint32_t * pzlen)41 static int sm2_compute_z(const struct sm2_pubkey *pkey, const uint8_t *pid, uint32_t idlen,
42                     uint8_t *pz, uint32_t *pzlen)
43 {
44     int ret;
45     uint16_t idx;
46     struct sm3_ctx_t ctx = { 0 };
47 
48     ret = hvb_sm3_init(&ctx);
49     if (hvb_check(ret != SM3_OK))
50         return SM2_HASH_INIT_ERROR;
51 
52     idx = (uint16_t)byte2bit(idlen);
53     idx = u16_inv(idx);
54     ret = hvb_sm3_update(&ctx, &idx, sizeof(idx));
55     if (hvb_check(ret != SM3_OK))
56         return SM2_HASH_UPDATE_ERROR;
57 
58     ret = hvb_sm3_update(&ctx, pid, idlen);
59     if (hvb_check(ret != SM3_OK))
60         return SM2_HASH_UPDATE_ERROR;
61 
62     uint8_t *sm2_params[] = {
63         sm2_bn_get_param_a(),
64         sm2_bn_get_param_b(),
65         sm2_bn_get_param_gx(),
66         sm2_bn_get_param_gy(),
67         (uint8_t *)pkey->x,
68         (uint8_t *)pkey->y
69     };
70 
71     for (idx = 0; idx < array_size(sm2_params); idx++) {
72         ret = hvb_sm3_update(&ctx, sm2_params[idx], SM2_KEY_LEN);
73         if (hvb_check(ret != SM3_OK))
74             return SM2_HASH_UPDATE_ERROR;
75     }
76 
77     ret = hvb_sm3_final(&ctx, pz, pzlen);
78     if (hvb_check(ret != SM3_OK))
79         return SM2_HASH_FINALE_ERROR;
80 
81     return SM2_VERIFY_OK;
82 }
83 
sm2_compute_digest(const uint8_t * pmsg,uint32_t msglen,const uint8_t * pz,uint32_t pzlen,uint8_t * pdigest,uint32_t * pdigestlen)84 static int sm2_compute_digest(const uint8_t *pmsg, uint32_t msglen, const uint8_t *pz, uint32_t pzlen,
85                     uint8_t *pdigest, uint32_t *pdigestlen)
86 {
87     int ret;
88     struct sm3_ctx_t ctx;
89 
90     ret = hvb_sm3_init(&ctx);
91     if (hvb_check(ret != SM3_OK))
92         return SM2_HASH_INIT_ERROR;
93 
94     ret = hvb_sm3_update(&ctx, pz, pzlen);
95     if (hvb_check(ret != SM3_OK))
96         return SM2_HASH_UPDATE_ERROR;
97 
98     ret = hvb_sm3_update(&ctx, pmsg, msglen);
99     if (hvb_check(ret != SM3_OK))
100         return SM2_HASH_UPDATE_ERROR;
101 
102     ret = hvb_sm3_final(&ctx, pdigest, pdigestlen);
103     if (hvb_check(ret != SM3_OK))
104         return SM2_HASH_FINALE_ERROR;
105 
106     return SM2_VERIFY_OK;
107 }
108 
sm2_check_rs(uint64_t r[],uint64_t s[],uint64_t t[])109 static int sm2_check_rs(uint64_t r[], uint64_t s[], uint64_t t[])
110 {
111     int ret;
112 
113     ret = sm2_bn_check_indomain_n(r);
114     if (hvb_check(ret != SM2_BN_OK))
115         return SM2_R_NOT_INDOMAIN;
116 
117     ret = sm2_bn_check_indomain_n(s);
118     if (hvb_check(ret != SM2_BN_OK))
119         return SM2_S_NOT_INDOMAIN;
120 
121     /* t = (r + s) mod n */
122     ret = sm2_bn_add_mod_n(r, s, t);
123     if (hvb_check(ret != SM2_BN_OK))
124         return SM2_MOD_ADD_ERROR;
125 
126     ret = sm2_bn_is_valid(t);
127     if (hvb_check(ret != SM2_BN_OK))
128         return SM2_R_ADD_S_ERROR;
129 
130     return SM2_VERIFY_OK;
131 }
132 
sm2_digest_verify(const struct sm2_pubkey * pkey,const uint8_t * pdigest,uint32_t digestlen,const uint8_t * psign,uint32_t signlen)133 int sm2_digest_verify(const struct sm2_pubkey *pkey, const uint8_t *pdigest, uint32_t digestlen,
134                     const uint8_t *psign, uint32_t signlen)
135 {
136     int ret;
137     uint64_t r[SM2_DATA_DWORD_SIZE] = { 0 };
138     uint64_t s[SM2_DATA_DWORD_SIZE] = { 0 };
139     uint64_t t[SM2_DATA_DWORD_SIZE] = { 0 };
140     uint64_t digest_tmp[SM2_DATA_DWORD_SIZE] = { 0 };
141     struct sm2_point_aff tmp_point = { 0 };
142 
143     if (hvb_check(digestlen != SM3_OUT_BYTE_SIZE || signlen != SM2_POINT_LEN)) {
144         return SM2_PARAM_LEN_ERROR;
145     }
146 
147     invert_copy_byte((uint8_t *)digest_tmp, (uint8_t *)pdigest, digestlen);
148     invert_copy_byte((uint8_t *)r, (uint8_t *)psign, SM2_KEY_LEN);
149     invert_copy_byte((uint8_t *)s, (uint8_t *)psign + SM2_KEY_LEN, SM2_KEY_LEN);
150     invert_copy_byte((uint8_t *)tmp_point.x, (uint8_t *)pkey->x, SM2_KEY_LEN);
151     invert_copy_byte((uint8_t *)tmp_point.y, (uint8_t *)pkey->y, SM2_KEY_LEN);
152     ret = sm2_check_rs(r, s, t);
153     if (hvb_check(ret != SM2_VERIFY_OK))
154         return ret;
155 
156     ret = sm2_point_mul_add(s, t, &tmp_point, &tmp_point);
157     if (hvb_check(ret != SM2_BN_OK))
158         return SM2_POINT_MUL_ADD_ERROR;
159 
160     ret = sm2_bn_add_mod_n(tmp_point.x, digest_tmp, t);
161     if (hvb_check(ret != SM2_BN_OK))
162         return SM2_MOD_ADD_ERROR;
163 
164     int ret_first = sm2_bn_cmp(r, t);
165     int ret_second = sm2_bn_cmp(r, t);
166     if (hvb_check(ret_first != 0 || ret_second != 0))
167         return SM2_VERIFY_ERROR;
168 
169     return SM2_VERIFY_OK + ret_first + ret_second;
170 }
171 
hvb_sm2_verify(const struct sm2_pubkey * pkey,const uint8_t * pid,uint32_t idlen,const uint8_t * pmsg,uint32_t msglen,const uint8_t * psign,uint32_t signlen)172 int hvb_sm2_verify(const struct sm2_pubkey *pkey, const uint8_t *pid, uint32_t idlen,
173                 const uint8_t *pmsg, uint32_t msglen, const uint8_t *psign, uint32_t signlen)
174 {
175     uint8_t pz[SM3_OUT_BYTE_SIZE] = { 0 };
176     uint8_t pdigest[SM3_OUT_BYTE_SIZE] = { 0 };
177     uint32_t zlen = SM3_OUT_BYTE_SIZE;
178     uint32_t digestlen = SM3_OUT_BYTE_SIZE;
179     int ret;
180 
181     ret = sm2_verify_check_param(pkey, pid, idlen, pmsg, msglen, psign, signlen);
182     if (hvb_check(ret != SM2_VERIFY_OK))
183         return SM2_PARAM_ERROR;
184 
185     ret = sm2_compute_z(pkey, pid, idlen, pz, &zlen);
186     if (hvb_check(ret != SM2_VERIFY_OK))
187         return SM2_COMPUTE_Z_ERROR;
188 
189     ret = sm2_compute_digest(pmsg, msglen, pz, zlen, pdigest, &digestlen);
190     if (hvb_check(ret != SM2_VERIFY_OK))
191         return SM2_COMPUTE_DIGEST_ERROR;
192 
193     return sm2_digest_verify(pkey, pdigest, digestlen, psign, signlen);
194 }
195