OpenVPN 3 Core Library
Loading...
Searching...
No Matches
cipher.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 cipher classes that are independent of the underlying CRYPTO_API
13
14#ifndef OPENVPN_CRYPTO_CIPHER_H
15#define OPENVPN_CRYPTO_CIPHER_H
16
17#include <string>
18
24
25namespace openvpn {
26template <typename CRYPTO_API>
28{
29 public:
30 OPENVPN_SIMPLE_EXCEPTION(cipher_mode_error);
31 OPENVPN_SIMPLE_EXCEPTION(cipher_uninitialized);
32 OPENVPN_SIMPLE_EXCEPTION(cipher_init_insufficient_key_material);
33 OPENVPN_SIMPLE_EXCEPTION(cipher_internal_error);
34 OPENVPN_SIMPLE_EXCEPTION(cipher_output_buffer);
35
36 public:
38 : mode_(CRYPTO_API::CipherContext::MODE_UNDEF)
39 {
40 }
41
42 CipherContext(const CryptoAlgs::Type cipher, const StaticKey &key, const int mode)
43 : mode_(CRYPTO_API::CipherContext::MODE_UNDEF)
44 {
45 init(cipher, key, mode);
46 }
47
48 bool defined() const
49 {
50 return ctx.is_initialized();
51 }
52
53 // size of iv buffer to pass to encrypt_decrypt
54 size_t iv_length() const
55 {
56 return ctx.iv_length();
57 }
58
59 // cipher mode (such as CIPH_CBC_MODE, etc.)
60 int cipher_mode() const
61 {
62 return ctx.cipher_mode();
63 }
64
65 // size of out buffer to pass to encrypt_decrypt
66 size_t output_size(const size_t in_size) const
67 {
68 return in_size + ctx.block_size();
69 }
70
71 void init(SSLLib::Ctx libctx, const CryptoAlgs::Type cipher, const StaticKey &key, const int mode)
72 {
73 const CryptoAlgs::Alg &alg = CryptoAlgs::get(cipher);
74
75 // check that provided key is large enough
76 if (key.size() < alg.key_length())
77 throw cipher_init_insufficient_key_material();
78
79 // IV consistency check
80 if (alg.iv_length() > CRYPTO_API::CipherContext::MAX_IV_LENGTH)
81 throw cipher_internal_error();
82
83 // initialize cipher context with cipher type, key, and encrypt/decrypt mode
84 ctx.init(libctx, cipher, key.data(), mode);
85
86 // save mode in object
87 mode_ = mode;
88 }
89
90 size_t encrypt(const unsigned char *iv,
91 unsigned char *out,
92 const size_t out_size,
93 const unsigned char *in,
94 const size_t in_size)
95 {
96 if (mode_ != CRYPTO_API::CipherContext::ENCRYPT)
97 throw cipher_mode_error();
98 return encrypt_decrypt(iv, out, out_size, in, in_size);
99 }
100
101 size_t decrypt(const unsigned char *iv,
102 unsigned char *out,
103 const size_t out_size,
104 const unsigned char *in,
105 const size_t in_size)
106 {
107 if (mode_ != CRYPTO_API::CipherContext::DECRYPT)
108 throw cipher_mode_error();
109 return encrypt_decrypt(iv, out, out_size, in, in_size);
110 }
111
112 size_t encrypt_decrypt(const unsigned char *iv,
113 unsigned char *out,
114 const size_t out_size,
115 const unsigned char *in,
116 const size_t in_size)
117 {
118 if (out_size < output_size(in_size))
119 throw cipher_output_buffer();
120 ctx.reset(iv);
121 size_t outlen = 0;
122 if (!ctx.update(out, out_size, in, in_size, outlen))
123 return 0;
124 if (!ctx.final(out + outlen, out_size - outlen, outlen))
125 return 0;
126 return outlen;
127 }
128
129 private:
130 int mode_;
131 typename CRYPTO_API::CipherContext ctx;
132};
133
134} // namespace openvpn
135
136#endif // OPENVPN_CRYPTO_CIPHER_H
OPENVPN_SIMPLE_EXCEPTION(cipher_mode_error)
int cipher_mode() const
Definition cipher.hpp:60
CRYPTO_API::CipherContext ctx
Definition cipher.hpp:131
void init(SSLLib::Ctx libctx, const CryptoAlgs::Type cipher, const StaticKey &key, const int mode)
Definition cipher.hpp:71
size_t encrypt(const unsigned char *iv, unsigned char *out, const size_t out_size, const unsigned char *in, const size_t in_size)
Definition cipher.hpp:90
size_t output_size(const size_t in_size) const
Definition cipher.hpp:66
size_t iv_length() const
Definition cipher.hpp:54
size_t encrypt_decrypt(const unsigned char *iv, unsigned char *out, const size_t out_size, const unsigned char *in, const size_t in_size)
Definition cipher.hpp:112
CipherContext(const CryptoAlgs::Type cipher, const StaticKey &key, const int mode)
Definition cipher.hpp:42
OPENVPN_SIMPLE_EXCEPTION(cipher_internal_error)
OPENVPN_SIMPLE_EXCEPTION(cipher_output_buffer)
OPENVPN_SIMPLE_EXCEPTION(cipher_uninitialized)
bool defined() const
Definition cipher.hpp:48
OPENVPN_SIMPLE_EXCEPTION(cipher_init_insufficient_key_material)
size_t decrypt(const unsigned char *iv, unsigned char *out, const size_t out_size, const unsigned char *in, const size_t in_size)
Definition cipher.hpp:101
size_t key_length() const
const unsigned char * data() const
size_t size() const
const Alg & get(const Type type)
static std::stringstream out
Definition test_path.cpp:10