sha256.ha (1322B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use bytes; 5 use crypto::mac; 6 use crypto::sha256; 7 use hash; 8 use io; 9 10 export type sha256state = struct { 11 mac::mac, 12 h: sha256::state, 13 keypad: [sha256::BLOCKSZ]u8, 14 }; 15 16 const sha256_vtable: io::vtable = io::vtable { 17 writer = &sha256write, 18 ... 19 }; 20 21 // Creates a [[crypto::mac::mac]] that computes an HMAC with given 'key' using 22 // SHA256 as underlying hash function. 23 // 24 // The caller must take extra care to call [[crypto::mac::finish]] when they are 25 // finished using the MAC function, which, in addition to freeing state 26 // associated with the MAC, will securely erase state which contains secret 27 // information. 28 export fn sha256(key: []u8) sha256state = { 29 let s = sha256state { 30 stream = &sha256_vtable, 31 h = sha256::sha256(), 32 sz = sha256::SZ, 33 bsz = sha256::BLOCKSZ, 34 sum = &sha256sum, 35 finish = &sha256finish, 36 ... 37 }; 38 39 init(&s.h, key, s.keypad); 40 return s; 41 }; 42 43 fn sha256write(st: *io::stream, buf: const []u8) (size | io::error) = { 44 let hm = st: *sha256state; 45 return hash::write(&hm.h, buf); 46 }; 47 48 fn sha256sum(mac: *mac::mac, dest: []u8) void = { 49 let hm = mac: *sha256state; 50 sum(&hm.h, hm.keypad, dest); 51 }; 52 53 fn sha256finish(mac: *mac::mac) void = { 54 let hm = mac: *sha256state; 55 bytes::zero(hm.keypad); 56 io::close(&hm.h)!; 57 };