Hello world example of using the authenticated encryption with mbed TLS. The canonical source for this example lives at https://github.com/ARMmbed/mbed-os-example-tls

mbed TLS Benchmark example on mbed OS

This application performs authenticated encryption and authenticated decryption of a buffer. It serves as a tutorial for the basic authenticated encryption functions of mbed TLS.

Getting started

Building with mbed CLI

If you'd like to use mbed CLI to build this, then you should set up your environment if you have not done so already. For instructions, refer to the main readme. The instructions on this page relate to using the developer.mbed.org Online Compiler

Import the program in to the Online Compiler, select your board from the drop down in the top right hand corner and then compile the application. Once it has built, you can drag and drop the binary onto your device.

Monitoring the application

The output in the terminal window should be similar to this:

terminal output

plaintext message: 536f6d65207468696e67732061726520626574746572206c65667420756e7265616400
ciphertext: c57f7afb94f14c7977d785d08682a2596bd62ee9dcf216b8cccd997afee9b402f5de1739e8e6467aa363749ef39392e5c66622b01c7203ec0a3d14
decrypted: 536f6d65207468696e67732061726520626574746572206c65667420756e7265616400

DONE
Committer:
mbed_official
Date:
Wed Oct 31 16:00:05 2018 +0000
Revision:
78:2749cf972e5f
Parent:
75:33f1c34c8a2d
Merge pull request #199 from RonEld/set_NULL_as_platform_context

Change mbedtls_platform_context parameter to NULL
.
Commit copied from https://github.com/ARMmbed/mbed-os-example-tls

Who changed what in which revision?

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