Coverage Report

Created: 2026-03-21 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/openpace/src/eac_kdf.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2010-2012 Frank Morgner and Dominik Oepen
3
 *
4
 * This file is part of OpenPACE.
5
 *
6
 * OpenPACE is free software: you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free
8
 * Software Foundation, either version 3 of the License, or (at your option)
9
 * any later version.
10
 *
11
 * OpenPACE is distributed in the hope that it will be useful, but WITHOUT ANY
12
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * OpenPACE.  If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * Additional permission under GNU GPL version 3 section 7
20
 *
21
 * If you modify this Program, or any covered work, by linking or combining it
22
 * with OpenSSL (or a modified version of that library), containing
23
 * parts covered by the terms of OpenSSL's license, the licensors of
24
 * this Program grant you additional permission to convey the resulting work.
25
 * Corresponding Source for a non-source form of such a combination shall include
26
 * the source code for the parts of OpenSSL used as well as that of the
27
 * covered work.
28
 *
29
 * If you modify this Program, or any covered work, by linking or combining it
30
 * with OpenSC (or a modified version of that library), containing
31
 * parts covered by the terms of OpenSC's license, the licensors of
32
 * this Program grant you additional permission to convey the resulting work. 
33
 * Corresponding Source for a non-source form of such a combination shall include
34
 * the source code for the parts of OpenSC used as well as that of the
35
 * covered work.
36
 */
37
38
/**
39
 * @file eac_kdf.c
40
 * @brief Key derivation functions
41
 *
42
 * @author Frank Morgner <frankmorgner@gmail.com>
43
 * @author Dominik Oepen <oepen@informatik.hu-berlin.de>
44
 */
45
46
#ifdef HAVE_CONFIG_H
47
#include "config.h"
48
#endif
49
50
#include "eac_err.h"
51
#include "eac_kdf.h"
52
#include "eac_util.h"
53
#include "misc.h"
54
#include "ssl_compat.h"
55
#ifdef _WIN32
56
#include <winsock2.h>
57
#else
58
#include <arpa/inet.h>
59
#endif
60
#include <openssl/crypto.h>
61
#include <string.h>
62
63
BUF_MEM *
64
kdf(const BUF_MEM *key, const BUF_MEM *nonce, const uint32_t counter,
65
        const KA_CTX *ka_ctx, EVP_MD_CTX *md_ctx)
66
0
{
67
0
    size_t inlen, key_len;
68
0
    BUF_MEM *in = NULL, *digest = NULL, *out = NULL;
69
70
0
    check((key && ka_ctx->md && ka_ctx->cipher), "Invalid arguments");
71
72
0
    key_len = EVP_CIPHER_key_length(ka_ctx->cipher);
73
0
    check(0 < EVP_MD_size(ka_ctx->md)
74
0
            && key_len <= (size_t) EVP_MD_size(ka_ctx->md),
75
0
            "Message digest not suitable for cipher");
76
77
0
    in = BUF_MEM_new();
78
0
    check(in, "Failed to allocate memory");
79
80
    /* Concatenate secret || nonce || counter
81
     * nonce is optional */
82
0
    if (nonce) {
83
0
        inlen = key->length + nonce->length + sizeof counter;
84
0
        check(BUF_MEM_grow(in, inlen), "Failed to allocate memory");
85
0
        memcpy(in->data, key->data, key->length);
86
0
        memcpy(in->data + key->length, nonce->data, nonce->length);
87
0
        memcpy(in->data + key->length + nonce->length, &counter, sizeof counter);
88
0
    } else {
89
0
        inlen = key->length + sizeof counter;
90
0
        check(BUF_MEM_grow(in, inlen), "Failed to allocate memory");
91
0
        memcpy(in->data, key->data, key->length);
92
0
        memcpy(in->data + key->length, &counter, sizeof counter);
93
0
    }
94
95
0
    digest = hash(ka_ctx->md, md_ctx, ka_ctx->md_engine, in);
96
0
    check(digest, "Failed to compute hash");
97
98
    /* Truncate the hash to the length of the key */
99
0
    out = BUF_MEM_create_init(digest->data, key_len);
100
101
0
    OPENSSL_cleanse(in->data, in->max);
102
0
    BUF_MEM_free(in);
103
0
    OPENSSL_cleanse(digest->data, digest->max);
104
0
    BUF_MEM_free(digest);
105
106
0
    return out;
107
108
0
err:
109
0
    if (in) {
110
0
        OPENSSL_cleanse(in->data, in->max);
111
0
        BUF_MEM_free(in);
112
0
    }
113
114
0
    return NULL;
115
0
}
116
117
BUF_MEM *
118
kdf_pi(const PACE_SEC *pi, const BUF_MEM *nonce, const KA_CTX *ctx, EVP_MD_CTX *md_ctx)
119
0
{
120
0
    BUF_MEM * out;
121
122
0
    out = kdf(pi->encoded, nonce, htonl(KDF_PI_COUNTER), ctx, md_ctx);
123
124
0
    return out;
125
0
}
126
127
BUF_MEM *
128
kdf_enc(const BUF_MEM *nonce, const KA_CTX *ctx, EVP_MD_CTX *md_ctx)
129
0
{
130
0
    check_return(ctx, "Invalid arguments");
131
132
0
    return kdf(ctx->shared_secret, nonce, htonl(KDF_ENC_COUNTER), ctx, md_ctx);
133
0
}
134
135
BUF_MEM *
136
kdf_mac(const BUF_MEM *nonce, const KA_CTX *ctx, EVP_MD_CTX *md_ctx)
137
0
{
138
0
    check_return(ctx, "Invalid arguments");
139
140
    return kdf(ctx->shared_secret, nonce, htonl(KDF_MAC_COUNTER), ctx, md_ctx);
141
0
}