OpenVPN 3 Core Library
Loading...
Searching...
No Matches
tokenencrypt.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#ifndef OPENVPN_CRYPTO_TOKENENCRYPT_H
13#define OPENVPN_CRYPTO_TOKENENCRYPT_H
14
15#include <string>
16#include <atomic>
17#include <cstdint> // for std::uint8_t
18
19#include <openssl/evp.h>
20
27
29
30namespace openvpn {
32{
33 public:
34 class Key
35 {
36 public:
37 static constexpr size_t SIZE = 16;
38
40 {
41 rng.rand_bytes(data, sizeof(data));
42 }
43
44 private:
45 friend class TokenEncrypt;
46 std::uint8_t data[SIZE];
47 };
48
49 // mode parameter for constructor
50 enum
51 {
53 DECRYPT = 0
54 };
55
56 TokenEncrypt(const Key &key, const int mode)
57 {
58 ctx = EVP_CIPHER_CTX_new();
59 EVP_CIPHER_CTX_reset(ctx);
60 if (!EVP_CipherInit_ex(ctx, EVP_aes_128_ecb(), nullptr, key.data, nullptr, mode))
61 {
62 EVP_CIPHER_CTX_free(ctx);
63 throw OpenSSLException("TokenEncrypt: EVP_CipherInit_ex[1] failed");
64 }
65 EVP_CIPHER_CTX_set_padding(ctx, 0);
66 }
67
69 {
70 EVP_CIPHER_CTX_free(ctx);
71 }
72
73 // Do the encrypt/decrypt
74 void operator()(std::uint8_t *dest, const std::uint8_t *src, const int size)
75 {
76 // NOTE: since this algorithm uses the ECB block cipher mode,
77 // it should only be used to encrypt/decrypt a message which
78 // is exactly equal to the AES block size (16 bytes).
79 if (size != EVP_CIPHER_CTX_block_size(ctx))
80 throw Exception("TokenEncrypt: encrypt/decrypt data must be equal to AES block size");
81 int outlen = 0;
82 if (!EVP_CipherInit_ex(ctx, nullptr, nullptr, nullptr, nullptr, -1))
83 throw OpenSSLException("TokenEncrypt: EVP_CipherInit_ex[2] failed");
84 if (!EVP_CipherUpdate(ctx, dest, &outlen, src, size))
85 throw OpenSSLException("TokenEncrypt: EVP_CipherUpdate failed");
86 // NOTE: we skip EVP_CipherFinal_ex because we are running in ECB mode without padding
87 if (outlen != size)
88 throw Exception("TokenEncrypt: unexpected output length=" + std::to_string(outlen) + " expected=" + std::to_string(size));
89 }
90
91 private:
92 TokenEncrypt(const TokenEncrypt &) = delete;
94
95 EVP_CIPHER_CTX *ctx;
96};
97
99{
101 : encrypt(key, TokenEncrypt::ENCRYPT),
102 decrypt(key, TokenEncrypt::DECRYPT)
103 {
104 }
105
108};
109} // namespace openvpn
110
111#endif
virtual void rand_bytes(unsigned char *buf, size_t size)=0
Fill a buffer with random bytes.
Abstract base class for cryptographically strong random number generators.
Definition randapi.hpp:228
Key(StrongRandomAPI &rng)
std::uint8_t data[SIZE]
static constexpr size_t SIZE
TokenEncrypt & operator=(const TokenEncrypt &)=delete
void operator()(std::uint8_t *dest, const std::uint8_t *src, const int size)
TokenEncrypt(const Key &key, const int mode)
TokenEncrypt(const TokenEncrypt &)=delete
EVP_CIPHER_CTX * ctx
Implementation of the base classes for random number generators.
TokenEncryptDecrypt(const TokenEncrypt::Key &key)