1 /*
2 * Hello world example of using the hashing functions of mbed TLS
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22 /*
23 * This program illustrates various ways of hashing a buffer.
24 * You normally need only one of these two includes.
25 */
26 #include "mbedtls/sha256.h" /* SHA-256 only */
27 #include "mbedtls/md.h" /* generic interface */
28
29 #if defined(TARGET_LIKE_MBED)
30 #include "mbed-drivers/mbed.h"
31 #endif
32 #include <cstdio>
33
print_hex(const char * title,const unsigned char buf[],size_t len)34 static void print_hex(const char *title, const unsigned char buf[], size_t len)
35 {
36 printf("%s: ", title);
37
38 for (size_t i = 0; i < len; i++)
39 printf("%02x", buf[i]);
40
41 printf("\r\n");
42 }
43
44 static const char hello_str[] = "Hello, world!";
45 static const unsigned char *hello_buffer = (const unsigned char *) hello_str;
46 static const size_t hello_len = sizeof hello_str - 1;
47
example(void)48 int example(void)
49 {
50 printf( "\r\n\r\n" );
51
52 /*
53 * Method 1: use all-in-one function of a specific SHA-xxx module
54 */
55 unsigned char output1[32]; /* SHA-256 outputs 32 bytes */
56
57 /* 0 here means use the full SHA-256, not the SHA-224 variant */
58 mbedtls_sha256(hello_buffer, hello_len, output1, 0);
59
60 print_hex("Method 1", output1, sizeof output1);
61
62
63 /*
64 * Method 2: use the streaming interface of a specific SHA-xxx module
65 * This is useful if we get our input piecewise.
66 */
67 unsigned char output2[32];
68 mbedtls_sha256_context ctx2;
69
70 mbedtls_sha256_init(&ctx2);
71 mbedtls_sha256_starts(&ctx2, 0); /* SHA-256, not 224 */
72
73 /* Simulating multiple fragments */
74 mbedtls_sha256_update(&ctx2, hello_buffer, 1);
75 mbedtls_sha256_update(&ctx2, hello_buffer + 1, 1);
76 mbedtls_sha256_update(&ctx2, hello_buffer + 2, hello_len - 2);
77
78 mbedtls_sha256_finish(&ctx2, output2);
79 print_hex("Method 2", output2, sizeof output2);
80
81 /* Or you could re-use the context by doing mbedtls_sha256_starts() again */
82 mbedtls_sha256_free(&ctx2);
83
84 /*
85 * Method 3: use all-in-one function of the generice interface
86 */
87 unsigned char output3[MBEDTLS_MD_MAX_SIZE]; /* Enough for any hash */
88
89 /* Can easily pick any hash you want, by identifier */
90 const mbedtls_md_info_t *md_info3 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
91
92 if (md_info3 == NULL)
93 {
94 printf("SHA256 not available\r\n");
95 return 1;
96 }
97
98 int ret3 = mbedtls_md(md_info3, hello_buffer, hello_len, output3);
99
100 if (ret3 != 0)
101 {
102 printf("md() returned -0x%04X\r\n", -ret3);
103 return 1;
104 }
105
106 print_hex("Method 3", output3, mbedtls_md_get_size(md_info3));
107
108
109 /*
110 * Method 4: streaming & generic interface
111 */
112 unsigned char output4[MBEDTLS_MD_MAX_SIZE]; /* Enough for any hash */
113
114 const mbedtls_md_info_t *md_info4 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
115
116 if (md_info4 == NULL)
117 {
118 printf("SHA256 not available\r\n");
119 return 1;
120 }
121
122 mbedtls_md_context_t ctx4;
123
124 mbedtls_md_init(&ctx4);
125
126 int ret4 = mbedtls_md_init_ctx(&ctx4, md_info4);
127 if (ret4 != 0)
128 {
129 printf("md_init_ctx() returned -0x%04X\r\n", -ret4);
130 return 1;
131 }
132
133 mbedtls_md_starts(&ctx4);
134
135 /* Simulating multiple fragments */
136 mbedtls_md_update(&ctx4, hello_buffer, 1);
137 mbedtls_md_update(&ctx4, hello_buffer + 1, 1);
138 mbedtls_md_update(&ctx4, hello_buffer + 2, hello_len - 2);
139
140 mbedtls_md_finish(&ctx4, output4);
141 print_hex("Method 4", output4, mbedtls_md_get_size(md_info4));
142
143 /* Or you could re-use the context by doing mbedtls_md_starts() again */
144 mbedtls_md_free(&ctx4);
145
146
147 printf("\r\nDONE\r\n");
148
149 return 0;
150 }
151
152 #if defined(TARGET_LIKE_MBED)
153
154 #include "mbed-drivers/test_env.h"
155 #include "minar/minar.h"
156
run()157 static void run() {
158 MBED_HOSTTEST_TIMEOUT(10);
159 MBED_HOSTTEST_SELECT(default);
160 MBED_HOSTTEST_DESCRIPTION(mbed TLS example on hashing);
161 MBED_HOSTTEST_START("MBEDTLS_EX_HASHING");
162 MBED_HOSTTEST_RESULT(example() == 0);
163 }
164
app_start(int,char * [])165 void app_start(int, char*[]) {
166 /* Use 115200 bps for consistency with other examples */
167 get_stdio_serial().baud(115200);
168 minar::Scheduler::postCallback(mbed::util::FunctionPointer0<void>(run).bind());
169 }
170
171 #else
172
main()173 int main() {
174 return example();
175 }
176
177 #endif
178