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// Wrap the Apple cipher API defined in <CommonCrypto/CommonCryptor.h> so
13// that it can be used as part of the crypto layer of the OpenVPN core.
14
15#ifndef OPENVPN_APPLECRYPTO_CRYPTO_CIPHER_H
16#define OPENVPN_APPLECRYPTO_CRYPTO_CIPHER_H
17
18#include <string>
19#include <cstring>
20
21#include <CommonCrypto/CommonCryptor.h>
22
30
33{
34 CipherContext(const CipherContext &) = delete;
36
37 public:
38 OPENVPN_SIMPLE_EXCEPTION(apple_cipher_mode_error);
39 OPENVPN_SIMPLE_EXCEPTION(apple_cipher_uninitialized);
40 OPENVPN_EXCEPTION(apple_cipher_error);
41
42 // mode parameter for constructor
43 enum
44 {
46 ENCRYPT = kCCEncrypt,
47 DECRYPT = kCCDecrypt
48 };
49
50 enum
51 {
54 };
55
57 : cinfo(nullptr), cref(nullptr)
58 {
59 }
60
62 {
63 erase();
64 }
65
66 void init(const CryptoAlgs::Type alg, const unsigned char *key, const int mode)
67 {
68 erase();
69
70 // check that mode is valid
71 if (!(mode == ENCRYPT || mode == DECRYPT))
72 throw apple_cipher_mode_error();
73
74 // initialize cipher context with cipher type
75 const CCCryptorStatus status = CCCryptorCreate(mode,
76 cipher_type(alg),
77 kCCOptionPKCS7Padding,
78 key,
80 nullptr,
81 &cref);
82 if (status != kCCSuccess)
83 throw CFException("CipherContext: CCCryptorCreate", status);
84
86 }
87
88 void reset(const unsigned char *iv)
89 {
91 const CCCryptorStatus status = CCCryptorReset(cref, iv);
92 if (status != kCCSuccess)
93 throw CFException("CipherContext: CCCryptorReset", status);
94 }
95
96 bool update(unsigned char *out,
97 const size_t max_out_size,
98 const unsigned char *in,
99 const size_t in_size,
100 size_t &out_acc)
101 {
103 size_t dataOutMoved;
104 const CCCryptorStatus status = CCCryptorUpdate(cref, in, in_size, out, max_out_size, &dataOutMoved);
105 if (status == kCCSuccess)
106 {
107 out_acc += dataOutMoved;
108 return true;
109 }
110 else
111 return false;
112 }
113
114 bool final(unsigned char *out, const size_t max_out_size, size_t &out_acc)
115 {
117 size_t dataOutMoved;
118 const CCCryptorStatus status = CCCryptorFinal(cref, out, max_out_size, &dataOutMoved);
119 if (status == kCCSuccess)
120 {
121 out_acc += dataOutMoved;
122 return true;
123 }
124 else
125 return false;
126 }
127
128 bool is_initialized() const
129 {
130 return cinfo != nullptr;
131 }
132
133 size_t iv_length() const
134 {
136 return cinfo->iv_length();
137 }
138
139 size_t block_size() const
140 {
142 return cinfo->block_size();
143 }
144
145 // return cipher mode (such as CIPH_CBC_MODE, etc.)
146 int cipher_mode() const
147 {
149 return CIPH_CBC_MODE;
150 }
151
152 private:
153 static CCAlgorithm cipher_type(const CryptoAlgs::Type alg)
154 {
155 switch (alg)
156 {
161 return kCCAlgorithmAES128;
163 return kCCAlgorithmDES;
165 return kCCAlgorithm3DES;
166#ifdef OPENVPN_PLATFORM_IPHONE
168 return kCCAlgorithmBlowfish;
169#endif
170 default:
171 OPENVPN_THROW(apple_cipher_error, CryptoAlgs::name(alg) << ": not usable");
172 }
173 }
174
175 void erase()
176 {
177 if (cinfo)
178 {
179 if (cref)
180 CCCryptorRelease(cref);
181 cref = nullptr;
182 cinfo = nullptr;
183 }
184 }
185
186 void check_initialized() const
187 {
188#ifdef OPENVPN_ENABLE_ASSERT
189 if (!cinfo)
190 throw apple_cipher_uninitialized();
191#endif
192 }
193
195 CCCryptorRef cref;
196};
197} // namespace openvpn::AppleCrypto
198
199#endif
CipherContext & operator=(const CipherContext &)=delete
OPENVPN_EXCEPTION(apple_cipher_error)
CipherContext(const CipherContext &)=delete
void reset(const unsigned char *iv)
Definition cipher.hpp:88
void init(const CryptoAlgs::Type alg, const unsigned char *key, const int mode)
Definition cipher.hpp:66
OPENVPN_SIMPLE_EXCEPTION(apple_cipher_mode_error)
bool update(unsigned char *out, const size_t max_out_size, const unsigned char *in, const size_t in_size, size_t &out_acc)
Definition cipher.hpp:96
static CCAlgorithm cipher_type(const CryptoAlgs::Type alg)
Definition cipher.hpp:153
const CryptoAlgs::Alg * cinfo
Definition cipher.hpp:194
OPENVPN_SIMPLE_EXCEPTION(apple_cipher_uninitialized)
size_t block_size() const
#define OPENVPN_THROW(exc, stuff)
size_t key_length(const Type type)
const Alg * get_ptr(const Type type)
const char * name(const KeyDerivation kd)
static std::stringstream out
Definition test_path.cpp:10