1 /* 2 * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 #include "inner.h" 26 27 /* see bearssl.h */ 28 void 29 br_md5sha1_init(br_md5sha1_context *cc) 30 { 31 cc->vtable = &br_md5sha1_vtable; 32 memcpy(cc->val_md5, br_md5_IV, sizeof cc->val_md5); 33 memcpy(cc->val_sha1, br_sha1_IV, sizeof cc->val_sha1); 34 cc->count = 0; 35 } 36 37 /* see bearssl.h */ 38 void 39 br_md5sha1_update(br_md5sha1_context *cc, const void *data, size_t len) 40 { 41 const unsigned char *buf; 42 size_t ptr; 43 44 buf = data; 45 ptr = (size_t)cc->count & 63; 46 while (len > 0) { 47 size_t clen; 48 49 clen = 64 - ptr; 50 if (clen > len) { 51 clen = len; 52 } 53 memcpy(cc->buf + ptr, buf, clen); 54 ptr += clen; 55 buf += clen; 56 len -= clen; 57 cc->count += (uint64_t)clen; 58 if (ptr == 64) { 59 br_md5_round(cc->buf, cc->val_md5); 60 br_sha1_round(cc->buf, cc->val_sha1); 61 ptr = 0; 62 } 63 } 64 } 65 66 /* see bearssl.h */ 67 void 68 br_md5sha1_out(const br_md5sha1_context *cc, void *dst) 69 { 70 unsigned char buf[64]; 71 uint32_t val_md5[4]; 72 uint32_t val_sha1[5]; 73 size_t ptr; 74 unsigned char *out; 75 uint64_t count; 76 77 count = cc->count; 78 ptr = (size_t)count & 63; 79 memcpy(buf, cc->buf, ptr); 80 memcpy(val_md5, cc->val_md5, sizeof val_md5); 81 memcpy(val_sha1, cc->val_sha1, sizeof val_sha1); 82 buf[ptr ++] = 0x80; 83 if (ptr > 56) { 84 memset(buf + ptr, 0, 64 - ptr); 85 br_md5_round(buf, val_md5); 86 br_sha1_round(buf, val_sha1); 87 memset(buf, 0, 56); 88 } else { 89 memset(buf + ptr, 0, 56 - ptr); 90 } 91 count <<= 3; 92 br_enc64le(buf + 56, count); 93 br_md5_round(buf, val_md5); 94 br_enc64be(buf + 56, count); 95 br_sha1_round(buf, val_sha1); 96 out = dst; 97 br_range_enc32le(out, val_md5, 4); 98 br_range_enc32be(out + 16, val_sha1, 5); 99 } 100 101 /* see bearssl.h */ 102 uint64_t 103 br_md5sha1_state(const br_md5sha1_context *cc, void *dst) 104 { 105 unsigned char *out; 106 107 out = dst; 108 br_range_enc32le(out, cc->val_md5, 4); 109 br_range_enc32be(out + 16, cc->val_sha1, 5); 110 return cc->count; 111 } 112 113 /* see bearssl.h */ 114 void 115 br_md5sha1_set_state(br_md5sha1_context *cc, const void *stb, uint64_t count) 116 { 117 const unsigned char *buf; 118 119 buf = stb; 120 br_range_dec32le(cc->val_md5, 4, buf); 121 br_range_dec32be(cc->val_sha1, 5, buf + 16); 122 cc->count = count; 123 } 124 125 /* see bearssl.h */ 126 const br_hash_class br_md5sha1_vtable = { 127 sizeof(br_md5sha1_context), 128 BR_HASHDESC_ID(br_md5sha1_ID) 129 | BR_HASHDESC_OUT(36) 130 | BR_HASHDESC_STATE(36) 131 | BR_HASHDESC_LBLEN(6), 132 (void (*)(const br_hash_class **))&br_md5sha1_init, 133 (void (*)(const br_hash_class **, const void *, size_t)) 134 &br_md5sha1_update, 135 (void (*)(const br_hash_class *const *, void *)) 136 &br_md5sha1_out, 137 (uint64_t (*)(const br_hash_class *const *, void *)) 138 &br_md5sha1_state, 139 (void (*)(const br_hash_class **, const void *, uint64_t)) 140 &br_md5sha1_set_state 141 }; 142