xref: /openbsd-src/lib/libcrypto/sm2/sm2_za.c (revision 51892d90bfcefb54f7395f2f97f2099daa1c609c)
1*51892d90Stb /*	$OpenBSD: sm2_za.c,v 1.1.1.1 2021/08/18 16:04:32 tb Exp $ */
2*51892d90Stb /*
3*51892d90Stb  * Copyright (c) 2017, 2019 Ribose Inc
4*51892d90Stb  *
5*51892d90Stb  * Permission to use, copy, modify, and/or distribute this software for any
6*51892d90Stb  * purpose with or without fee is hereby granted, provided that the above
7*51892d90Stb  * copyright notice and this permission notice appear in all copies.
8*51892d90Stb  *
9*51892d90Stb  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*51892d90Stb  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*51892d90Stb  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*51892d90Stb  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*51892d90Stb  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*51892d90Stb  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*51892d90Stb  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*51892d90Stb  */
17*51892d90Stb 
18*51892d90Stb #ifndef OPENSSL_NO_SM2
19*51892d90Stb 
20*51892d90Stb #include <openssl/sm2.h>
21*51892d90Stb #include <openssl/evp.h>
22*51892d90Stb #include <openssl/bn.h>
23*51892d90Stb #include <string.h>
24*51892d90Stb 
25*51892d90Stb int
sm2_compute_userid_digest(uint8_t * out,const EVP_MD * digest,uint8_t * uid,size_t uid_len,const EC_KEY * key)26*51892d90Stb sm2_compute_userid_digest(uint8_t *out, const EVP_MD *digest, uint8_t *uid,
27*51892d90Stb     size_t uid_len, const EC_KEY *key)
28*51892d90Stb {
29*51892d90Stb 	const EC_GROUP *group;
30*51892d90Stb 	EVP_MD_CTX *hash = NULL;
31*51892d90Stb 	BN_CTX *ctx = NULL;
32*51892d90Stb 	BIGNUM *p, *a, *b, *xG, *yG, *xA, *yA;
33*51892d90Stb 	uint8_t *buf = NULL;
34*51892d90Stb 	uint16_t entla;
35*51892d90Stb 	uint8_t e_byte;
36*51892d90Stb 	int bytes, p_bytes;
37*51892d90Stb 	int rc = 0;
38*51892d90Stb 
39*51892d90Stb 	if ((group = EC_KEY_get0_group(key)) == NULL)
40*51892d90Stb 		goto err;
41*51892d90Stb 
42*51892d90Stb 	if ((hash = EVP_MD_CTX_new()) == NULL)
43*51892d90Stb 		goto err;
44*51892d90Stb 
45*51892d90Stb 	if ((ctx = BN_CTX_new()) == NULL)
46*51892d90Stb 		goto err;
47*51892d90Stb 
48*51892d90Stb 	if ((p = BN_CTX_get(ctx)) == NULL)
49*51892d90Stb 		goto err;
50*51892d90Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
51*51892d90Stb 		goto err;
52*51892d90Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
53*51892d90Stb 		goto err;
54*51892d90Stb 	if ((xG = BN_CTX_get(ctx)) == NULL)
55*51892d90Stb 		goto err;
56*51892d90Stb 	if ((yG = BN_CTX_get(ctx)) == NULL)
57*51892d90Stb 		goto err;
58*51892d90Stb 	if ((xA = BN_CTX_get(ctx)) == NULL)
59*51892d90Stb 		goto err;
60*51892d90Stb 	if ((yA = BN_CTX_get(ctx)) == NULL)
61*51892d90Stb 		goto err;
62*51892d90Stb 
63*51892d90Stb 	memset(out, 0, EVP_MD_size(digest));
64*51892d90Stb 
65*51892d90Stb 	if (!EVP_DigestInit(hash, digest))
66*51892d90Stb 		goto err;
67*51892d90Stb 
68*51892d90Stb 	/*
69*51892d90Stb 	 * ZA=H256(ENTLA || IDA || a || b || xG || yG || xA || yA)
70*51892d90Stb 	 */
71*51892d90Stb 
72*51892d90Stb 	if (uid_len >= 8192)
73*51892d90Stb 		goto err;
74*51892d90Stb 
75*51892d90Stb 	entla = (unsigned short)(8 * uid_len);
76*51892d90Stb 
77*51892d90Stb 	e_byte = entla >> 8;
78*51892d90Stb 	if (!EVP_DigestUpdate(hash, &e_byte, 1))
79*51892d90Stb 		goto err;
80*51892d90Stb 
81*51892d90Stb 	e_byte = entla & 0xFF;
82*51892d90Stb 	if (!EVP_DigestUpdate(hash, &e_byte, 1))
83*51892d90Stb 		goto err;
84*51892d90Stb 
85*51892d90Stb 	if (!EVP_DigestUpdate(hash, uid, uid_len))
86*51892d90Stb 		goto err;
87*51892d90Stb 
88*51892d90Stb 	if (!EC_GROUP_get_curve(group, p, a, b, ctx))
89*51892d90Stb 		goto err;
90*51892d90Stb 
91*51892d90Stb 	p_bytes = BN_num_bytes(p);
92*51892d90Stb 
93*51892d90Stb 	if ((buf = calloc(1, p_bytes)) == NULL)
94*51892d90Stb 		goto err;
95*51892d90Stb 
96*51892d90Stb 	if ((bytes = BN_num_bytes(a)) > p_bytes)
97*51892d90Stb 		goto err;
98*51892d90Stb 	BN_bn2bin(a, buf + p_bytes - bytes);
99*51892d90Stb 	if (!EVP_DigestUpdate(hash, buf, p_bytes))
100*51892d90Stb 		goto err;
101*51892d90Stb 
102*51892d90Stb 	if ((bytes = BN_num_bytes(b)) > p_bytes)
103*51892d90Stb 		goto err;
104*51892d90Stb 	memset(buf, 0, p_bytes - bytes);
105*51892d90Stb 	BN_bn2bin(b, buf + p_bytes - bytes);
106*51892d90Stb 	if (!EVP_DigestUpdate(hash, buf, p_bytes))
107*51892d90Stb 		goto err;
108*51892d90Stb 
109*51892d90Stb 	if (!EC_POINT_get_affine_coordinates(group,
110*51892d90Stb 	    EC_GROUP_get0_generator(group), xG, yG, ctx))
111*51892d90Stb 		goto err;
112*51892d90Stb 
113*51892d90Stb 	if ((bytes = BN_num_bytes(xG)) > p_bytes)
114*51892d90Stb 		goto err;
115*51892d90Stb 	memset(buf, 0, p_bytes - bytes);
116*51892d90Stb 	BN_bn2bin(xG, buf + p_bytes - bytes);
117*51892d90Stb 
118*51892d90Stb 	if (!EVP_DigestUpdate(hash, buf, p_bytes))
119*51892d90Stb 		goto err;
120*51892d90Stb 
121*51892d90Stb 	if ((bytes = BN_num_bytes(yG)) > p_bytes)
122*51892d90Stb 		goto err;
123*51892d90Stb 	memset(buf, 0, p_bytes - bytes);
124*51892d90Stb 	BN_bn2bin(yG, buf + p_bytes - bytes);
125*51892d90Stb 
126*51892d90Stb 	if (!EVP_DigestUpdate(hash, buf, p_bytes))
127*51892d90Stb 		goto err;
128*51892d90Stb 
129*51892d90Stb 	if (!EC_POINT_get_affine_coordinates(group,
130*51892d90Stb 	    EC_KEY_get0_public_key(key), xA, yA, ctx))
131*51892d90Stb 		goto err;
132*51892d90Stb 
133*51892d90Stb 	if ((bytes = BN_num_bytes(xA)) > p_bytes)
134*51892d90Stb 		goto err;
135*51892d90Stb 	memset(buf, 0, p_bytes - bytes);
136*51892d90Stb 	BN_bn2bin(xA, buf + p_bytes - bytes);
137*51892d90Stb 
138*51892d90Stb 	if (!EVP_DigestUpdate(hash, buf, p_bytes))
139*51892d90Stb 		goto err;
140*51892d90Stb 
141*51892d90Stb 	if ((bytes = BN_num_bytes(yA)) > p_bytes)
142*51892d90Stb 		goto err;
143*51892d90Stb 	memset(buf, 0, p_bytes - bytes);
144*51892d90Stb 	BN_bn2bin(yA, buf + p_bytes - bytes);
145*51892d90Stb 
146*51892d90Stb 	if (!EVP_DigestUpdate(hash, buf, p_bytes))
147*51892d90Stb 		goto err;
148*51892d90Stb 
149*51892d90Stb 	if (!EVP_DigestFinal(hash, out, NULL))
150*51892d90Stb 		goto err;
151*51892d90Stb 
152*51892d90Stb 	rc = 1;
153*51892d90Stb 
154*51892d90Stb  err:
155*51892d90Stb 	free(buf);
156*51892d90Stb 	BN_CTX_free(ctx);
157*51892d90Stb 	EVP_MD_CTX_free(hash);
158*51892d90Stb 	return rc;
159*51892d90Stb }
160*51892d90Stb 
161*51892d90Stb #endif /* OPENSSL_NO_SM2 */
162