Make SM2 functions private
[openssl.git] / crypto / sm2 / sm2_za.c
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 <openssl/evp.h>
14 #include <openssl/bn.h>
15 #include <string.h>
16
17 int 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 }