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
authcrypt.cpp
00001 /* 00002 * Hello world example of using the authenticated encryption with Mbed TLS 00003 * 00004 * Copyright (C) 2017, Arm Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 */ 00019 00020 #include "authcrypt.h" 00021 00022 #include "mbed.h" 00023 00024 #include "mbedtls/cipher.h" 00025 #include "mbedtls/entropy.h" 00026 #include "mbedtls/ctr_drbg.h" 00027 #if DEBUG_LEVEL > 0 00028 #include "mbedtls/debug.h" 00029 #endif 00030 00031 #include <string.h> 00032 00033 const unsigned char Authcrypt::secret_key[16] = { 00034 0xf4, 0x82, 0xc6, 0x70, 0x3c, 0xc7, 0x61, 0x0a, 00035 0xb9, 0xa0, 0xb8, 0xe9, 0x87, 0xb8, 0xc1, 0x72, 00036 }; 00037 00038 const char Authcrypt::message[] = "Some things are better left unread"; 00039 00040 const char Authcrypt::metadata[] = "eg sequence number, routing info"; 00041 00042 Authcrypt::Authcrypt() 00043 { 00044 memset(ciphertext, 0, sizeof(ciphertext)); 00045 memset(decrypted, 0, sizeof(decrypted)); 00046 00047 mbedtls_entropy_init(&entropy); 00048 mbedtls_ctr_drbg_init(&drbg); 00049 mbedtls_cipher_init(&cipher); 00050 } 00051 00052 Authcrypt::~Authcrypt() 00053 { 00054 memset(ciphertext, 0, sizeof(ciphertext)); 00055 memset(decrypted, 0, sizeof(decrypted)); 00056 00057 mbedtls_cipher_free(&cipher); 00058 mbedtls_ctr_drbg_free(&drbg); 00059 mbedtls_entropy_free(&entropy); 00060 } 00061 00062 int Authcrypt::run() 00063 { 00064 mbedtls_printf("\n\n"); 00065 print_hex("plaintext message", 00066 reinterpret_cast<const unsigned char *>(message), 00067 sizeof(message)); 00068 00069 /* 00070 * Seed the PRNG using the entropy pool, and throw in our secret key as an 00071 * additional source of randomness. 00072 */ 00073 int ret = mbedtls_ctr_drbg_seed(&drbg, mbedtls_entropy_func, &entropy, 00074 secret_key, sizeof(secret_key)); 00075 if (ret != 0) { 00076 mbedtls_printf("mbedtls_ctr_drbg_seed() returned -0x%04X\n", -ret); 00077 return ret; 00078 } 00079 00080 /* Setup AES-CCM contex */ 00081 ret = mbedtls_cipher_setup(&cipher, 00082 mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CCM)); 00083 if (ret != 0) { 00084 mbedtls_printf("mbedtls_cipher_setup() returned -0x%04X\n", -ret); 00085 return ret; 00086 } 00087 00088 ret = mbedtls_cipher_setkey(&cipher, secret_key, 00089 8 * sizeof(secret_key), MBEDTLS_ENCRYPT); 00090 if (ret != 0) { 00091 mbedtls_printf("mbedtls_cipher_setkey() returned -0x%04X\n", -ret); 00092 return ret; 00093 } 00094 00095 /* 00096 * Encrypt-authenticate the message and authenticate additional data 00097 * 00098 * First generate a random 8-byte nonce. 00099 * Put it directly in the output buffer as the recipient will need it. 00100 * 00101 * Warning: you must never re-use the same (key, nonce) pair. One of 00102 * the best ways to ensure this to use a counter for the nonce. 00103 * However, this means you should save the counter accross rebots, if 00104 * the key is a long-term one. The alternative we choose here is to 00105 * generate the nonce randomly. However it only works if you have a 00106 * good source of randomness. 00107 */ 00108 const size_t nonce_len = 8; 00109 mbedtls_ctr_drbg_random(&drbg, ciphertext, nonce_len); 00110 00111 size_t ciphertext_len = 0; 00112 /* 00113 * Go for a conservative 16-byte (128-bit) tag and append it to the 00114 * ciphertext 00115 */ 00116 const size_t tag_len = 16; 00117 ret = mbedtls_cipher_auth_encrypt(&cipher, ciphertext, nonce_len, 00118 reinterpret_cast<const unsigned char *>(metadata), 00119 sizeof(metadata), 00120 reinterpret_cast<const unsigned char *>(message), 00121 sizeof(message), 00122 ciphertext + nonce_len, &ciphertext_len, 00123 ciphertext + nonce_len + sizeof(message), 00124 tag_len); 00125 if (ret != 0) { 00126 mbedtls_printf("mbedtls_cipher_auth_encrypt() returned -0x%04X\n", 00127 -ret); 00128 return ret; 00129 } 00130 ciphertext_len += nonce_len + tag_len; 00131 00132 /* 00133 * The following information should now be transmitted: 00134 * - First ciphertext_len bytes of ciphertext buffer 00135 * - Metadata if not already transmitted elsewhere 00136 */ 00137 print_hex("ciphertext", ciphertext, ciphertext_len); 00138 00139 /* Decrypt-authenticate */ 00140 size_t decrypted_len = 0; 00141 00142 ret = mbedtls_cipher_setkey(&cipher, secret_key, 8 * sizeof(secret_key), 00143 MBEDTLS_DECRYPT); 00144 if (ret != 0) { 00145 mbedtls_printf("mbedtls_cipher_setkey() returned -0x%04X\n", -ret); 00146 return ret; 00147 } 00148 00149 ret = mbedtls_cipher_auth_decrypt(&cipher, ciphertext, nonce_len, 00150 reinterpret_cast<const unsigned char *>(metadata), 00151 sizeof(metadata), ciphertext + nonce_len, 00152 ciphertext_len - nonce_len - tag_len, decrypted, 00153 &decrypted_len, ciphertext + ciphertext_len - tag_len, 00154 tag_len); 00155 /* Checking the return code is CRITICAL for security here */ 00156 if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) { 00157 mbedtls_printf("Something bad is happening! Data is not " 00158 "authentic!\n"); 00159 return ret; 00160 } else if (ret != 0) { 00161 mbedtls_printf("mbedtls_cipher_authdecrypt() returned -0x%04X\n", 00162 -ret); 00163 return ret; 00164 } 00165 00166 print_hex("decrypted", decrypted, decrypted_len); 00167 00168 mbedtls_printf("\nDONE\n"); 00169 00170 return 0; 00171 } 00172 00173 void Authcrypt::print_hex(const char *title, 00174 const unsigned char buf[], 00175 size_t len) 00176 { 00177 mbedtls_printf("%s: ", title); 00178 00179 for (size_t i = 0; i < len; i++) 00180 mbedtls_printf("%02x", buf[i]); 00181 00182 mbedtls_printf("\n"); 00183 }
Generated on Thu Jul 14 2022 01:25:58 by 1.7.2