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