Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
OpenSSLAesCcm.hxx
Go to the documentation of this file.
1
41#ifndef _UTILS_OPENSSLAESCCM_HXX_
42#define _UTILS_OPENSSLAESCCM_HXX_
43
44#include <string>
45#include <openssl/evp.h>
46
47#include "utils/logging.h"
48
49#ifndef ASSERT_EQ
50#define ASSERT_EQ(expected, actual) \
51 do \
52 { \
53 int __ret = (actual); \
54 int __e = (expected); \
55 if (__e != __ret) \
56 { \
57 LOG(FATAL, "At %s(%d): Failed assertion " #actual \
58 ": expected %d actual %d\n", \
59 __FILE__, __LINE__, __e, __ret); \
60 HASSERT(0); \
61 } \
62 } while (false)
63#endif
64
72void CCMEncrypt(const std::string &aes_key, const std::string &iv,
73 const std::string &auth_data, const std::string &plain, std::string *cipher,
74 std::string *tag)
75{
76 ASSERT_EQ(32u, aes_key.size());
77 ASSERT_EQ(11u, iv.size());
78
79 EVP_CIPHER_CTX *ctx;
80 ctx = EVP_CIPHER_CTX_new();
81
82 ASSERT_EQ(1,
83 EVP_EncryptInit_ex(ctx, EVP_aes_256_ccm(), nullptr, nullptr, nullptr));
84
85 constexpr int taglen = 16;
86 constexpr int Lvalue = 4;
87 constexpr int ivlen = 15 - Lvalue;
88 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, taglen, nullptr);
89 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, ivlen, NULL);
90 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, Lvalue, NULL);
91 // ASSERT_EQ(ivlen, EVP_CIPHER_CTX_iv_length(ctx));
92 int key_length = EVP_CIPHER_CTX_key_length(ctx);
93 ASSERT_EQ(32, key_length);
94 ASSERT_EQ(
95 1, EVP_EncryptInit_ex(ctx, nullptr, nullptr,
96 (const uint8_t *)aes_key.data(), (const uint8_t *)iv.data()));
97
98 int outlen = -1;
99 ASSERT_EQ(
100 1, EVP_EncryptUpdate(ctx, nullptr, &outlen, nullptr, plain.size()));
101
102 ASSERT_EQ(1, EVP_EncryptUpdate(ctx, nullptr, &outlen,
103 (const uint8_t *)auth_data.data(), auth_data.size()));
104 cipher->resize(plain.size() + 16);
105 ASSERT_EQ(1, EVP_EncryptUpdate(ctx, (uint8_t *)&((*cipher)[0]), &outlen,
106 (const uint8_t *)plain.data(), plain.size()));
107 HASSERT(outlen <= (int)cipher->size());
108 LOG(INFO, "encupdate: in=%d, ret=%d", (int)plain.size(), outlen);
109 cipher->resize(outlen);
110 // CCM always outputs the same number of bytes than the input.
111 ASSERT_EQ((int)plain.size(), outlen);
112 int ret = -1;
113 ASSERT_EQ(1, EVP_EncryptFinal_ex(ctx, (uint8_t *)&((*cipher)[0]), &ret));
114 ASSERT_EQ(0, ret);
115
116 tag->resize(16);
117 ASSERT_EQ(
118 1, EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, 16, &((*tag)[0])));
119
120 EVP_CIPHER_CTX_free(ctx);
121}
122
124class MD
125{
126public:
131 static std::string SHA256(const void *data, size_t len)
132 {
133 EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
134 std::string ret(32, 0);
135 EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
136 EVP_DigestUpdate(mdctx, data, len);
137 unsigned int md_len;
138 EVP_DigestFinal_ex(mdctx, (uint8_t *)&ret[0], &md_len);
139 HASSERT(md_len == 32);
140 EVP_MD_CTX_free(mdctx);
141 return ret;
142 }
143
144private:
146 MD();
147};
148
149#endif // _UTILS_OPENSSLAESCCM_HXX_
void CCMEncrypt(const std::string &aes_key, const std::string &iv, const std::string &auth_data, const std::string &plain, std::string *cipher, std::string *tag)
Performs authenticated encryption using AES-CCM.
Helper class to do hashing algorithms via OpenSSL library.
MD()
This class cannot be instantiated.
static std::string SHA256(const void *data, size_t len)
Computes a SHA256 hash of a given data payload.
#define LOG(level, message...)
Conditionally write a message to the logging output.
Definition logging.h:99
static const int INFO
Loglevel that is printed by default, reporting some status information.
Definition logging.h:57
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138