1 | /* |
2 | * This file is part of the MicroPython project, http://micropython.org/ |
3 | * |
4 | * The MIT License (MIT) |
5 | * |
6 | * Copyright (c) 2014 Paul Sokolovsky |
7 | * |
8 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
9 | * of this software and associated documentation files (the "Software"), to deal |
10 | * in the Software without restriction, including without limitation the rights |
11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
12 | * copies of the Software, and to permit persons to whom the Software is |
13 | * furnished to do so, subject to the following conditions: |
14 | * |
15 | * The above copyright notice and this permission notice shall be included in |
16 | * all copies or substantial portions of the Software. |
17 | * |
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
24 | * THE SOFTWARE. |
25 | */ |
26 | |
27 | #include <assert.h> |
28 | #include <string.h> |
29 | |
30 | #include "py/runtime.h" |
31 | |
32 | #if MICROPY_PY_UHASHLIB |
33 | |
34 | #if MICROPY_SSL_MBEDTLS |
35 | #include "mbedtls/version.h" |
36 | #endif |
37 | |
38 | #if MICROPY_PY_UHASHLIB_SHA256 |
39 | |
40 | #if MICROPY_SSL_MBEDTLS |
41 | #include "mbedtls/sha256.h" |
42 | #else |
43 | #include "crypto-algorithms/sha256.h" |
44 | #endif |
45 | |
46 | #endif |
47 | |
48 | #if MICROPY_PY_UHASHLIB_SHA1 || MICROPY_PY_UHASHLIB_MD5 |
49 | |
50 | #if MICROPY_SSL_AXTLS |
51 | #include "lib/axtls/crypto/crypto.h" |
52 | #endif |
53 | |
54 | #if MICROPY_SSL_MBEDTLS |
55 | #include "mbedtls/md5.h" |
56 | #include "mbedtls/sha1.h" |
57 | #endif |
58 | |
59 | #endif |
60 | |
61 | typedef struct _mp_obj_hash_t { |
62 | mp_obj_base_t base; |
63 | char state[0]; |
64 | } mp_obj_hash_t; |
65 | |
66 | #if MICROPY_PY_UHASHLIB_SHA256 |
67 | STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg); |
68 | |
69 | #if MICROPY_SSL_MBEDTLS |
70 | |
71 | #if MBEDTLS_VERSION_NUMBER < 0x02070000 |
72 | #define mbedtls_sha256_starts_ret mbedtls_sha256_starts |
73 | #define mbedtls_sha256_update_ret mbedtls_sha256_update |
74 | #define mbedtls_sha256_finish_ret mbedtls_sha256_finish |
75 | #endif |
76 | |
77 | STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { |
78 | mp_arg_check_num(n_args, n_kw, 0, 1, false); |
79 | mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context)); |
80 | o->base.type = type; |
81 | mbedtls_sha256_init((mbedtls_sha256_context *)&o->state); |
82 | mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0); |
83 | if (n_args == 1) { |
84 | uhashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]); |
85 | } |
86 | return MP_OBJ_FROM_PTR(o); |
87 | } |
88 | |
89 | STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { |
90 | mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); |
91 | mp_buffer_info_t bufinfo; |
92 | mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); |
93 | mbedtls_sha256_update_ret((mbedtls_sha256_context *)&self->state, bufinfo.buf, bufinfo.len); |
94 | return mp_const_none; |
95 | } |
96 | |
97 | STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) { |
98 | mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); |
99 | vstr_t vstr; |
100 | vstr_init_len(&vstr, 32); |
101 | mbedtls_sha256_finish_ret((mbedtls_sha256_context *)&self->state, (unsigned char *)vstr.buf); |
102 | return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); |
103 | } |
104 | |
105 | #else |
106 | |
107 | #include "crypto-algorithms/sha256.c" |
108 | |
109 | STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { |
110 | mp_arg_check_num(n_args, n_kw, 0, 1, false); |
111 | mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX)); |
112 | o->base.type = type; |
113 | sha256_init((CRYAL_SHA256_CTX *)o->state); |
114 | if (n_args == 1) { |
115 | uhashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]); |
116 | } |
117 | return MP_OBJ_FROM_PTR(o); |
118 | } |
119 | |
120 | STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { |
121 | mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); |
122 | mp_buffer_info_t bufinfo; |
123 | mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); |
124 | sha256_update((CRYAL_SHA256_CTX *)self->state, bufinfo.buf, bufinfo.len); |
125 | return mp_const_none; |
126 | } |
127 | |
128 | STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) { |
129 | mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); |
130 | vstr_t vstr; |
131 | vstr_init_len(&vstr, SHA256_BLOCK_SIZE); |
132 | sha256_final((CRYAL_SHA256_CTX *)self->state, (byte *)vstr.buf); |
133 | return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); |
134 | } |
135 | #endif |
136 | |
137 | STATIC MP_DEFINE_CONST_FUN_OBJ_2(uhashlib_sha256_update_obj, uhashlib_sha256_update); |
138 | STATIC MP_DEFINE_CONST_FUN_OBJ_1(uhashlib_sha256_digest_obj, uhashlib_sha256_digest); |
139 | |
140 | STATIC const mp_rom_map_elem_t uhashlib_sha256_locals_dict_table[] = { |
141 | { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&uhashlib_sha256_update_obj) }, |
142 | { MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&uhashlib_sha256_digest_obj) }, |
143 | }; |
144 | |
145 | STATIC MP_DEFINE_CONST_DICT(uhashlib_sha256_locals_dict, uhashlib_sha256_locals_dict_table); |
146 | |
147 | STATIC const mp_obj_type_t uhashlib_sha256_type = { |
148 | { &mp_type_type }, |
149 | .name = MP_QSTR_sha256, |
150 | .make_new = uhashlib_sha256_make_new, |
151 | .locals_dict = (void *)&uhashlib_sha256_locals_dict, |
152 | }; |
153 | #endif |
154 | |
155 | #if MICROPY_PY_UHASHLIB_SHA1 |
156 | STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg); |
157 | |
158 | #if MICROPY_SSL_AXTLS |
159 | STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { |
160 | mp_arg_check_num(n_args, n_kw, 0, 1, false); |
161 | mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX)); |
162 | o->base.type = type; |
163 | SHA1_Init((SHA1_CTX *)o->state); |
164 | if (n_args == 1) { |
165 | uhashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]); |
166 | } |
167 | return MP_OBJ_FROM_PTR(o); |
168 | } |
169 | |
170 | STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { |
171 | mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); |
172 | mp_buffer_info_t bufinfo; |
173 | mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); |
174 | SHA1_Update((SHA1_CTX *)self->state, bufinfo.buf, bufinfo.len); |
175 | return mp_const_none; |
176 | } |
177 | |
178 | STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) { |
179 | mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); |
180 | vstr_t vstr; |
181 | vstr_init_len(&vstr, SHA1_SIZE); |
182 | SHA1_Final((byte *)vstr.buf, (SHA1_CTX *)self->state); |
183 | return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); |
184 | } |
185 | #endif |
186 | |
187 | #if MICROPY_SSL_MBEDTLS |
188 | |
189 | #if MBEDTLS_VERSION_NUMBER < 0x02070000 |
190 | #define mbedtls_sha1_starts_ret mbedtls_sha1_starts |
191 | #define mbedtls_sha1_update_ret mbedtls_sha1_update |
192 | #define mbedtls_sha1_finish_ret mbedtls_sha1_finish |
193 | #endif |
194 | |
195 | STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { |
196 | mp_arg_check_num(n_args, n_kw, 0, 1, false); |
197 | mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context)); |
198 | o->base.type = type; |
199 | mbedtls_sha1_init((mbedtls_sha1_context *)o->state); |
200 | mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state); |
201 | if (n_args == 1) { |
202 | uhashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]); |
203 | } |
204 | return MP_OBJ_FROM_PTR(o); |
205 | } |
206 | |
207 | STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { |
208 | mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); |
209 | mp_buffer_info_t bufinfo; |
210 | mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); |
211 | mbedtls_sha1_update_ret((mbedtls_sha1_context *)self->state, bufinfo.buf, bufinfo.len); |
212 | return mp_const_none; |
213 | } |
214 | |
215 | STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) { |
216 | mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); |
217 | vstr_t vstr; |
218 | vstr_init_len(&vstr, 20); |
219 | mbedtls_sha1_finish_ret((mbedtls_sha1_context *)self->state, (byte *)vstr.buf); |
220 | mbedtls_sha1_free((mbedtls_sha1_context *)self->state); |
221 | return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); |
222 | } |
223 | #endif |
224 | |
225 | STATIC MP_DEFINE_CONST_FUN_OBJ_2(uhashlib_sha1_update_obj, uhashlib_sha1_update); |
226 | STATIC MP_DEFINE_CONST_FUN_OBJ_1(uhashlib_sha1_digest_obj, uhashlib_sha1_digest); |
227 | |
228 | STATIC const mp_rom_map_elem_t uhashlib_sha1_locals_dict_table[] = { |
229 | { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&uhashlib_sha1_update_obj) }, |
230 | { MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&uhashlib_sha1_digest_obj) }, |
231 | }; |
232 | STATIC MP_DEFINE_CONST_DICT(uhashlib_sha1_locals_dict, uhashlib_sha1_locals_dict_table); |
233 | |
234 | STATIC const mp_obj_type_t uhashlib_sha1_type = { |
235 | { &mp_type_type }, |
236 | .name = MP_QSTR_sha1, |
237 | .make_new = uhashlib_sha1_make_new, |
238 | .locals_dict = (void *)&uhashlib_sha1_locals_dict, |
239 | }; |
240 | #endif |
241 | |
242 | #if MICROPY_PY_UHASHLIB_MD5 |
243 | STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg); |
244 | |
245 | #if MICROPY_SSL_AXTLS |
246 | STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { |
247 | mp_arg_check_num(n_args, n_kw, 0, 1, false); |
248 | mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(MD5_CTX)); |
249 | o->base.type = type; |
250 | MD5_Init((MD5_CTX *)o->state); |
251 | if (n_args == 1) { |
252 | uhashlib_md5_update(MP_OBJ_FROM_PTR(o), args[0]); |
253 | } |
254 | return MP_OBJ_FROM_PTR(o); |
255 | } |
256 | |
257 | STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) { |
258 | mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); |
259 | mp_buffer_info_t bufinfo; |
260 | mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); |
261 | MD5_Update((MD5_CTX *)self->state, bufinfo.buf, bufinfo.len); |
262 | return mp_const_none; |
263 | } |
264 | |
265 | STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) { |
266 | mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); |
267 | vstr_t vstr; |
268 | vstr_init_len(&vstr, MD5_SIZE); |
269 | MD5_Final((byte *)vstr.buf, (MD5_CTX *)self->state); |
270 | return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); |
271 | } |
272 | #endif // MICROPY_SSL_AXTLS |
273 | |
274 | #if MICROPY_SSL_MBEDTLS |
275 | |
276 | #if MBEDTLS_VERSION_NUMBER < 0x02070000 |
277 | #define mbedtls_md5_starts_ret mbedtls_md5_starts |
278 | #define mbedtls_md5_update_ret mbedtls_md5_update |
279 | #define mbedtls_md5_finish_ret mbedtls_md5_finish |
280 | #endif |
281 | |
282 | STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { |
283 | mp_arg_check_num(n_args, n_kw, 0, 1, false); |
284 | mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context)); |
285 | o->base.type = type; |
286 | mbedtls_md5_init((mbedtls_md5_context *)o->state); |
287 | mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state); |
288 | if (n_args == 1) { |
289 | uhashlib_md5_update(MP_OBJ_FROM_PTR(o), args[0]); |
290 | } |
291 | return MP_OBJ_FROM_PTR(o); |
292 | } |
293 | |
294 | STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) { |
295 | mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); |
296 | mp_buffer_info_t bufinfo; |
297 | mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); |
298 | mbedtls_md5_update_ret((mbedtls_md5_context *)self->state, bufinfo.buf, bufinfo.len); |
299 | return mp_const_none; |
300 | } |
301 | |
302 | STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) { |
303 | mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); |
304 | vstr_t vstr; |
305 | vstr_init_len(&vstr, 16); |
306 | mbedtls_md5_finish_ret((mbedtls_md5_context *)self->state, (byte *)vstr.buf); |
307 | mbedtls_md5_free((mbedtls_md5_context *)self->state); |
308 | return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); |
309 | } |
310 | #endif // MICROPY_SSL_MBEDTLS |
311 | |
312 | STATIC MP_DEFINE_CONST_FUN_OBJ_2(uhashlib_md5_update_obj, uhashlib_md5_update); |
313 | STATIC MP_DEFINE_CONST_FUN_OBJ_1(uhashlib_md5_digest_obj, uhashlib_md5_digest); |
314 | |
315 | STATIC const mp_rom_map_elem_t uhashlib_md5_locals_dict_table[] = { |
316 | { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&uhashlib_md5_update_obj) }, |
317 | { MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&uhashlib_md5_digest_obj) }, |
318 | }; |
319 | STATIC MP_DEFINE_CONST_DICT(uhashlib_md5_locals_dict, uhashlib_md5_locals_dict_table); |
320 | |
321 | STATIC const mp_obj_type_t uhashlib_md5_type = { |
322 | { &mp_type_type }, |
323 | .name = MP_QSTR_md5, |
324 | .make_new = uhashlib_md5_make_new, |
325 | .locals_dict = (void *)&uhashlib_md5_locals_dict, |
326 | }; |
327 | #endif // MICROPY_PY_UHASHLIB_MD5 |
328 | |
329 | STATIC const mp_rom_map_elem_t mp_module_uhashlib_globals_table[] = { |
330 | { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uhashlib) }, |
331 | #if MICROPY_PY_UHASHLIB_SHA256 |
332 | { MP_ROM_QSTR(MP_QSTR_sha256), MP_ROM_PTR(&uhashlib_sha256_type) }, |
333 | #endif |
334 | #if MICROPY_PY_UHASHLIB_SHA1 |
335 | { MP_ROM_QSTR(MP_QSTR_sha1), MP_ROM_PTR(&uhashlib_sha1_type) }, |
336 | #endif |
337 | #if MICROPY_PY_UHASHLIB_MD5 |
338 | { MP_ROM_QSTR(MP_QSTR_md5), MP_ROM_PTR(&uhashlib_md5_type) }, |
339 | #endif |
340 | }; |
341 | |
342 | STATIC MP_DEFINE_CONST_DICT(mp_module_uhashlib_globals, mp_module_uhashlib_globals_table); |
343 | |
344 | const mp_obj_module_t mp_module_uhashlib = { |
345 | .base = { &mp_type_module }, |
346 | .globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals, |
347 | }; |
348 | |
349 | #endif // MICROPY_PY_UHASHLIB |
350 | |