Skip to content

Commit b3cebca

Browse files
Andres Amaya GarciaAndres Amaya Garcia
authored andcommitted
Split authcrypt code in .cpp and .h
1 parent ff8622c commit b3cebca

File tree

3 files changed

+297
-182
lines changed

3 files changed

+297
-182
lines changed

authcrypt/authcrypt.cpp

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* Hello world example of using the authenticated encryption with mbed TLS
3+
*
4+
* Copyright (C) 2017, ARM Limited, All Rights Reserved
5+
* SPDX-License-Identifier: Apache-2.0
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
8+
* not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
20+
#include "authcrypt.h"
21+
22+
#include "mbed.h"
23+
24+
#include "mbedtls/cipher.h"
25+
#include "mbedtls/entropy.h"
26+
#include "mbedtls/ctr_drbg.h"
27+
#if DEBUG_LEVEL > 0
28+
#include "mbedtls/debug.h"
29+
#endif
30+
31+
#include "mbedtls/platform.h"
32+
33+
#include <string.h>
34+
35+
const unsigned char Authcrypt::secret_key[16] = {
36+
0xf4, 0x82, 0xc6, 0x70, 0x3c, 0xc7, 0x61, 0x0a,
37+
0xb9, 0xa0, 0xb8, 0xe9, 0x87, 0xb8, 0xc1, 0x72,
38+
};
39+
40+
const char Authcrypt::message[] = "Some things are better left unread";
41+
42+
const char Authcrypt::metadata[] = "eg sequence number, routing info";
43+
44+
Authcrypt::Authcrypt()
45+
{
46+
memset(ciphertext, 0, sizeof(ciphertext));
47+
memset(decrypted, 0, sizeof(decrypted));
48+
49+
mbedtls_entropy_init(&entropy);
50+
mbedtls_ctr_drbg_init(&drbg);
51+
mbedtls_cipher_init(&cipher);
52+
}
53+
54+
Authcrypt::~Authcrypt()
55+
{
56+
memset(ciphertext, 0, sizeof(ciphertext));
57+
memset(decrypted, 0, sizeof(decrypted));
58+
59+
mbedtls_cipher_free(&cipher);
60+
mbedtls_ctr_drbg_free(&drbg);
61+
mbedtls_entropy_free(&entropy);
62+
}
63+
64+
int Authcrypt::run()
65+
{
66+
mbedtls_printf("\r\n\r\n");
67+
print_hex("plaintext message",
68+
reinterpret_cast<const unsigned char *>(message),
69+
sizeof(message));
70+
71+
/*
72+
* Seed the PRNG using the entropy pool, and throw in our secret key as an
73+
* additional source of randomness.
74+
*/
75+
int ret = mbedtls_ctr_drbg_seed(&drbg, mbedtls_entropy_func, &entropy,
76+
secret_key, sizeof(secret_key));
77+
if (ret != 0) {
78+
mbedtls_printf("mbedtls_ctr_drbg_seed() returned -0x%04X\r\n", -ret);
79+
return ret;
80+
}
81+
82+
/* Setup AES-CCM contex */
83+
ret = mbedtls_cipher_setup(&cipher,
84+
mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CCM));
85+
if (ret != 0) {
86+
mbedtls_printf("mbedtls_cipher_setup() returned -0x%04X\r\n", -ret);
87+
return ret;
88+
}
89+
90+
ret = mbedtls_cipher_setkey(&cipher, secret_key,
91+
8 * sizeof(secret_key), MBEDTLS_ENCRYPT);
92+
if (ret != 0) {
93+
mbedtls_printf("mbedtls_cipher_setkey() returned -0x%04X\r\n", -ret);
94+
return ret;
95+
}
96+
97+
/*
98+
* Encrypt-authenticate the message and authenticate additional data
99+
*
100+
* First generate a random 8-byte nonce.
101+
* Put it directly in the output buffer as the recipient will need it.
102+
*
103+
* Warning: you must never re-use the same (key, nonce) pair. One of
104+
* the best ways to ensure this to use a counter for the nonce.
105+
* However, this means you should save the counter accross rebots, if
106+
* the key is a long-term one. The alternative we choose here is to
107+
* generate the nonce randomly. However it only works if you have a
108+
* good source of randomness.
109+
*/
110+
const size_t nonce_len = 8;
111+
mbedtls_ctr_drbg_random(&drbg, ciphertext, nonce_len);
112+
113+
size_t ciphertext_len = 0;
114+
/*
115+
* Go for a conservative 16-byte (128-bit) tag and append it to the
116+
* ciphertext
117+
*/
118+
const size_t tag_len = 16;
119+
ret = mbedtls_cipher_auth_encrypt(&cipher, ciphertext, nonce_len,
120+
reinterpret_cast<const unsigned char *>(metadata),
121+
sizeof(metadata),
122+
reinterpret_cast<const unsigned char *>(message),
123+
sizeof(message),
124+
ciphertext + nonce_len, &ciphertext_len,
125+
ciphertext + nonce_len + sizeof(message),
126+
tag_len);
127+
if (ret != 0) {
128+
mbedtls_printf("mbedtls_cipher_auth_encrypt() returned -0x%04X\r\n",
129+
-ret);
130+
return ret;
131+
}
132+
ciphertext_len += nonce_len + tag_len;
133+
134+
/*
135+
* The following information should now be transmitted:
136+
* - First ciphertext_len bytes of ciphertext buffer
137+
* - Metadata if not already transmitted elsewhere
138+
*/
139+
print_hex("ciphertext", ciphertext, ciphertext_len);
140+
141+
/* Decrypt-authenticate */
142+
size_t decrypted_len = 0;
143+
144+
ret = mbedtls_cipher_setkey(&cipher, secret_key, 8 * sizeof(secret_key),
145+
MBEDTLS_DECRYPT);
146+
if (ret != 0) {
147+
mbedtls_printf("mbedtls_cipher_setkey() returned -0x%04X\r\n", -ret);
148+
return ret;
149+
}
150+
151+
ret = mbedtls_cipher_auth_decrypt(&cipher, ciphertext, nonce_len,
152+
reinterpret_cast<const unsigned char *>(metadata),
153+
sizeof(metadata), ciphertext + nonce_len,
154+
ciphertext_len - nonce_len - tag_len, decrypted,
155+
&decrypted_len, ciphertext + ciphertext_len - tag_len,
156+
tag_len);
157+
/* Checking the return code is CRITICAL for security here */
158+
if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) {
159+
mbedtls_printf("Something bad is happening! Data is not "
160+
"authentic!\r\n");
161+
return ret;
162+
} else if (ret != 0) {
163+
mbedtls_printf("mbedtls_cipher_authdecrypt() returned -0x%04X\r\n",
164+
-ret);
165+
return ret;
166+
}
167+
168+
print_hex("decrypted", decrypted, decrypted_len);
169+
170+
mbedtls_printf("\r\nDONE\r\n");
171+
172+
return 0;
173+
}
174+
175+
void Authcrypt::print_hex(const char *title,
176+
const unsigned char buf[],
177+
size_t len)
178+
{
179+
mbedtls_printf("%s: ", title);
180+
181+
for (size_t i = 0; i < len; i++)
182+
mbedtls_printf("%02x", buf[i]);
183+
184+
mbedtls_printf("\r\n");
185+
}

authcrypt/authcrypt.h

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Hello world example of using the authenticated encryption with mbed TLS
3+
*
4+
* Copyright (C) 2017, ARM Limited, All Rights Reserved
5+
* SPDX-License-Identifier: Apache-2.0
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
8+
* not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
20+
#ifndef _AUTHCRYPT_H_
21+
#define _AUTHCRYPT_H_
22+
23+
#include "mbedtls/cipher.h"
24+
#include "mbedtls/entropy.h"
25+
#include "mbedtls/ctr_drbg.h"
26+
27+
/**
28+
* This class implements the logic to demonstrate authenticated encryption using
29+
* mbed TLS.
30+
*/
31+
class Authcrypt
32+
{
33+
public:
34+
/**
35+
* Construct an Authcrypt instance
36+
*/
37+
Authcrypt();
38+
39+
/**
40+
* Free any allocated resources
41+
*/
42+
~Authcrypt();
43+
44+
/**
45+
* Run the authenticated encryption example
46+
*
47+
* \return 0 if successful
48+
*/
49+
int run();
50+
51+
/**
52+
* The pre-shared key
53+
*
54+
* \note This should be generated randomly and be unique to the
55+
* device/channel/etc. Just used a fixed on here for simplicity.
56+
*/
57+
static const unsigned char secret_key[16];
58+
59+
/**
60+
* Message that should be protected
61+
*/
62+
static const char message[];
63+
64+
/**
65+
* Metadata transmitted in the clear but authenticated
66+
*/
67+
static const char metadata[];
68+
69+
private:
70+
/**
71+
* Print a buffer's contents in hexadecimal
72+
*
73+
* \param[in] title
74+
* The string to print before the hex string
75+
* \param[in] buf
76+
* The buffer to print in hex
77+
* \param[in] len
78+
* The length of the buffer
79+
*/
80+
void print_hex(const char *title, const unsigned char buf[], size_t len);
81+
82+
/**
83+
* Ciphertext buffer large enough to hold message + nonce + tag
84+
*/
85+
unsigned char ciphertext[128];
86+
87+
/**
88+
* Plaintext buffer large enough to hold the decrypted message
89+
*/
90+
unsigned char decrypted[128];
91+
92+
/**
93+
* Entropy pool for seeding PRNG
94+
*/
95+
mbedtls_entropy_context entropy;
96+
97+
/**
98+
* Pseudo-random generator
99+
*/
100+
mbedtls_ctr_drbg_context drbg;
101+
102+
/**
103+
* The block cipher configuration
104+
*/
105+
mbedtls_cipher_context_t cipher;
106+
};
107+
108+
#endif /* _AUTHCRYPT_H_ */

0 commit comments

Comments
 (0)