Coverage Report

Created: 2026-04-10 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rnp/src/librepgp/v2_seipd.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2023, [MTG AG](https://www.mtg.de).
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without modification,
6
 * are permitted provided that the following conditions are met:
7
 *
8
 * 1.  Redistributions of source code must retain the above copyright notice,
9
 *     this list of conditions and the following disclaimer.
10
 *
11
 * 2.  Redistributions in binary form must reproduce the above copyright notice,
12
 *     this list of conditions and the following disclaimer in the documentation
13
 *     and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#include "config.h"
28
29
#if defined(ENABLE_CRYPTO_REFRESH)
30
31
#include "v2_seipd.h"
32
#include "logging.h"
33
#include "crypto/hkdf.hpp"
34
35
seipd_v2_aead_fields_t
36
seipd_v2_key_and_nonce_derivation(pgp_seipdv2_hdr_t &hdr, uint8_t *sesskey)
37
0
{
38
0
    auto hkdf = rnp::Hkdf::create(PGP_HASH_SHA256);
39
40
0
    size_t   sesskey_len = pgp_key_size(hdr.cipher_alg);
41
0
    uint32_t nonce_size = 0;
42
0
    uint32_t key_size = pgp_key_size(hdr.cipher_alg);
43
44
0
    switch (hdr.aead_alg) {
45
0
    case PGP_AEAD_EAX:
46
0
        nonce_size = 16;
47
0
        break;
48
0
    case PGP_AEAD_OCB:
49
0
        nonce_size = 15;
50
0
        break;
51
0
    case PGP_AEAD_NONE:
52
0
    case PGP_AEAD_UNKNOWN:
53
0
        RNP_LOG("only EAX and OCB is supported for v2 SEIPD packets");
54
0
        throw rnp::rnp_exception(RNP_ERROR_NOT_SUPPORTED);
55
0
    }
56
0
    const uint8_t info[5] = {
57
0
      static_cast<uint8_t>(PGP_PKT_SE_IP_DATA | PGP_PTAG_ALWAYS_SET | PGP_PTAG_NEW_FORMAT),
58
0
      static_cast<uint8_t>(hdr.version),
59
0
      static_cast<uint8_t>(hdr.cipher_alg),
60
0
      static_cast<uint8_t>(hdr.aead_alg),
61
0
      hdr.chunk_size_octet};
62
0
    uint32_t             out_size = key_size + nonce_size - 8;
63
0
    std::vector<uint8_t> hkdf_out(out_size);
64
0
    hkdf->extract_expand(hdr.salt,
65
0
                         sizeof(hdr.salt),
66
0
                         sesskey,
67
0
                         sesskey_len,
68
0
                         info,
69
0
                         sizeof(info),
70
0
                         hkdf_out.data(),
71
0
                         hkdf_out.size());
72
73
0
    seipd_v2_aead_fields_t result;
74
0
    result.key = std::vector<uint8_t>(hkdf_out.data(), hkdf_out.data() + key_size);
75
0
    result.nonce =
76
0
      std::vector<uint8_t>(hkdf_out.data() + key_size, hkdf_out.data() + hkdf_out.size());
77
0
    for (uint32_t i = 0; i < 8; i++) {
78
        // fill up the nonce with zero octets
79
0
        result.nonce.push_back(0);
80
0
    }
81
0
    return result;
82
0
}
83
84
#endif