blob: 09681f92ba5d727559341e6f3181240683edde0f [file] [log] [blame]
Manuel Pégourié-Gonnard63e7eba2015-07-28 14:17:48 +02001/*
2 * Hello world example of using the hashing functions of mbed TLS
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 *
6 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnardcdee2d92015-08-07 09:40:51 +02007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Manuel Pégourié-Gonnard63e7eba2015-07-28 14:17:48 +020021 */
22
23/*
24 * This program illustrates various ways of hashing a buffer.
25 * You normally need only one of these two includes.
26 */
27#include "mbedtls/sha256.h" /* SHA-256 only */
28#include "mbedtls/md.h" /* generic interface */
29
30#if defined(TARGET_LIKE_MBED)
31#include "mbed/mbed.h"
32#endif
33#include <cstdio>
34
35static void print_hex(const char *title, const unsigned char buf[], size_t len)
36{
37 printf("%s: ", title);
38
39 for (size_t i = 0; i < len; i++)
40 printf("%02x", buf[i]);
41
42 printf("\r\n");
43}
44
45static const char hello_str[] = "Hello, world!";
46static const unsigned char *hello_buffer = (const unsigned char *) hello_str;
47static const size_t hello_len = sizeof hello_str - 1;
48
49int example(void)
50{
51 printf( "\r\n\r\n" );
52
53 /*
54 * Method 1: use all-in-one function of a specific SHA-xxx module
55 */
56 unsigned char output1[32]; /* SHA-256 outputs 32 bytes */
57
58 /* 0 here means use the full SHA-256, not the SHA-224 variant */
59 mbedtls_sha256(hello_buffer, hello_len, output1, 0);
60
61 print_hex("Method 1", output1, sizeof output1);
62
63
64 /*
65 * Method 2: use the streaming interface of a specific SHA-xxx module
66 * This is useful if we get our input piecewise.
67 */
68 unsigned char output2[32];
69 mbedtls_sha256_context ctx2;
70
71 mbedtls_sha256_init(&ctx2);
72 mbedtls_sha256_starts(&ctx2, 0); /* SHA-256, not 224 */
73
74 /* Simulating multiple fragments */
75 mbedtls_sha256_update(&ctx2, hello_buffer, 1);
76 mbedtls_sha256_update(&ctx2, hello_buffer + 1, 1);
77 mbedtls_sha256_update(&ctx2, hello_buffer + 2, hello_len - 2);
78
79 mbedtls_sha256_finish(&ctx2, output2);
80 print_hex("Method 2", output2, sizeof output2);
81
82 /* Or you could re-use the context by doing mbedtls_sha256_starts() again */
83 mbedtls_sha256_free(&ctx2);
84
85 /*
86 * Method 3: use all-in-one function of the generice interface
87 */
88 unsigned char output3[MBEDTLS_MD_MAX_SIZE]; /* Enough for any hash */
89
90 /* Can easily pick any hash you want, by identifier */
91 const mbedtls_md_info_t *md_info3 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
92
93 if (md_info3 == NULL)
94 {
95 printf("SHA256 not available\r\n");
96 return 1;
97 }
98
99 int ret3 = mbedtls_md(md_info3, hello_buffer, hello_len, output3);
100
101 if (ret3 != 0)
102 {
103 printf("md() returned -0x%04X\r\n", -ret3);
104 return 1;
105 }
106
107 print_hex("Method 3", output3, mbedtls_md_get_size(md_info3));
108
109
110 /*
111 * Method 4: streaming & generic interface
112 */
113 unsigned char output4[MBEDTLS_MD_MAX_SIZE]; /* Enough for any hash */
114
115 const mbedtls_md_info_t *md_info4 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
116
117 if (md_info4 == NULL)
118 {
119 printf("SHA256 not available\r\n");
120 return 1;
121 }
122
123 mbedtls_md_context_t ctx4;
124
125 mbedtls_md_init(&ctx4);
126
127 int ret4 = mbedtls_md_init_ctx(&ctx4, md_info4);
128 if (ret4 != 0)
129 {
130 printf("md_init_ctx() returned -0x%04X\r\n", -ret4);
131 return 1;
132 }
133
134 mbedtls_md_starts(&ctx4);
135
136 /* Simulating multiple fragments */
137 mbedtls_md_update(&ctx4, hello_buffer, 1);
138 mbedtls_md_update(&ctx4, hello_buffer + 1, 1);
139 mbedtls_md_update(&ctx4, hello_buffer + 2, hello_len - 2);
140
141 mbedtls_md_finish(&ctx4, output4);
142 print_hex("Method 4", output4, mbedtls_md_get_size(md_info4));
143
144 /* Or you could re-use the context by doing mbedtls_md_starts() again */
145 mbedtls_md_free(&ctx4);
146
147
148 printf("\r\nDONE\r\n");
149
150 return 0;
151}
152
153#if defined(TARGET_LIKE_MBED)
154
155#include "mbed/test_env.h"
Manuel Pégourié-Gonnarde87b04c2015-08-11 04:09:44 +0200156#include "minar/minar.h"
Manuel Pégourié-Gonnard63e7eba2015-07-28 14:17:48 +0200157
Manuel Pégourié-Gonnarde87b04c2015-08-11 04:09:44 +0200158static void run() {
Manuel Pégourié-Gonnardbd5bbec2015-08-06 18:10:17 +0200159 /* Use 115200 bps for consistency with other examples */
160 Serial pc(USBTX, USBRX);
161 pc.baud(115200);
162
Manuel Pégourié-Gonnard63e7eba2015-07-28 14:17:48 +0200163 MBED_HOSTTEST_TIMEOUT(10);
164 MBED_HOSTTEST_SELECT(default);
165 MBED_HOSTTEST_DESCRIPTION(mbed TLS example on hashing);
166 MBED_HOSTTEST_START("MBEDTLS_EX_HASHING");
167 MBED_HOSTTEST_RESULT(example() == 0);
168}
169
Manuel Pégourié-Gonnarde87b04c2015-08-11 04:09:44 +0200170void app_start(int, char*[]) {
171 minar::Scheduler::postCallback(FunctionPointer0<void>(run).bind());
172}
173
Manuel Pégourié-Gonnard63e7eba2015-07-28 14:17:48 +0200174#else
175
176int main() {
177 return example();
178}
179
180#endif