OpenVPN 3 Core Library
Loading...
Searching...
No Matches
encrypt_chm.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12// General-purpose OpenVPN protocol encrypt method (CBC/HMAC) that is independent of the underlying CRYPTO_API
13
14#ifndef OPENVPN_CRYPTO_ENCRYPT_CHM_H
15#define OPENVPN_CRYPTO_ENCRYPT_CHM_H
16
17#include <cstring>
18#include <utility>
19
29
30namespace openvpn {
31template <typename CRYPTO_API>
33{
34 public:
35 OPENVPN_SIMPLE_EXCEPTION(chm_unsupported_cipher_mode);
36
38 {
39 // skip null packets
40 if (!buf.size())
41 return;
42
43 if (cipher.defined())
44 {
45 // workspace for generating IV
46 unsigned char iv_buf[CRYPTO_API::CipherContext::MAX_IV_LENGTH];
47 const size_t iv_length = cipher.iv_length();
48
49 // IV and packet ID are generated differently depending on cipher mode
50 const int cipher_mode = cipher.cipher_mode();
51 if (cipher_mode == CRYPTO_API::CipherContext::CIPH_CBC_MODE)
52 {
53 // in CBC mode, use an explicit, random IV
54 rng->rand_bytes(iv_buf, iv_length);
55
56 // generate fresh outgoing packet ID and prepend to cleartext buffer
58 }
59 else
60 {
61 throw chm_unsupported_cipher_mode();
62 }
63
64 // initialize work buffer
66
67 // encrypt from buf -> work
68 const size_t encrypt_bytes = cipher.encrypt(iv_buf, work.data(), work.max_size(), buf.c_data(), buf.size());
69 if (!encrypt_bytes)
70 {
71 buf.reset_size();
72 return;
73 }
74 work.set_size(encrypt_bytes);
75
76 // prepend the IV to the ciphertext
77 work.prepend(iv_buf, iv_length);
78
79 // HMAC the ciphertext
81
82 // return ciphertext result in buf
83 buf.swap(work);
84 }
85 else // no encryption
86 {
87 // generate fresh outgoing packet ID and prepend to cleartext buffer
89
90 // HMAC the cleartext
91 prepend_hmac(buf);
92 }
93 }
94
96 {
97 rng = std::move(rng_arg);
98 }
99
104
105 private:
106 // compute HMAC signature of data buffer,
107 // then prepend the signature to the buffer.
109 {
110 if (hmac.defined())
111 {
112 const unsigned char *content = buf.data();
113 const size_t content_size = buf.size();
114 const size_t hmac_size = hmac.output_size();
115 unsigned char *hmac_buf = buf.prepend_alloc(hmac_size);
116 hmac.hmac(hmac_buf, hmac_size, content, content_size);
117 }
118 }
119
122};
123
124} // namespace openvpn
125
126#endif // OPENVPN_CRYPTO_ENCRYPT_H
void swap(BufferAllocatedType< T_ > &other)
Swaps the contents of this BufferAllocatedType object with another BufferAllocatedType object.
Definition buffer.hpp:1799
const T * c_data() const
Returns a const pointer to the start of the buffer.
Definition buffer.hpp:1194
T * prepend_alloc(const size_t size)
Allocate space for prepending data to the buffer.
Definition buffer.hpp:1597
size_t max_size() const
Return the maximum allowable size value in T objects given the current offset (without considering re...
Definition buffer.hpp:1377
void prepend(const T *data, const size_t size)
Prepend data to the buffer.
Definition buffer.hpp:1575
size_t size() const
Returns the size of the buffer in T objects.
Definition buffer.hpp:1242
T * data()
Get a mutable pointer to the start of the array.
Definition buffer.hpp:1450
void set_size(const size_t size)
After an external method, operating on the array as a mutable unsigned char buffer,...
Definition buffer.hpp:1384
void reset_size()
Resets the size of the buffer to zero.
Definition buffer.hpp:1170
OPENVPN_SIMPLE_EXCEPTION(chm_unsupported_cipher_mode)
void prepend_hmac(BufferAllocated &buf)
CipherContext< CRYPTO_API > cipher
void set_rng(StrongRandomAPI::Ptr rng_arg)
OvpnHMAC< CRYPTO_API > hmac
BufferAllocated work
StrongRandomAPI::Ptr rng
void encrypt(BufferAllocated &buf)
PacketIDDataSend pid_send
size_t prepare(const unsigned int context, Buffer &buf) const
Definition frame.hpp:266
void prepend_next(Buffer &buf)
virtual void rand_bytes(unsigned char *buf, size_t size)=0
Fill a buffer with random bytes.
Implementation of the base classes for random number generators.