OpenVPN 3 Core Library
Loading...
Searching...
No Matches
hmac.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_APPLECRYPTO_CRYPTO_HMAC_H
13#define OPENVPN_APPLECRYPTO_CRYPTO_HMAC_H
14
15// Wrap the Apple HMAC API defined in <CommonCrypto/CommonHMAC.h> so that
16// it can be used as part of the crypto layer of the OpenVPN core.
17
18#include <string>
19#include <cstring>
20
21#include <CommonCrypto/CommonHMAC.h>
22
26
27namespace openvpn::AppleCrypto {
29{
30 HMACContext(const HMACContext &) = delete;
31 HMACContext &operator=(const HMACContext &) = delete;
32
33 public:
34 OPENVPN_EXCEPTION(digest_cannot_be_used_with_hmac);
35 OPENVPN_SIMPLE_EXCEPTION(hmac_uninitialized);
36 OPENVPN_SIMPLE_EXCEPTION(hmac_keysize_error);
37
38 enum
39 {
42 };
43
45 {
46 state = PRE;
47 }
48
49 HMACContext(const CryptoAlgs::Type digest, const unsigned char *key, const size_t key_size)
50 {
51 init(digest, key, key_size);
52 }
53
54 ~HMACContext() = default;
55
56 void init(const CryptoAlgs::Type digest, const unsigned char *key, const size_t key_size)
57 {
58 state = PRE;
63 throw digest_cannot_be_used_with_hmac(info->name());
64 if (key_size > MAX_HMAC_KEY_SIZE)
65 throw hmac_keysize_error();
66 std::memcpy(key_, key, key_size_ = key_size);
67 state = PARTIAL;
68 }
69
70 void reset() // Apple HMAC API is missing reset method, so we have to reinit
71 {
72 cond_reset(true);
73 }
74
75 void update(const unsigned char *in, const size_t size)
76 {
77 cond_reset(false);
78 CCHmacUpdate(&ctx, in, size);
79 }
80
81 size_t final(unsigned char *out)
82 {
83 cond_reset(false);
84 CCHmacFinal(&ctx, out);
85 return digest_size_;
86 }
87
88 size_t size() const
89 {
90 if (!is_initialized())
91 throw hmac_uninitialized();
92 return digest_size_;
93 }
94
95 bool is_initialized() const
96 {
97 return state >= PARTIAL;
98 }
99
100 private:
101 void cond_reset(const bool force_init)
102 {
103 switch (state)
104 {
105 case PRE:
106 throw hmac_uninitialized();
107 case READY:
108 if (!force_init)
109 return;
110 case PARTIAL:
111 CCHmacInit(&ctx, hmac_alg, key_, key_size_);
112 state = READY;
113 }
114 }
115
116 enum State
117 {
118 PRE = 0,
120 READY
121 };
122 int state;
123
125 CCHmacAlgorithm hmac_alg;
126 size_t key_size_;
128 unsigned char key_[MAX_HMAC_KEY_SIZE];
129 CCHmacContext ctx;
130};
131} // namespace openvpn::AppleCrypto
132
133#endif
static const DigestInfo * digest_type(const CryptoAlgs::Type alg)
Definition digest.hpp:225
const char * name() const
Definition digest.hpp:116
CCHmacAlgorithm hmac_alg() const
Definition digest.hpp:128
void init(const CryptoAlgs::Type digest, const unsigned char *key, const size_t key_size)
Definition hmac.hpp:56
unsigned char key_[MAX_HMAC_KEY_SIZE]
Definition hmac.hpp:128
OPENVPN_SIMPLE_EXCEPTION(hmac_keysize_error)
void cond_reset(const bool force_init)
Definition hmac.hpp:101
OPENVPN_EXCEPTION(digest_cannot_be_used_with_hmac)
const DigestInfo * info
Definition hmac.hpp:124
HMACContext(const HMACContext &)=delete
HMACContext & operator=(const HMACContext &)=delete
HMACContext(const CryptoAlgs::Type digest, const unsigned char *key, const size_t key_size)
Definition hmac.hpp:49
void update(const unsigned char *in, const size_t size)
Definition hmac.hpp:75
OPENVPN_SIMPLE_EXCEPTION(hmac_uninitialized)
size_t size(const Type type)
static std::stringstream out
Definition test_path.cpp:10