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