/src/openssl/crypto/sm2/sm2_za.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * Copyright 2017 Ribose Inc. All Rights Reserved. |
4 | | * Ported from Ribose contributions from Botan. |
5 | | * |
6 | | * Licensed under the OpenSSL license (the "License"). You may not use |
7 | | * this file except in compliance with the License. You can obtain a copy |
8 | | * in the file LICENSE in the source distribution or at |
9 | | * https://www.openssl.org/source/license.html |
10 | | */ |
11 | | |
12 | | #include "internal/sm2.h" |
13 | | #include "internal/sm2err.h" |
14 | | #include <openssl/err.h> |
15 | | #include <openssl/evp.h> |
16 | | #include <openssl/bn.h> |
17 | | #include <string.h> |
18 | | #include "internal/numbers.h" |
19 | | |
20 | | int sm2_compute_userid_digest(uint8_t *out, |
21 | | const EVP_MD *digest, |
22 | | const char *user_id, |
23 | | const EC_KEY *key) |
24 | 0 | { |
25 | 0 | int rc = 0; |
26 | 0 | const EC_GROUP *group = EC_KEY_get0_group(key); |
27 | 0 | BN_CTX *ctx = NULL; |
28 | 0 | EVP_MD_CTX *hash = NULL; |
29 | 0 | BIGNUM *p = NULL; |
30 | 0 | BIGNUM *a = NULL; |
31 | 0 | BIGNUM *b = NULL; |
32 | 0 | BIGNUM *xG = NULL; |
33 | 0 | BIGNUM *yG = NULL; |
34 | 0 | BIGNUM *xA = NULL; |
35 | 0 | BIGNUM *yA = NULL; |
36 | 0 | int p_bytes = 0; |
37 | 0 | uint8_t *buf = NULL; |
38 | 0 | size_t uid_len = 0; |
39 | 0 | uint16_t entla = 0; |
40 | 0 | uint8_t e_byte = 0; |
41 | 0 |
|
42 | 0 | hash = EVP_MD_CTX_new(); |
43 | 0 | ctx = BN_CTX_new(); |
44 | 0 | if (hash == NULL || ctx == NULL) { |
45 | 0 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE); |
46 | 0 | goto done; |
47 | 0 | } |
48 | 0 |
|
49 | 0 | p = BN_CTX_get(ctx); |
50 | 0 | a = BN_CTX_get(ctx); |
51 | 0 | b = BN_CTX_get(ctx); |
52 | 0 | xG = BN_CTX_get(ctx); |
53 | 0 | yG = BN_CTX_get(ctx); |
54 | 0 | xA = BN_CTX_get(ctx); |
55 | 0 | yA = BN_CTX_get(ctx); |
56 | 0 |
|
57 | 0 | if (yA == NULL) { |
58 | 0 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE); |
59 | 0 | goto done; |
60 | 0 | } |
61 | 0 |
|
62 | 0 | if (!EVP_DigestInit(hash, digest)) { |
63 | 0 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB); |
64 | 0 | goto done; |
65 | 0 | } |
66 | 0 |
|
67 | 0 | /* ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA) */ |
68 | 0 |
|
69 | 0 | uid_len = strlen(user_id); |
70 | 0 | if (uid_len >= (UINT16_MAX / 8)) { |
71 | 0 | /* too large */ |
72 | 0 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, SM2_R_USER_ID_TOO_LARGE); |
73 | 0 | goto done; |
74 | 0 | } |
75 | 0 |
|
76 | 0 | entla = (uint16_t)(8 * uid_len); |
77 | 0 |
|
78 | 0 | e_byte = entla >> 8; |
79 | 0 | if (!EVP_DigestUpdate(hash, &e_byte, 1)) { |
80 | 0 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB); |
81 | 0 | goto done; |
82 | 0 | } |
83 | 0 | e_byte = entla & 0xFF; |
84 | 0 | if (!EVP_DigestUpdate(hash, &e_byte, 1) |
85 | 0 | || !EVP_DigestUpdate(hash, user_id, uid_len)) { |
86 | 0 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB); |
87 | 0 | goto done; |
88 | 0 | } |
89 | 0 |
|
90 | 0 | if (!EC_GROUP_get_curve(group, p, a, b, ctx)) { |
91 | 0 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EC_LIB); |
92 | 0 | goto done; |
93 | 0 | } |
94 | 0 |
|
95 | 0 | p_bytes = BN_num_bytes(p); |
96 | 0 | buf = OPENSSL_zalloc(p_bytes); |
97 | 0 | if (buf == NULL) { |
98 | 0 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE); |
99 | 0 | goto done; |
100 | 0 | } |
101 | 0 |
|
102 | 0 | if (BN_bn2binpad(a, buf, p_bytes) < 0 |
103 | 0 | || !EVP_DigestUpdate(hash, buf, p_bytes) |
104 | 0 | || BN_bn2binpad(b, buf, p_bytes) < 0 |
105 | 0 | || !EVP_DigestUpdate(hash, buf, p_bytes) |
106 | 0 | || !EC_POINT_get_affine_coordinates(group, |
107 | 0 | EC_GROUP_get0_generator(group), |
108 | 0 | xG, yG, ctx) |
109 | 0 | || BN_bn2binpad(xG, buf, p_bytes) < 0 |
110 | 0 | || !EVP_DigestUpdate(hash, buf, p_bytes) |
111 | 0 | || BN_bn2binpad(yG, buf, p_bytes) < 0 |
112 | 0 | || !EVP_DigestUpdate(hash, buf, p_bytes) |
113 | 0 | || !EC_POINT_get_affine_coordinates(group, |
114 | 0 | EC_KEY_get0_public_key(key), |
115 | 0 | xA, yA, ctx) |
116 | 0 | || BN_bn2binpad(xA, buf, p_bytes) < 0 |
117 | 0 | || !EVP_DigestUpdate(hash, buf, p_bytes) |
118 | 0 | || BN_bn2binpad(yA, buf, p_bytes) < 0 |
119 | 0 | || !EVP_DigestUpdate(hash, buf, p_bytes) |
120 | 0 | || !EVP_DigestFinal(hash, out, NULL)) { |
121 | 0 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_INTERNAL_ERROR); |
122 | 0 | goto done; |
123 | 0 | } |
124 | 0 |
|
125 | 0 | rc = 1; |
126 | 0 |
|
127 | 0 | done: |
128 | 0 | OPENSSL_free(buf); |
129 | 0 | BN_CTX_free(ctx); |
130 | 0 | EVP_MD_CTX_free(hash); |
131 | 0 | return rc; |
132 | 0 | } |