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:
Thu Nov 09 09:15:07 2017 +0000
Revision:
48:6b6340f5cdc3
Parent:
36:454dcefc8453
Child:
63:5e7be856a68b
Change Arm trademarks in the examples' source files

.
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 "mbedtls/platform.h"
mbed_official 36:454dcefc8453 32
mbed_official 36:454dcefc8453 33 #include <string.h>
mbed_official 36:454dcefc8453 34
mbed_official 36:454dcefc8453 35 const unsigned char Authcrypt::secret_key[16] = {
mbed_official 36:454dcefc8453 36 0xf4, 0x82, 0xc6, 0x70, 0x3c, 0xc7, 0x61, 0x0a,
mbed_official 36:454dcefc8453 37 0xb9, 0xa0, 0xb8, 0xe9, 0x87, 0xb8, 0xc1, 0x72,
mbed_official 36:454dcefc8453 38 };
mbed_official 36:454dcefc8453 39
mbed_official 36:454dcefc8453 40 const char Authcrypt::message[] = "Some things are better left unread";
mbed_official 36:454dcefc8453 41
mbed_official 36:454dcefc8453 42 const char Authcrypt::metadata[] = "eg sequence number, routing info";
mbed_official 36:454dcefc8453 43
mbed_official 36:454dcefc8453 44 Authcrypt::Authcrypt()
mbed_official 36:454dcefc8453 45 {
mbed_official 36:454dcefc8453 46 memset(ciphertext, 0, sizeof(ciphertext));
mbed_official 36:454dcefc8453 47 memset(decrypted, 0, sizeof(decrypted));
mbed_official 36:454dcefc8453 48
mbed_official 36:454dcefc8453 49 mbedtls_entropy_init(&entropy);
mbed_official 36:454dcefc8453 50 mbedtls_ctr_drbg_init(&drbg);
mbed_official 36:454dcefc8453 51 mbedtls_cipher_init(&cipher);
mbed_official 36:454dcefc8453 52 }
mbed_official 36:454dcefc8453 53
mbed_official 36:454dcefc8453 54 Authcrypt::~Authcrypt()
mbed_official 36:454dcefc8453 55 {
mbed_official 36:454dcefc8453 56 memset(ciphertext, 0, sizeof(ciphertext));
mbed_official 36:454dcefc8453 57 memset(decrypted, 0, sizeof(decrypted));
mbed_official 36:454dcefc8453 58
mbed_official 36:454dcefc8453 59 mbedtls_cipher_free(&cipher);
mbed_official 36:454dcefc8453 60 mbedtls_ctr_drbg_free(&drbg);
mbed_official 36:454dcefc8453 61 mbedtls_entropy_free(&entropy);
mbed_official 36:454dcefc8453 62 }
mbed_official 36:454dcefc8453 63
mbed_official 36:454dcefc8453 64 int Authcrypt::run()
mbed_official 36:454dcefc8453 65 {
mbed_official 36:454dcefc8453 66 mbedtls_printf("\r\n\r\n");
mbed_official 36:454dcefc8453 67 print_hex("plaintext message",
mbed_official 36:454dcefc8453 68 reinterpret_cast<const unsigned char *>(message),
mbed_official 36:454dcefc8453 69 sizeof(message));
mbed_official 36:454dcefc8453 70
mbed_official 36:454dcefc8453 71 /*
mbed_official 36:454dcefc8453 72 * Seed the PRNG using the entropy pool, and throw in our secret key as an
mbed_official 36:454dcefc8453 73 * additional source of randomness.
mbed_official 36:454dcefc8453 74 */
mbed_official 36:454dcefc8453 75 int ret = mbedtls_ctr_drbg_seed(&drbg, mbedtls_entropy_func, &entropy,
mbed_official 36:454dcefc8453 76 secret_key, sizeof(secret_key));
mbed_official 36:454dcefc8453 77 if (ret != 0) {
mbed_official 36:454dcefc8453 78 mbedtls_printf("mbedtls_ctr_drbg_seed() returned -0x%04X\r\n", -ret);
mbed_official 36:454dcefc8453 79 return ret;
mbed_official 36:454dcefc8453 80 }
mbed_official 36:454dcefc8453 81
mbed_official 36:454dcefc8453 82 /* Setup AES-CCM contex */
mbed_official 36:454dcefc8453 83 ret = mbedtls_cipher_setup(&cipher,
mbed_official 36:454dcefc8453 84 mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CCM));
mbed_official 36:454dcefc8453 85 if (ret != 0) {
mbed_official 36:454dcefc8453 86 mbedtls_printf("mbedtls_cipher_setup() returned -0x%04X\r\n", -ret);
mbed_official 36:454dcefc8453 87 return ret;
mbed_official 36:454dcefc8453 88 }
mbed_official 36:454dcefc8453 89
mbed_official 36:454dcefc8453 90 ret = mbedtls_cipher_setkey(&cipher, secret_key,
mbed_official 36:454dcefc8453 91 8 * sizeof(secret_key), MBEDTLS_ENCRYPT);
mbed_official 36:454dcefc8453 92 if (ret != 0) {
mbed_official 36:454dcefc8453 93 mbedtls_printf("mbedtls_cipher_setkey() returned -0x%04X\r\n", -ret);
mbed_official 36:454dcefc8453 94 return ret;
mbed_official 36:454dcefc8453 95 }
mbed_official 36:454dcefc8453 96
mbed_official 36:454dcefc8453 97 /*
mbed_official 36:454dcefc8453 98 * Encrypt-authenticate the message and authenticate additional data
mbed_official 36:454dcefc8453 99 *
mbed_official 36:454dcefc8453 100 * First generate a random 8-byte nonce.
mbed_official 36:454dcefc8453 101 * Put it directly in the output buffer as the recipient will need it.
mbed_official 36:454dcefc8453 102 *
mbed_official 36:454dcefc8453 103 * Warning: you must never re-use the same (key, nonce) pair. One of
mbed_official 36:454dcefc8453 104 * the best ways to ensure this to use a counter for the nonce.
mbed_official 36:454dcefc8453 105 * However, this means you should save the counter accross rebots, if
mbed_official 36:454dcefc8453 106 * the key is a long-term one. The alternative we choose here is to
mbed_official 36:454dcefc8453 107 * generate the nonce randomly. However it only works if you have a
mbed_official 36:454dcefc8453 108 * good source of randomness.
mbed_official 36:454dcefc8453 109 */
mbed_official 36:454dcefc8453 110 const size_t nonce_len = 8;
mbed_official 36:454dcefc8453 111 mbedtls_ctr_drbg_random(&drbg, ciphertext, nonce_len);
mbed_official 36:454dcefc8453 112
mbed_official 36:454dcefc8453 113 size_t ciphertext_len = 0;
mbed_official 36:454dcefc8453 114 /*
mbed_official 36:454dcefc8453 115 * Go for a conservative 16-byte (128-bit) tag and append it to the
mbed_official 36:454dcefc8453 116 * ciphertext
mbed_official 36:454dcefc8453 117 */
mbed_official 36:454dcefc8453 118 const size_t tag_len = 16;
mbed_official 36:454dcefc8453 119 ret = mbedtls_cipher_auth_encrypt(&cipher, ciphertext, nonce_len,
mbed_official 36:454dcefc8453 120 reinterpret_cast<const unsigned char *>(metadata),
mbed_official 36:454dcefc8453 121 sizeof(metadata),
mbed_official 36:454dcefc8453 122 reinterpret_cast<const unsigned char *>(message),
mbed_official 36:454dcefc8453 123 sizeof(message),
mbed_official 36:454dcefc8453 124 ciphertext + nonce_len, &ciphertext_len,
mbed_official 36:454dcefc8453 125 ciphertext + nonce_len + sizeof(message),
mbed_official 36:454dcefc8453 126 tag_len);
mbed_official 36:454dcefc8453 127 if (ret != 0) {
mbed_official 36:454dcefc8453 128 mbedtls_printf("mbedtls_cipher_auth_encrypt() returned -0x%04X\r\n",
mbed_official 36:454dcefc8453 129 -ret);
mbed_official 36:454dcefc8453 130 return ret;
mbed_official 36:454dcefc8453 131 }
mbed_official 36:454dcefc8453 132 ciphertext_len += nonce_len + tag_len;
mbed_official 36:454dcefc8453 133
mbed_official 36:454dcefc8453 134 /*
mbed_official 36:454dcefc8453 135 * The following information should now be transmitted:
mbed_official 36:454dcefc8453 136 * - First ciphertext_len bytes of ciphertext buffer
mbed_official 36:454dcefc8453 137 * - Metadata if not already transmitted elsewhere
mbed_official 36:454dcefc8453 138 */
mbed_official 36:454dcefc8453 139 print_hex("ciphertext", ciphertext, ciphertext_len);
mbed_official 36:454dcefc8453 140
mbed_official 36:454dcefc8453 141 /* Decrypt-authenticate */
mbed_official 36:454dcefc8453 142 size_t decrypted_len = 0;
mbed_official 36:454dcefc8453 143
mbed_official 36:454dcefc8453 144 ret = mbedtls_cipher_setkey(&cipher, secret_key, 8 * sizeof(secret_key),
mbed_official 36:454dcefc8453 145 MBEDTLS_DECRYPT);
mbed_official 36:454dcefc8453 146 if (ret != 0) {
mbed_official 36:454dcefc8453 147 mbedtls_printf("mbedtls_cipher_setkey() returned -0x%04X\r\n", -ret);
mbed_official 36:454dcefc8453 148 return ret;
mbed_official 36:454dcefc8453 149 }
mbed_official 36:454dcefc8453 150
mbed_official 36:454dcefc8453 151 ret = mbedtls_cipher_auth_decrypt(&cipher, ciphertext, nonce_len,
mbed_official 36:454dcefc8453 152 reinterpret_cast<const unsigned char *>(metadata),
mbed_official 36:454dcefc8453 153 sizeof(metadata), ciphertext + nonce_len,
mbed_official 36:454dcefc8453 154 ciphertext_len - nonce_len - tag_len, decrypted,
mbed_official 36:454dcefc8453 155 &decrypted_len, ciphertext + ciphertext_len - tag_len,
mbed_official 36:454dcefc8453 156 tag_len);
mbed_official 36:454dcefc8453 157 /* Checking the return code is CRITICAL for security here */
mbed_official 36:454dcefc8453 158 if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) {
mbed_official 36:454dcefc8453 159 mbedtls_printf("Something bad is happening! Data is not "
mbed_official 36:454dcefc8453 160 "authentic!\r\n");
mbed_official 36:454dcefc8453 161 return ret;
mbed_official 36:454dcefc8453 162 } else if (ret != 0) {
mbed_official 36:454dcefc8453 163 mbedtls_printf("mbedtls_cipher_authdecrypt() returned -0x%04X\r\n",
mbed_official 36:454dcefc8453 164 -ret);
mbed_official 36:454dcefc8453 165 return ret;
mbed_official 36:454dcefc8453 166 }
mbed_official 36:454dcefc8453 167
mbed_official 36:454dcefc8453 168 print_hex("decrypted", decrypted, decrypted_len);
mbed_official 36:454dcefc8453 169
mbed_official 36:454dcefc8453 170 mbedtls_printf("\r\nDONE\r\n");
mbed_official 36:454dcefc8453 171
mbed_official 36:454dcefc8453 172 return 0;
mbed_official 36:454dcefc8453 173 }
mbed_official 36:454dcefc8453 174
mbed_official 36:454dcefc8453 175 void Authcrypt::print_hex(const char *title,
mbed_official 36:454dcefc8453 176 const unsigned char buf[],
mbed_official 36:454dcefc8453 177 size_t len)
mbed_official 36:454dcefc8453 178 {
mbed_official 36:454dcefc8453 179 mbedtls_printf("%s: ", title);
mbed_official 36:454dcefc8453 180
mbed_official 36:454dcefc8453 181 for (size_t i = 0; i < len; i++)
mbed_official 36:454dcefc8453 182 mbedtls_printf("%02x", buf[i]);
mbed_official 36:454dcefc8453 183
mbed_official 36:454dcefc8453 184 mbedtls_printf("\r\n");
mbed_official 36:454dcefc8453 185 }