summaryrefslogtreecommitdiff
path: root/source/crypto/Hashes.mc
blob: 14e2cf2fc6c84e9b896be0a594b6f7157a476343 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// Author:  cirakg & claude ai
// Summary: One interface over SHA-1, SHA-256 (native) and SHA-512 (pure Monkey C).
//
// Connect IQ has native SHA-1 and SHA-256 (Toybox.Cryptography.Hash) but no
// SHA-512, which source/crypto/Sha512.mc implements from FIPS 180-4. OTP code
// asks for an algorithm by its Hashes.Algorithm value and doesn't care which
// implementation answers.

import Toybox.Cryptography;
import Toybox.Lang;

module Hashes {

    // OTP and HMAC hash algorithms. The values are stored in entry records, so
    // never renumber them.
    enum Algorithm {
        SHA1 = 0,
        SHA256 = 1,
        SHA512 = 2
    }

    // Input block size in bytes (what HMAC pads its key to).
    function blockSize(alg as Algorithm) as Number {
        return alg == SHA512 ? 128 : 64;
    }

    // Digest length in bytes.
    function digestSize(alg as Algorithm) as Number {
        if (alg == SHA1) {
            return 20;
        }
        return alg == SHA256 ? 32 : 64;
    }

    // True for the three supported values (input from settings or imports is
    // checked with this before it becomes an Algorithm).
    function isValid(value as Number) as Boolean {
        return value == SHA1 || value == SHA256 || value == SHA512;
    }

    // The digest of data.
    function digest(alg as Algorithm, data as ByteArray) as ByteArray {
        if (alg == SHA512) {
            return Sha512.digest(data);
        }
        var hash = new Cryptography.Hash({
            :algorithm => alg == SHA1 ? Cryptography.HASH_SHA1 : Cryptography.HASH_SHA256
        });
        if (data.size() > 0) {
            hash.update(data);
        }
        return hash.digest();
    }
}