diff options
| author | cirakg <cirakg@cirakg.xyz> | 2026-10-18 23:44:18 +0200 |
|---|---|---|
| committer | cirakg <cirakg@cirakg.xyz> | 2026-10-18 23:44:18 +0200 |
| commit | e47ae684101981a7c20f3270994a61944059c825 (patch) | |
| tree | c2baab8baafa1be446dad7f224f1a1cf68493825 /source/util/Clock.mc | |
| parent | b70cde45b67e1f6bb65d598d25c1a5184bdab520 (diff) | |
feat(crypto): add SHA-512, HMAC, PBKDF2, HKDF, AES-256 records and self-test
- Sha512: FIPS 180-4 in Monkey C (no native SHA-512), rotations inlined
with precomputed masks; constants derived from the primes, not typed.
- Hmac: RFC 2104 over SHA-1/256/512 (native HMAC only supports SHA-256).
- Kdf: resumable PBKDF2-HMAC-SHA256 job with calibration bounds
(2,000-200,000 iterations) and HKDF-SHA256.
- Aes: CBC with PKCS#7 over the native cipher; AES-256 chosen.
- SealedBox: encrypt-then-MAC records (HKDF-split keys, length-prefixed
aad, constant-time tag check before decryption).
- SelfTest: known-answer tests for every primitive at start-up.
- Bytes (wipe, constant-time equal), Clock (2038-safe widening, trusted
clock), Jobs (bounded steps against the watchdog, timer runner).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'source/util/Clock.mc')
| -rw-r--r-- | source/util/Clock.mc | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/source/util/Clock.mc b/source/util/Clock.mc new file mode 100644 index 0000000..4e2faf4 --- /dev/null +++ b/source/util/Clock.mc @@ -0,0 +1,36 @@ +// Author: cirakg & claude ai +// Summary: UTC time for TOTP: the 2038-safe widening of the watch clock, the user's offset, and the trusted clock. +// +// Connect IQ stores time as a 32-bit signed integer, which turns negative on +// 2038-01-19. Reading it as unsigned keeps it correct until 2106 (README 9). +// The trusted clock (Time.CURRENT_TIME_RTC, API 3.0.10) is synced from GPS and +// can't be changed by the user; the UI warns when it is unsynced or differs +// from the normal clock. + +import Toybox.Lang; +import Toybox.Time; + +module Clock { + + const TWO_POW_32 = 4294967296l; + + // A 32-bit clock value read as unsigned. + function toUnsigned(value as Number) as Long { + var v = value.toLong(); + return v < 0 ? v + TWO_POW_32 : v; + } + + // Current unix time (UTC seconds) plus the user's offset for clock skew. + function nowUnix(offsetSeconds as Number) as Long { + return toUnsigned(Time.now().value()) + offsetSeconds; + } + + // The trusted clock's unix time, or null when it isn't synced yet. + function trustedUnix() as Long? { + try { + return toUnsigned(Time.getCurrentTime({:currentTimeType => Time.CURRENT_TIME_RTC}).value()); + } catch (e instanceof Time.RealTimeClockNotValidException) { + return null; + } + } +} |
