Compare commits

..

No commits in common. "90d3e4b4e95b279f7312014a65d47f4cab726a67" and "41efcce00f3709f64af2fdc69a90ac882c7becab" have entirely different histories.

6 changed files with 2394 additions and 53 deletions

2
.gitignore vendored
View File

@ -1,3 +1 @@
/target /target
Cargo.lock

View File

@ -12,6 +12,3 @@ binascii = { version = "0.1", default-features = false, features = ["decode"] }
[profile.release] [profile.release]
lto = true lto = true
panic = "abort" panic = "abort"
strip = true
opt-level = "z"
codegen-units = 1

View File

@ -1 +1,2 @@
cargo build -Z build-std=core --target avr-atmega328p.json --release cargo build -Z build-std=core --target avr-atmega328p.json --release
avr-objcopy -O ihex -R .eeprom target/avr-atmega328p/release/rustytoken.elf rustytoken.hex

2339
rustytoken.hex 100644

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +1,23 @@
#![no_std] // #![no_std]
#![no_main] // #![no_main]
mod crypto; mod crypto;
use arduino_hal::hal::usart::BaudrateArduinoExt; use arduino_hal::hal::usart::BaudrateArduinoExt;
use arduino_hal::prelude::*; use arduino_hal::prelude::*;
use arduino_hal::{delay_ms, Usart}; use arduino_hal::{delay_ms, Usart};
use binascii::b32decode;
use crypto::hmac_sha1; use crypto::hmac_sha1;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use panic_halt as _; // use panic_halt as _;
const INTERVAL: u64 = 30; const INTERVAL: u64 = 30;
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 let mut result = [0u8; 32];
// You can change the max length by modifying the const
let mut result = [0u8; SECRET_KEY_MAX_LEN];
let mut inc = 0; let mut inc = 0;
let offset = match 8 - (secret.len() % 8) { let offset = 8 - (secret.len() % 8);
8 => 0,
n => n,
};
for c in secret.chars() { for c in secret.chars() {
result[inc] = c.to_ascii_uppercase() as u8; result[inc] = c.to_ascii_uppercase() as u8;
@ -34,63 +30,73 @@ fn process_secret<'a>(secret: &str, output: &mut [u8]) -> usize {
let decoded = match binascii::b32decode(&result[..inc], output).ok() { let decoded = match binascii::b32decode(&result[..inc], output).ok() {
Some(bytes) => bytes, Some(bytes) => bytes,
None => "".as_bytes(), // TODO: Implement a way to display errors None => "".as_bytes(),
}; };
decoded.len() decoded.len()
} }
fn generate_otp_token(private_key: &str, actual_time: u64) -> u32 { fn generate_otp_token(private_key: &str, actual_time: u64) -> u64 {
let mut output = [0u8; 50]; let mut output = [0u8; 200];
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;
let msg = interval.to_be_bytes(); let msg = interval.to_be_bytes();
println!("key:\n{private_key:?}");
println!("msg:\n{msg:?}");
let mut hmac_digest = [0u8; 20]; let mut hmac_digest = [0u8; 20];
hmac_sha1(&output[..private_key_len], &msg, &mut hmac_digest); hmac_sha1(&output[..private_key_len], &msg, &mut hmac_digest);
println!("{:?}", hmac_digest);
let start = (hmac_digest[19] & 0xF) as usize; let start = (hmac_digest[19] & 0xF) as usize;
println!("Start before process: {}", hmac_digest[19]);
println!("start: {start}");
let bytes: [u8; 4] = hmac_digest[start..start + 4].try_into().unwrap(); let bytes: [u8; 4] = hmac_digest[start..start + 4].try_into().unwrap();
println!("bytes: {bytes:?}");
let raw_token = u32::from_be_bytes(bytes); let raw_token = u32::from_be_bytes(bytes);
((raw_token & 0x7F_FF_FF_FF) % 1_000_000) as u32 println!("raw token: {raw_token}");
((raw_token & 0x7F_FF_FF_FF) % 1_000_000) as u64
} }
fn token_to_bytes(mut token: u32, output: &mut [u8]) { fn main() {
let mut inc = 0; // let now = SystemTime::now();
while token > 0 { // let elapsed = now.duration_since(UNIX_EPOCH).unwrap();
output[inc] = (token % 10) as u8 + b'0'; // let seconds = elapsed.as_secs();
token /= 10; // println!("seconds: {seconds}");
inc += 1;
}
output.reverse()
}
#[arduino_hal::entry] // let otp_token = generate_otp_token("holaaaaamundo", seconds);
fn main() -> ! {
let dp = arduino_hal::Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp);
let mut led = pins.d13.into_output(); // println!("{:06}", otp_token);
let mut serial = Usart::new( // std::thread::sleep(Duration::from_secs(1));
dp.USART0,
pins.d0,
pins.d1.into_output(),
BaudrateArduinoExt::into_baudrate(9600),
);
// let token = generate_otp_token("holaaaaamundo", 1680155315);
let token = generate_otp_token("FS7J22EHLLSOGKUVJKV2XE7FTIX24JAJ", 1680155315);
let mut output = [0u8; 6];
token_to_bytes(token, &mut output);
for b in output {
serial.write_byte(b);
}
serial.write_byte('\n' as u8);
loop { loop {
led.toggle(); let now = SystemTime::now();
delay_ms(1000); let elapsed = now.duration_since(UNIX_EPOCH).unwrap();
let seconds = elapsed.as_secs();
let otp_token = generate_otp_token("holaaaaamundo", seconds);
println!("{:06}", otp_token);
std::thread::sleep(Duration::from_secs(1));
} }
} }
// #[arduino_hal::entry]
// fn main() -> ! {
// let dp = arduino_hal::Peripherals::take().unwrap();
// let pins = arduino_hal::pins!(dp);
//
// let mut led = pins.d13.into_output();
// let mut serial = Usart::new(
// dp.USART0,
// pins.d0,
// pins.d1.into_output(),
// BaudrateArduinoExt::into_baudrate(9600),
// );
//
// loop {
// led.toggle();
// delay_ms(1000);
// }
// }

View File

@ -1 +1 @@
avrdude -p atmega328p -c arduino -P /dev/ttyACM0 -U flash:w:target/avr-atmega328p/release/rustytoken.elf:e avrdude -p atmega328p -c arduino -P /dev/ttyACM0 -U flash:w:rustytoken.hex:i