Compare commits
No commits in common. "432a770887376222d2b7d2cff5edb5bde4ea7c66" and "90d3e4b4e95b279f7312014a65d47f4cab726a67" have entirely different histories.
432a770887
...
90d3e4b4e9
|
@ -12,7 +12,7 @@ dependencies = [
|
||||||
"avr-hal-generic",
|
"avr-hal-generic",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
"ufmt 0.1.2",
|
"ufmt",
|
||||||
"void",
|
"void",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -25,12 +25,6 @@ dependencies = [
|
||||||
"avr-hal-generic",
|
"avr-hal-generic",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "avr-device"
|
name = "avr-device"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -66,7 +60,7 @@ dependencies = [
|
||||||
"nb 0.1.3",
|
"nb 0.1.3",
|
||||||
"paste",
|
"paste",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"ufmt 0.1.2",
|
"ufmt",
|
||||||
"void",
|
"void",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -94,26 +88,6 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chrono"
|
|
||||||
version = "0.4.24"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b"
|
|
||||||
dependencies = [
|
|
||||||
"num-integer",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ds323x"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "057e63d03a3beb83d3c9b7a19b799c60e203b0c53f1bbec6a715804907f73a2b"
|
|
||||||
dependencies = [
|
|
||||||
"embedded-hal",
|
|
||||||
"rtcc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embedded-hal"
|
name = "embedded-hal"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
|
@ -145,25 +119,6 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
|
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-integer"
|
|
||||||
version = "0.1.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-traits"
|
|
||||||
version = "0.2.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "panic-halt"
|
name = "panic-halt"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -200,15 +155,6 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rtcc"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3623619ce77c09a7d87cf7c61c5c887b9c7dee8805f66af6c4aa5824be4d9930"
|
|
||||||
dependencies = [
|
|
||||||
"chrono",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
|
@ -221,10 +167,8 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arduino-hal",
|
"arduino-hal",
|
||||||
"binascii",
|
"binascii",
|
||||||
"ds323x",
|
|
||||||
"panic-halt",
|
"panic-halt",
|
||||||
"sha1_smol",
|
"sha1_smol",
|
||||||
"ufmt 0.2.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -251,17 +195,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "31d3c0c63312dfc9d8e5c71114d617018a19f6058674003c0da29ee8d8036cdd"
|
checksum = "31d3c0c63312dfc9d8e5c71114d617018a19f6058674003c0da29ee8d8036cdd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-hack",
|
"proc-macro-hack",
|
||||||
"ufmt-macros 0.2.0",
|
"ufmt-macros",
|
||||||
"ufmt-write",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ufmt"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1a64846ec02b57e9108d6469d98d1648782ad6bb150a95a9baac26900bbeab9d"
|
|
||||||
dependencies = [
|
|
||||||
"ufmt-macros 0.3.0",
|
|
||||||
"ufmt-write",
|
"ufmt-write",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -277,17 +211,6 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ufmt-macros"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d337d3be617449165cb4633c8dece429afd83f84051024079f97ad32a9663716"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ufmt-write"
|
name = "ufmt-write"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
|
@ -8,12 +8,10 @@ arduino-hal = { git = "https://github.com/rahix/avr-hal", features = ["arduino-
|
||||||
panic-halt = "0.2.0"
|
panic-halt = "0.2.0"
|
||||||
sha1_smol = "1.0.0"
|
sha1_smol = "1.0.0"
|
||||||
binascii = { version = "0.1", default-features = false, features = ["decode"] }
|
binascii = { version = "0.1", default-features = false, features = ["decode"] }
|
||||||
ds323x = "0.5.0"
|
|
||||||
ufmt = "0.2.0"
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
strip = true
|
strip = true
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
codegen-units = 1
|
codegen-units = 1
|
2
build.sh
2
build.sh
|
@ -1 +1 @@
|
||||||
cargo build -Z build-std-features=panic_immediate_abort -Z build-std=core --target avr-atmega328p.json --release
|
cargo build -Z build-std=core --target avr-atmega328p.json --release
|
||||||
|
|
122
src/datetime.rs
122
src/datetime.rs
|
@ -1,122 +0,0 @@
|
||||||
// This code was extracted from http://git.musl-libc.org/cgit/musl/tree/src/time?h=v0.9.15
|
|
||||||
|
|
||||||
pub struct Datetime {
|
|
||||||
pub year: u16,
|
|
||||||
pub month: u8,
|
|
||||||
pub day: u8,
|
|
||||||
pub hours: u8,
|
|
||||||
pub minutes: u8,
|
|
||||||
pub seconds: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
if month >= 12 || month < 0 {
|
|
||||||
let mut adj = month / 12;
|
|
||||||
month %= 12;
|
|
||||||
if month < 0 {
|
|
||||||
adj -= 1;
|
|
||||||
month += 12;
|
|
||||||
}
|
|
||||||
year += adj as i64;
|
|
||||||
}
|
|
||||||
let (mut t, is_leap) = year_to_secs(year);
|
|
||||||
t += month_to_secs(month, is_leap);
|
|
||||||
t += 86400 * (self.day as i64 - 1);
|
|
||||||
t += 3600 * self.hours as i64;
|
|
||||||
t += 60 * self.minutes as i64;
|
|
||||||
t += self.seconds as i64;
|
|
||||||
t as u64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn year_to_secs(year: i64) -> (i64, bool) {
|
|
||||||
let is_leap: bool;
|
|
||||||
let res: i64;
|
|
||||||
|
|
||||||
if year - 2 <= 136 {
|
|
||||||
let y = year as i32;
|
|
||||||
let mut leaps = (y - 68) >> 2;
|
|
||||||
if !((y - 68) & 3 != 0) {
|
|
||||||
leaps -= 1;
|
|
||||||
is_leap = true;
|
|
||||||
} else {
|
|
||||||
is_leap = false;
|
|
||||||
}
|
|
||||||
res = 31536000 * (y - 70) as i64 + 86400 * leaps as i64;
|
|
||||||
} else {
|
|
||||||
let mut cycles: i64;
|
|
||||||
let centuries: i64;
|
|
||||||
let mut leaps: i64;
|
|
||||||
let mut rem: i64;
|
|
||||||
|
|
||||||
cycles = (year - 100) / 400;
|
|
||||||
rem = (year - 100) % 400;
|
|
||||||
if rem < 0 {
|
|
||||||
cycles -= 1;
|
|
||||||
rem += 400;
|
|
||||||
}
|
|
||||||
if rem == 0 {
|
|
||||||
is_leap = true;
|
|
||||||
centuries = 0;
|
|
||||||
leaps = 0;
|
|
||||||
} else {
|
|
||||||
if rem >= 200 {
|
|
||||||
if rem >= 300 {
|
|
||||||
centuries = 3;
|
|
||||||
rem -= 300;
|
|
||||||
} else {
|
|
||||||
centuries = 2;
|
|
||||||
rem -= 200;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if rem >= 100 {
|
|
||||||
centuries = 1;
|
|
||||||
rem -= 100;
|
|
||||||
} else {
|
|
||||||
centuries = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if rem == 0 {
|
|
||||||
is_leap = false;
|
|
||||||
leaps = 0;
|
|
||||||
} else {
|
|
||||||
leaps = rem / 4;
|
|
||||||
rem %= 4;
|
|
||||||
is_leap = rem == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
leaps += 97 * cycles + 24 * centuries - (is_leap as i64);
|
|
||||||
|
|
||||||
res = (year - 100) * 31536000 + leaps * 86400 + 946684800 + 86400;
|
|
||||||
}
|
|
||||||
|
|
||||||
(res, is_leap)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn month_to_secs(month: i64, is_leap: bool) -> i64 {
|
|
||||||
const SECS_THROUGH_MONTH: [i64; 12] = [
|
|
||||||
0, // Jan
|
|
||||||
31 * 86400, // Feb
|
|
||||||
59 * 86400, // Mar
|
|
||||||
90 * 86400, // Apr
|
|
||||||
120 * 86400, // May
|
|
||||||
151 * 86400, // Jun
|
|
||||||
181 * 86400, // Jul
|
|
||||||
212 * 86400, // Aug
|
|
||||||
243 * 86400, // Sep
|
|
||||||
273 * 86400, // Oct
|
|
||||||
304 * 86400, // Nov
|
|
||||||
334 * 86400, // Dec
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut t = SECS_THROUGH_MONTH[month as usize];
|
|
||||||
if is_leap && month >= 2 {
|
|
||||||
t += 86400;
|
|
||||||
}
|
|
||||||
|
|
||||||
t
|
|
||||||
}
|
|
71
src/main.rs
71
src/main.rs
|
@ -2,17 +2,16 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
mod crypto;
|
mod crypto;
|
||||||
mod datetime;
|
|
||||||
|
|
||||||
use arduino_hal::default_serial;
|
use arduino_hal::hal::usart::BaudrateArduinoExt;
|
||||||
use arduino_hal::delay_ms;
|
use arduino_hal::prelude::*;
|
||||||
|
use arduino_hal::{delay_ms, Usart};
|
||||||
use crypto::hmac_sha1;
|
use crypto::hmac_sha1;
|
||||||
use ds323x::Rtcc;
|
|
||||||
|
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
const INTERVAL: u64 = 30;
|
const INTERVAL: u64 = 30;
|
||||||
const SECRET_KEY_MAX_LEN: usize = 32;
|
const SECRET_KEY_MAX_LEN: u8 = 32;
|
||||||
|
|
||||||
fn process_secret<'a>(secret: &str, output: &mut [u8]) -> usize {
|
fn process_secret<'a>(secret: &str, output: &mut [u8]) -> usize {
|
||||||
// RFC 6238 Doesn't specify a max length for the secret keys, So I chose 32
|
// RFC 6238 Doesn't specify a max length for the secret keys, So I chose 32
|
||||||
|
@ -41,7 +40,7 @@ fn process_secret<'a>(secret: &str, output: &mut [u8]) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_otp_token(private_key: &str, actual_time: u64) -> u32 {
|
fn generate_otp_token(private_key: &str, actual_time: u64) -> u32 {
|
||||||
let mut output = [0u8; 32];
|
let mut output = [0u8; 50];
|
||||||
let private_key_len = process_secret(private_key, &mut output);
|
let private_key_len = process_secret(private_key, &mut output);
|
||||||
|
|
||||||
let interval = actual_time / INTERVAL;
|
let interval = actual_time / INTERVAL;
|
||||||
|
@ -57,54 +56,38 @@ fn generate_otp_token(private_key: &str, actual_time: u64) -> u32 {
|
||||||
((raw_token & 0x7F_FF_FF_FF) % 1_000_000) as u32
|
((raw_token & 0x7F_FF_FF_FF) % 1_000_000) as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn token_to_bytes(mut token: u32, output: &mut [u8]) {
|
||||||
|
let mut inc = 0;
|
||||||
|
while token > 0 {
|
||||||
|
output[inc] = (token % 10) as u8 + b'0';
|
||||||
|
token /= 10;
|
||||||
|
inc += 1;
|
||||||
|
}
|
||||||
|
output.reverse()
|
||||||
|
}
|
||||||
|
|
||||||
#[arduino_hal::entry]
|
#[arduino_hal::entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
let dp = arduino_hal::Peripherals::take().unwrap();
|
let dp = arduino_hal::Peripherals::take().unwrap();
|
||||||
let pins = arduino_hal::pins!(dp);
|
let pins = arduino_hal::pins!(dp);
|
||||||
|
|
||||||
let mut led = pins.d13.into_output();
|
let mut led = pins.d13.into_output();
|
||||||
let mut serial = default_serial!(dp, pins, 9600);
|
let mut serial = Usart::new(
|
||||||
|
dp.USART0,
|
||||||
let i2c_clock = arduino_hal::I2c::new(
|
pins.d0,
|
||||||
dp.TWI,
|
pins.d1.into_output(),
|
||||||
pins.a4.into_pull_up_input(),
|
BaudrateArduinoExt::into_baudrate(9600),
|
||||||
pins.a5.into_pull_up_input(),
|
|
||||||
50000,
|
|
||||||
);
|
);
|
||||||
let mut rtc = ds323x::Ds323x::new_ds3231(i2c_clock);
|
|
||||||
|
|
||||||
let year = rtc.year().unwrap();
|
|
||||||
let month = rtc.month().unwrap();
|
|
||||||
let day = rtc.day().unwrap();
|
|
||||||
let hour = match rtc.hours().unwrap() {
|
|
||||||
ds323x::Hours::AM(val) => val,
|
|
||||||
ds323x::Hours::PM(val) => val + 12,
|
|
||||||
ds323x::Hours::H24(val) => val,
|
|
||||||
};
|
|
||||||
let minute = rtc.minutes().unwrap();
|
|
||||||
let second = rtc.seconds().unwrap();
|
|
||||||
|
|
||||||
let datetime = datetime::Datetime {
|
|
||||||
year: year,
|
|
||||||
month: month,
|
|
||||||
day: day,
|
|
||||||
hours: hour,
|
|
||||||
minutes: minute,
|
|
||||||
seconds: second,
|
|
||||||
};
|
|
||||||
let timestamp = datetime.unix_epoch();
|
|
||||||
ufmt::uwriteln!(&mut serial, "Timestamp: {}", timestamp);
|
|
||||||
|
|
||||||
|
// let token = generate_otp_token("holaaaaamundo", 1680155315);
|
||||||
let token = generate_otp_token("FS7J22EHLLSOGKUVJKV2XE7FTIX24JAJ", 1680155315);
|
let token = generate_otp_token("FS7J22EHLLSOGKUVJKV2XE7FTIX24JAJ", 1680155315);
|
||||||
ufmt::uwriteln!(&mut serial, "token: {}", token).unwrap();
|
let mut output = [0u8; 6];
|
||||||
|
token_to_bytes(token, &mut output);
|
||||||
|
|
||||||
delay_ms(5000);
|
for b in output {
|
||||||
let token = generate_otp_token("FS7J22EHLLSOGKUVJKV2XE7FTIX24JAJ", 1680155315);
|
serial.write_byte(b);
|
||||||
ufmt::uwriteln!(&mut serial, "token: {}", token).unwrap();
|
}
|
||||||
|
serial.write_byte('\n' as u8);
|
||||||
delay_ms(5000);
|
|
||||||
let token = generate_otp_token("FS7J22EHLLSOGKUVJKV2XE7FTIX24JAJ", 1680155315);
|
|
||||||
ufmt::uwriteln!(&mut serial, "token: {}", token).unwrap();
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
led.toggle();
|
led.toggle();
|
||||||
|
|
Loading…
Reference in New Issue