From 4396e6a43d5075dc774ab52ea0cd6f5379cffce1 Mon Sep 17 00:00:00 2001
From: kirbylife <kirbylife@protonmail.com>
Date: Wed, 26 Apr 2023 23:33:28 -0600
Subject: [PATCH] Reduce the bin size removing the sha1_smol library

---
 Cargo.lock      |  14 +--
 Cargo.toml      |   4 +-
 src/crypto.rs   |  38 ++------
 src/datetime.rs |   4 +-
 src/main.rs     | 242 +++++++++++++++++++++---------------------------
 src/storage.rs  |   8 +-
 6 files changed, 131 insertions(+), 179 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index c9ee47a..5472a24 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -101,6 +101,7 @@ dependencies = [
 [[package]]
 name = "ds323x"
 version = "0.5.0"
+source = "git+https://github.com/kirbylife/ds323x-rs?branch=fix-set-day-format#e204b77494f921cfc276c9a66e6e9ba95dc4e142"
 dependencies = [
  "embedded-hal",
  "rtcc",
@@ -122,6 +123,11 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "723dce4e9f25b6e6c5f35628e144794e5b459216ed7da97b7c4b66cdb3fa82ca"
 
+[[package]]
+name = "hmac-sha1-compact"
+version = "1.1.3"
+source = "git+https://github.com/kirbylife/rust-hmac-sha1#a3c4116837efb8a850fb0d03985831ce4dc2bc12"
+
 [[package]]
 name = "nb"
 version = "0.1.3"
@@ -220,19 +226,13 @@ dependencies = [
  "arduino-hal",
  "ds323x",
  "embedded-hal",
+ "hmac-sha1-compact",
  "nb 1.1.0",
  "panic-halt",
  "randomize",
- "sha1_smol",
  "ufmt 0.2.0",
 ]
 
-[[package]]
-name = "sha1_smol"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
-
 [[package]]
 name = "syn"
 version = "1.0.109"
diff --git a/Cargo.toml b/Cargo.toml
index 14336d6..5119130 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,9 +5,9 @@ edition = "2021"
 
 [dependencies]
 arduino-hal = {  git = "https://github.com/rahix/avr-hal", features = ["arduino-uno"] }
+ds323x = { git = "https://github.com/kirbylife/ds323x-rs", branch = "fix-set-day-format" }
+hmac-sha1-compact = { git = "https://github.com/kirbylife/rust-hmac-sha1" }
 panic-halt = "0.2.0"
-sha1_smol = "1.0.0"
-ds323x = { path = "../ds323x-rs" }
 embedded-hal = "0.2.7"
 nb = "1.1.0"
 randomize = "3.0.1"
diff --git a/src/crypto.rs b/src/crypto.rs
index 259b648..3e0f132 100644
--- a/src/crypto.rs
+++ b/src/crypto.rs
@@ -1,34 +1,16 @@
-use sha1_smol::Sha1;
+use hmac_sha1_compact::HMAC;
 
-const BLOCK_SIZE: usize = 64;
+pub const INTERVAL: u64 = 30;
 
-pub fn hmac_sha1(key: &[u8], message: &[u8], output: &mut [u8]) {
-    // Preprocess the key.
-    let mut key_padded = [0u8; BLOCK_SIZE];
-    key_padded[..key.len()].copy_from_slice(key);
+pub fn generate_otp_token(private_key: &[u8], actual_time: u64) -> u32 {
+    let interval = actual_time / INTERVAL;
+    let msg = interval.to_be_bytes();
 
-    for byte in &mut key_padded {
-        *byte ^= 0x36;
-    }
+    let hmac_digest = HMAC::mac(&msg, private_key);
 
-    // Hash the inner padded key and the message.
-    let mut hash = Sha1::new();
-    hash.update(&key_padded[..]);
-    hash.update(message);
-    let mut inner_hash = [0u8; 20];
-    inner_hash.copy_from_slice(&hash.digest().bytes());
+    let start = (hmac_digest[19] & 0xF) as usize;
+    let bytes: [u8; 4] = hmac_digest[start..start + 4].try_into().unwrap();
 
-    // Preprocess the key again.
-    for byte in &mut key_padded {
-        *byte ^= 0x36 ^ 0x5c;
-    }
-
-    // Hash the outer padded key and the inner hash.
-    let mut hash = Sha1::new();
-    hash.update(&key_padded[..]);
-    hash.update(&inner_hash[..]);
-    let hmac_digest = hash.digest().bytes();
-
-    // Copy the result into the output buffer.
-    output.copy_from_slice(&hmac_digest);
+    let raw_token = u32::from_be_bytes(bytes);
+    ((raw_token & 0x7F_FF_FF_FF) % 1_000_000) as u32
 }
diff --git a/src/datetime.rs b/src/datetime.rs
index 2b181c7..14e65e7 100644
--- a/src/datetime.rs
+++ b/src/datetime.rs
@@ -11,8 +11,8 @@ pub struct Datetime {
 
 impl Datetime {
     pub fn unix_epoch(&self) -> u64 {
-        let mut year: i64 = self.year as i64 - 1900;
-        let mut month: i64 = self.month as i64 - 1;
+        let year: i64 = self.year as i64 - 1900;
+        let month: i64 = self.month as i64 - 1;
 
         let (mut t, is_leap) = year_to_secs(year);
         t += month_to_secs(month, is_leap);
diff --git a/src/main.rs b/src/main.rs
index 5e330c6..2934843 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,15 +11,14 @@ use arduino_hal::default_serial;
 use arduino_hal::delay_ms;
 // use arduino_hal::delay_ms;
 use arduino_hal::prelude::*;
-use crypto::hmac_sha1;
+use crypto::generate_otp_token;
+use crypto::INTERVAL;
 use ds323x::Rtcc;
 use nb::block;
 use panic_halt as _;
 use storage::SECRET_KEY_MAX_LEN;
 use storage::SECRET_KEY_NAME_LEN;
 
-const INTERVAL: u64 = 30;
-
 const ENDL: u8 = 0;
 const OK: u8 = 1;
 const ERROR: u8 = 2;
@@ -31,24 +30,6 @@ const GET_TOKENS: u8 = 40;
 const WIPE_TOKENS: u8 = 50;
 const EXIT: u8 = 254;
 
-fn decimal_to_packed_bcd(dec: u8) -> u8 {
-    ((dec / 10) << 4) | (dec % 10)
-}
-
-fn generate_otp_token(private_key: &[u8], actual_time: u64) -> u32 {
-    let interval = actual_time / INTERVAL;
-    let msg = interval.to_be_bytes();
-
-    let mut hmac_digest = [0u8; 20];
-    hmac_sha1(private_key, &msg, &mut hmac_digest);
-
-    let start = (hmac_digest[19] & 0xF) as usize;
-    let bytes: [u8; 4] = hmac_digest[start..start + 4].try_into().unwrap();
-
-    let raw_token = u32::from_be_bytes(bytes);
-    ((raw_token & 0x7F_FF_FF_FF) % 1_000_000) as u32
-}
-
 #[arduino_hal::entry]
 fn main() -> ! {
     let dp = arduino_hal::Peripherals::take().unwrap();
@@ -83,114 +64,112 @@ fn main() -> ! {
     let up = pins.d6.into_pull_up_input();
     let mut button = button::Button::new(&up, true);
 
-    // button.update();
-    // if button.update() == button::Event::Pressed || true {
-    //     display.write_str("Connected to");
-    //     display.set_cursor(0, 1);
-    //     display.write_str("USB...");
-    //     loop {
-    //         // Waiting from a command since the tool
-    //         let cmd = block!(serial.read()).unwrap_or(u8::MAX);
-    //         display.set_cursor(8, 1);
-    //         display.write_str("---");
-    //         display.set_cursor(8, 1);
-    //         display.write_u32(cmd as u32);
+    button.update();
+    if button.update() == button::Event::Pressed {
+        display.write_str("Connected to");
+        display.set_cursor(0, 1);
+        display.write_str("USB...");
+        loop {
+            // Waiting from a command since the tool
+            let cmd = block!(serial.read()).unwrap_or(u8::MAX);
+            display.set_cursor(8, 1);
+            display.write_str("---");
+            display.set_cursor(8, 1);
+            display.write_u32(cmd as u32);
 
-    //         match cmd {
-    //             EXIT => {}
-    //             HANDSHAKE => serial.write(OK).unwrap(),
-    //             SET_TIMESTAMP => {
-    //                 serial.write(OK).unwrap();
-    //                 let year = loop {
-    //                     let y = block!(serial.read()).unwrap();
-    //                     serial.write(y).unwrap();
-    //                     if block!(serial.read()).unwrap() == OK {
-    //                         break y;
-    //                     }
-    //                 };
-    //                 let month = loop {
-    //                     let m = block!(serial.read()).unwrap();
-    //                     serial.write(m).unwrap();
-    //                     if block!(serial.read()).unwrap() == OK {
-    //                         break m;
-    //                     }
-    //                 };
-    //                 let day = loop {
-    //                     let d = block!(serial.read()).unwrap();
-    //                     serial.write(d).unwrap();
-    //                     if block!(serial.read()).unwrap() == OK {
-    //                         break d;
-    //                     }
-    //                 };
-    //                 let hours = loop {
-    //                     let h = block!(serial.read()).unwrap();
-    //                     serial.write(h).unwrap();
-    //                     if block!(serial.read()).unwrap() == OK {
-    //                         break h;
-    //                     }
-    //                 };
-    //                 let minutes = loop {
-    //                     let m = block!(serial.read()).unwrap();
-    //                     serial.write(m).unwrap();
-    //                     if block!(serial.read()).unwrap() == OK {
-    //                         break m;
-    //                     }
-    //                 };
-    //                 let seconds = loop {
-    //                     let s = block!(serial.read()).unwrap();
-    //                     serial.write(s).unwrap();
-    //                     if block!(serial.read()).unwrap() == OK {
-    //                         break s;
-    //                     }
-    //                 };
-    //                 rtc.set_year(year as u16 + 2000).unwrap();
-    //                 rtc.set_month(month).unwrap();
-    //                 rtc.set_day(day).unwrap();
-    //                 rtc.set_hours(ds323x::Hours::H24(hours)).unwrap();
-    //                 rtc.set_minutes(minutes).unwrap();
-    //                 rtc.set_seconds(seconds).unwrap();
-    //                 serial.write(OK).unwrap();
-    //             }
-    //             ADD_TOKEN => match tokens.search_free() {
-    //                 Some(index) => {
-    //                     serial.write(OK).unwrap();
-    //                     let mut name_buff = [0u8; SECRET_KEY_NAME_LEN as usize];
-    //                     for i in 0..name_buff.len() {
-    //                         let ch = block!(serial.read()).unwrap();
-    //                         if ch == ENDL {
-    //                             break;
-    //                         } else {
-    //                             name_buff[i] = ch;
-    //                         }
-    //                     }
+            match cmd {
+                EXIT => {}
+                HANDSHAKE => serial.write(OK).unwrap(),
+                SET_TIMESTAMP => {
+                    serial.write(OK).unwrap();
+                    let year = loop {
+                        let y = block!(serial.read()).unwrap();
+                        serial.write(y).unwrap();
+                        if block!(serial.read()).unwrap() == OK {
+                            break y;
+                        }
+                    };
+                    let month = loop {
+                        let m = block!(serial.read()).unwrap();
+                        serial.write(m).unwrap();
+                        if block!(serial.read()).unwrap() == OK {
+                            break m;
+                        }
+                    };
+                    let day = loop {
+                        let d = block!(serial.read()).unwrap();
+                        serial.write(d).unwrap();
+                        if block!(serial.read()).unwrap() == OK {
+                            break d;
+                        }
+                    };
+                    let hours = loop {
+                        let h = block!(serial.read()).unwrap();
+                        serial.write(h).unwrap();
+                        if block!(serial.read()).unwrap() == OK {
+                            break h;
+                        }
+                    };
+                    let minutes = loop {
+                        let m = block!(serial.read()).unwrap();
+                        serial.write(m).unwrap();
+                        if block!(serial.read()).unwrap() == OK {
+                            break m;
+                        }
+                    };
+                    let seconds = loop {
+                        let s = block!(serial.read()).unwrap();
+                        serial.write(s).unwrap();
+                        if block!(serial.read()).unwrap() == OK {
+                            break s;
+                        }
+                    };
+                    rtc.set_year(year as u16 + 2000).unwrap();
+                    rtc.set_month(month).unwrap();
+                    rtc.set_day(day).unwrap();
+                    rtc.set_hours(ds323x::Hours::H24(hours)).unwrap();
+                    rtc.set_minutes(minutes).unwrap();
+                    rtc.set_seconds(seconds).unwrap();
+                    serial.write(OK).unwrap();
+                }
+                ADD_TOKEN => match tokens.search_free() {
+                    Some(index) => {
+                        serial.write(OK).unwrap();
+                        let mut name_buff = [0u8; SECRET_KEY_NAME_LEN as usize];
+                        for i in 0..name_buff.len() {
+                            let ch = block!(serial.read()).unwrap();
+                            if ch == ENDL {
+                                break;
+                            } else {
+                                name_buff[i] = ch;
+                            }
+                        }
 
-    //                     let mut key_buff = [0u8; SECRET_KEY_MAX_LEN as usize];
-    //                     for i in 0..key_buff.len() {
-    //                         let ch = block!(serial.read()).unwrap();
-    //                         if ch == ENDL {
-    //                             break;
-    //                         } else {
-    //                             key_buff[i] = ch;
-    //                         }
-    //                     }
-    //                     match tokens.write(index, &name_buff, &key_buff) {
-    //                         Some(_) => serial.write(OK).unwrap(),
-    //                         None => serial.write(ERROR).unwrap(),
-    //                     }
-    //                 }
-    //                 None => serial.write(ERROR).unwrap(),
-    //             },
-    //             WIPE_TOKENS => {
-    //                 serial.write(OK).unwrap();
-    //                 tokens.wipe_all_tokens();
-    //                 serial.write(OK).unwrap();
-    //             }
-    //             _ => {}
-    //             u8::MAX => {}
-    //         }
-    //     }
-    // }
-    // loop {}
+                        let mut key_buff = [0u8; SECRET_KEY_MAX_LEN as usize];
+                        for i in 0..key_buff.len() {
+                            let ch = block!(serial.read()).unwrap();
+                            if ch == ENDL {
+                                break;
+                            } else {
+                                key_buff[i] = ch;
+                            }
+                        }
+                        match tokens.write(index, &name_buff, &key_buff) {
+                            Some(_) => serial.write(OK).unwrap(),
+                            None => serial.write(ERROR).unwrap(),
+                        }
+                    }
+                    None => serial.write(ERROR).unwrap(),
+                },
+                WIPE_TOKENS => {
+                    serial.write(OK).unwrap();
+                    tokens.wipe_all_tokens();
+                    serial.write(OK).unwrap();
+                }
+                _ => {}
+            }
+        }
+    }
 
     match tokens.current {
         Some(index) => {
@@ -202,15 +181,6 @@ fn main() -> ! {
                     let key = &buff_key[..len_key];
                     let dt = datetime::Datetime::from_ds3231(&mut rtc);
 
-                    let datetime::Datetime {
-                        year,
-                        month,
-                        day,
-                        hours,
-                        minutes,
-                        seconds,
-                    } = dt;
-
                     let timestamp = dt.unix_epoch();
 
                     let token = generate_otp_token(key, timestamp);
diff --git a/src/storage.rs b/src/storage.rs
index a3d88d6..7494c65 100644
--- a/src/storage.rs
+++ b/src/storage.rs
@@ -70,18 +70,18 @@ impl<'a> Tokens<'a> {
         let index_name = index * SECRET_KEY_FULL_LEN;
         let index_key = (index * SECRET_KEY_FULL_LEN) + SECRET_KEY_NAME_LEN;
         match self.mem.read(index_name, name) {
-            Ok(n) => {}
+            Ok(_) => {}
             Err(_) => return None,
         }
         match self.mem.read(index_key, key) {
-            Ok(n) => {}
+            Ok(_) => {}
             Err(_) => return None,
         }
-        let mut len_name = name
+        let len_name = name
             .iter()
             .position(|&n| n == 0)
             .unwrap_or(SECRET_KEY_NAME_LEN as usize);
-        let mut len_key = key
+        let len_key = key
             .iter()
             .position(|&n| n == 0)
             .unwrap_or(SECRET_KEY_MAX_LEN as usize);