aboutsummaryrefslogtreecommitdiff
path: root/source/crypto/Hashes.mc
diff options
context:
space:
mode:
Diffstat (limited to 'source/crypto/Hashes.mc')
-rw-r--r--source/crypto/Hashes.mc54
1 files changed, 54 insertions, 0 deletions
diff --git a/source/crypto/Hashes.mc b/source/crypto/Hashes.mc
new file mode 100644
index 0000000..14e2cf2
--- /dev/null
+++ b/source/crypto/Hashes.mc
@@ -0,0 +1,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();
+ }
+}