]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/sm2/sm2_za.c
crypto/sm2/sm2_za.c: include internal/numbers.h
[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"
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 20int 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}