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:
Mon Oct 08 17:00:06 2018 +0100
Revision:
75:33f1c34c8a2d
Parent:
63:5e7be856a68b
Child:
78:2749cf972e5f
Merge pull request #126 from andresag01/line-endings

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