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 Aug 04 15:45:10 2016 +0100
Revision:
5:97e046e0e2b1
Parent:
0:9a918c8d34dc
Child:
36:454dcefc8453
Correct HAVEGE entropy in the configurations.


Commit copied from https://github.com/ARMmbed/mbed-os-example-tls

Who changed what in which revision?

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