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.
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
12 #include <openssl/sm2.h>
13 #include <openssl/evp.h>
14 #include <openssl/bn.h>
17 int SM2_compute_userid_digest(uint8_t *out,
24 const EC_GROUP *group = EC_KEY_get0_group(key);
27 EVP_MD_CTX *hash = NULL;
44 hash = EVP_MD_CTX_new();
60 if (p == NULL || a == NULL || b == NULL ||
61 xG == NULL || yG == NULL || xA == NULL || yA == NULL)
64 memset(out, 0, EVP_MD_size(digest));
66 if (EVP_DigestInit(hash, digest) == 0)
70 ZA=H256(ENTLA || IDA || a || b || xG || yG || xA || yA)
73 uid_len = strlen(user_id);
75 if (uid_len >= 8192) /* too large */
78 entla = (unsigned short)(8 * uid_len);
81 if (EVP_DigestUpdate(hash, &e_byte, 1) == 0)
83 e_byte = entla & 0xFF;
84 if (EVP_DigestUpdate(hash, &e_byte, 1) == 0)
87 if (EVP_DigestUpdate(hash, user_id, uid_len) == 0)
90 if (EC_GROUP_get_curve_GFp(group, p, a, b, ctx) == 0)
93 p_bytes = BN_num_bytes(p);
94 buf = OPENSSL_zalloc(p_bytes);
96 BN_bn2binpad(a, buf, p_bytes);
97 if (EVP_DigestUpdate(hash, buf, p_bytes) == 0)
99 BN_bn2binpad(b, buf, p_bytes);
100 if (EVP_DigestUpdate(hash, buf, p_bytes) == 0)
102 EC_POINT_get_affine_coordinates_GFp(group,
103 EC_GROUP_get0_generator(group),
105 BN_bn2binpad(xG, buf, p_bytes);
106 if (EVP_DigestUpdate(hash, buf, p_bytes) == 0)
108 BN_bn2binpad(yG, buf, p_bytes);
109 if (EVP_DigestUpdate(hash, buf, p_bytes) == 0)
112 EC_POINT_get_affine_coordinates_GFp(group,
113 EC_KEY_get0_public_key(key),
115 BN_bn2binpad(xA, buf, p_bytes);
116 if (EVP_DigestUpdate(hash, buf, p_bytes) == 0)
118 BN_bn2binpad(yA, buf, p_bytes);
119 if (EVP_DigestUpdate(hash, buf, p_bytes) == 0)
122 if (EVP_DigestFinal(hash, out, NULL) == 0)
130 EVP_MD_CTX_free(hash);