Coverage Report

Created: 2018-08-29 13:53

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