]>
Commit | Line | Data |
---|---|---|
3d328a44 | 1 | /* |
b0edda11 | 2 | * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. |
3d328a44 JL |
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 | ||
e425f90f | 12 | #include "internal/sm2.h" |
245be530 MC |
13 | #include "internal/sm2err.h" |
14 | #include <openssl/err.h> | |
3d328a44 JL |
15 | #include <openssl/evp.h> |
16 | #include <openssl/bn.h> | |
17 | #include <string.h> | |
18 | ||
2167239a | 19 | int sm2_compute_userid_digest(uint8_t *out, |
3d328a44 JL |
20 | const EVP_MD *digest, |
21 | const char *user_id, | |
22 | const EC_KEY *key) | |
23 | { | |
24 | int rc = 0; | |
3d328a44 | 25 | const EC_GROUP *group = EC_KEY_get0_group(key); |
3d328a44 JL |
26 | BN_CTX *ctx = NULL; |
27 | EVP_MD_CTX *hash = NULL; | |
3d328a44 JL |
28 | BIGNUM *p = NULL; |
29 | BIGNUM *a = NULL; | |
30 | BIGNUM *b = NULL; | |
3d328a44 JL |
31 | BIGNUM *xG = NULL; |
32 | BIGNUM *yG = NULL; | |
33 | BIGNUM *xA = NULL; | |
34 | BIGNUM *yA = NULL; | |
3d328a44 JL |
35 | int p_bytes = 0; |
36 | uint8_t *buf = NULL; | |
37 | size_t uid_len = 0; | |
38 | uint16_t entla = 0; | |
39 | uint8_t e_byte = 0; | |
40 | ||
41 | hash = EVP_MD_CTX_new(); | |
3d328a44 | 42 | ctx = BN_CTX_new(); |
245be530 MC |
43 | if (hash == NULL || ctx == NULL) { |
44 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE); | |
45 | goto done; | |
46 | } | |
3d328a44 JL |
47 | |
48 | p = BN_CTX_get(ctx); | |
49 | a = BN_CTX_get(ctx); | |
50 | b = BN_CTX_get(ctx); | |
51 | xG = BN_CTX_get(ctx); | |
52 | yG = BN_CTX_get(ctx); | |
53 | xA = BN_CTX_get(ctx); | |
54 | yA = BN_CTX_get(ctx); | |
55 | ||
245be530 MC |
56 | if (yA == NULL) { |
57 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE); | |
58 | goto done; | |
59 | } | |
3d328a44 JL |
60 | |
61 | memset(out, 0, EVP_MD_size(digest)); | |
62 | ||
245be530 MC |
63 | if (!EVP_DigestInit(hash, digest)) { |
64 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB); | |
3d328a44 | 65 | goto done; |
245be530 | 66 | } |
3d328a44 | 67 | |
245be530 | 68 | /* ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA) */ |
3d328a44 JL |
69 | |
70 | uid_len = strlen(user_id); | |
245be530 MC |
71 | if (uid_len >= (UINT16_MAX / 8)) { |
72 | /* too large */ | |
73 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, SM2_R_USER_ID_TOO_LARGE); | |
3d328a44 | 74 | goto done; |
245be530 | 75 | } |
3d328a44 | 76 | |
245be530 | 77 | entla = (uint16_t)(8 * uid_len); |
3d328a44 JL |
78 | |
79 | e_byte = entla >> 8; | |
245be530 MC |
80 | if (!EVP_DigestUpdate(hash, &e_byte, 1)) { |
81 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB); | |
3d328a44 | 82 | goto done; |
245be530 | 83 | } |
3d328a44 | 84 | e_byte = entla & 0xFF; |
245be530 MC |
85 | if (!EVP_DigestUpdate(hash, &e_byte, 1) |
86 | || !EVP_DigestUpdate(hash, user_id, uid_len)) { | |
87 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB); | |
3d328a44 | 88 | goto done; |
245be530 | 89 | } |
3d328a44 | 90 | |
245be530 MC |
91 | if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) { |
92 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EC_LIB); | |
3d328a44 | 93 | goto done; |
245be530 | 94 | } |
3d328a44 JL |
95 | |
96 | p_bytes = BN_num_bytes(p); | |
97 | buf = OPENSSL_zalloc(p_bytes); | |
245be530 MC |
98 | if (buf == NULL) { |
99 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE); | |
3d328a44 | 100 | goto done; |
245be530 MC |
101 | } |
102 | ||
103 | if (BN_bn2binpad(a, buf, p_bytes) < 0 | |
104 | || !EVP_DigestUpdate(hash, buf, p_bytes) | |
105 | || BN_bn2binpad(b, buf, p_bytes) < 0 | |
106 | || !EVP_DigestUpdate(hash, buf, p_bytes) | |
107 | || !EC_POINT_get_affine_coordinates_GFp(group, | |
108 | EC_GROUP_get0_generator(group), | |
109 | xG, yG, ctx) | |
110 | || BN_bn2binpad(xG, buf, p_bytes) < 0 | |
111 | || !EVP_DigestUpdate(hash, buf, p_bytes) | |
112 | || BN_bn2binpad(yG, buf, p_bytes) < 0 | |
113 | || !EVP_DigestUpdate(hash, buf, p_bytes) | |
114 | || !EC_POINT_get_affine_coordinates_GFp(group, | |
115 | EC_KEY_get0_public_key(key), | |
116 | xA, yA, ctx) | |
117 | || BN_bn2binpad(xA, buf, p_bytes) < 0 | |
118 | || !EVP_DigestUpdate(hash, buf, p_bytes) | |
119 | || BN_bn2binpad(yA, buf, p_bytes) < 0 | |
120 | || !EVP_DigestUpdate(hash, buf, p_bytes) | |
121 | || !EVP_DigestFinal(hash, out, NULL)) { | |
122 | SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_INTERNAL_ERROR); | |
3d328a44 | 123 | goto done; |
245be530 | 124 | } |
3d328a44 JL |
125 | |
126 | rc = 1; | |
127 | ||
128 | done: | |
129 | OPENSSL_free(buf); | |
130 | BN_CTX_free(ctx); | |
131 | EVP_MD_CTX_free(hash); | |
132 | return rc; | |
133 | } |