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
55 {
56 }
57
58 void init(const CryptoAlgs::Type digest, const unsigned char *key, const size_t key_size)
59 {
60 state = PRE;
65 throw digest_cannot_be_used_with_hmac(info->name());
66 if (key_size > MAX_HMAC_KEY_SIZE)
67 throw hmac_keysize_error();
68 std::memcpy(key_, key, key_size_ = key_size);
69 state = PARTIAL;
70 }
71
72 void reset() // Apple HMAC API is missing reset method, so we have to reinit
73 {
74 cond_reset(true);
75 }
76
77 void update(const unsigned char *in, const size_t size)
78 {
79 cond_reset(false);
80 CCHmacUpdate(&ctx, in, size);
81 }
82
83 size_t final(unsigned char *out)
84 {
85 cond_reset(false);
86 CCHmacFinal(&ctx, out);
87 return digest_size_;
88 }
89
90 size_t size() const
91 {
92 if (!is_initialized())
93 throw hmac_uninitialized();
94 return digest_size_;
95 }
96
97 bool is_initialized() const
98 {
99 return state >= PARTIAL;
100 }
101
102 private:
103 void cond_reset(const bool force_init)
104 {
105 switch (state)
106 {
107 case PRE:
108 throw hmac_uninitialized();
109 case READY:
110 if (!force_init)
111 return;
112 case PARTIAL:
113 CCHmacInit(&ctx, hmac_alg, key_, key_size_);
114 state = READY;
115 }
116 }
117
118 enum State
119 {
120 PRE = 0,
122 READY
123 };
124 int state;
125
127 CCHmacAlgorithm hmac_alg;
128 size_t key_size_;
130 unsigned char key_[MAX_HMAC_KEY_SIZE];
131 CCHmacContext ctx;
132};
133} // namespace openvpn::AppleCrypto
134
135#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:58
unsigned char key_[MAX_HMAC_KEY_SIZE]
Definition hmac.hpp:130
OPENVPN_SIMPLE_EXCEPTION(hmac_keysize_error)
void cond_reset(const bool force_init)
Definition hmac.hpp:103
OPENVPN_EXCEPTION(digest_cannot_be_used_with_hmac)
const DigestInfo * info
Definition hmac.hpp:126
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:77
OPENVPN_SIMPLE_EXCEPTION(hmac_uninitialized)
size_t size(const Type type)
static std::stringstream out
Definition test_path.cpp:10