forked from joeycastillo/Sensor-Watch
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'structured-totp+maxz' into advanced
Aggregates the TOTP credentials into a data structure, making it easier to define and use the credentials. Also incorporate backwards movement code from another branch. Co-authored-by: Max Zettlmeißl <[email protected]> Tested-by: Matheus Afonso Martins Moreira <[email protected]> Signed-off-by: Matheus Afonso Martins Moreira <[email protected]> GitHub-Pull-Request: joeycastillo#369 GitHub-Related-Pull-Request: joeycastillo#356
- Loading branch information
Showing
4 changed files
with
117 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,16 @@ | ||
/* SPDX-License-Identifier: MIT */ | ||
|
||
/* | ||
* MIT License | ||
* | ||
* Copyright (c) 2022 Wesley Ellis (https://github.com/tahnok) | ||
* Copyright © 2021 Wesley Ellis (https://github.com/tahnok) | ||
* Copyright © 2021-2023 Joey Castillo <[email protected]> | ||
* Copyright © 2022 Jack Bond-Preston <[email protected]> | ||
* Copyright © 2023 Alex Utter <[email protected]> | ||
* Copyright © 2023 Emilien Court <[email protected]> | ||
* Copyright © 2023 Jeremy O'Brien <[email protected]> | ||
* Copyright © 2024 Matheus Afonso Martins Moreira <[email protected]> (https://www.matheusmoreira.com/) | ||
* Copyright © 2024 Max Zettlmeißl <[email protected]> | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
|
@@ -28,92 +37,140 @@ | |
#include "watch.h" | ||
#include "watch_utility.h" | ||
#include "TOTP.h" | ||
#include "base32.h" | ||
|
||
typedef struct { | ||
unsigned char labels[2]; | ||
hmac_alg algorithm; | ||
uint32_t period; | ||
size_t key_length; | ||
unsigned char *key; | ||
} totp_t; | ||
|
||
#define CREDENTIAL(label, key_array, algo, timestep) \ | ||
(const totp_t) { \ | ||
.key = ((unsigned char *) key_array), \ | ||
.key_length = sizeof(key_array) - 1, \ | ||
.period = (timestep), \ | ||
.labels = (#label), \ | ||
.algorithm = (algo), \ | ||
} | ||
|
||
//////////////////////////////////////////////////////////////////////////////// | ||
// Enter your TOTP key data below | ||
static const uint8_t num_keys = 2; | ||
static uint8_t keys[] = { | ||
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0xde, 0xad, 0xbe, 0xef, // 1 - JBSWY3DPEHPK3PXP | ||
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0xde, 0xad, 0xbe, 0xef, // 2 - JBSWY3DPEHPK3PXP | ||
}; | ||
static const uint8_t key_sizes[] = { | ||
10, | ||
10, | ||
}; | ||
static const uint32_t timesteps[] = { | ||
30, | ||
30, | ||
}; | ||
static const char labels[][2] = { | ||
{ '2', 'F' }, | ||
{ 'A', 'C' }, | ||
}; | ||
static const hmac_alg algorithms[] = { | ||
SHA1, | ||
SHA1, | ||
|
||
static totp_t credentials[] = { | ||
CREDENTIAL(2F, "JBSWY3DPEHPK3PXP", SHA1, 30), | ||
CREDENTIAL(AC, "JBSWY3DPEHPK3PXP", SHA1, 30), | ||
}; | ||
|
||
// END OF KEY DATA. | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
static void _update_display(totp_state_t *totp_state) { | ||
static inline totp_t *totp_current(totp_state_t *totp_state) { | ||
return &credentials[totp_state->current_index]; | ||
} | ||
|
||
static inline size_t totp_total(void) { | ||
return sizeof(credentials) / sizeof(*credentials); | ||
} | ||
|
||
static void totp_display(totp_state_t *totp_state) { | ||
char buf[14]; | ||
div_t result; | ||
uint8_t valid_for; | ||
totp_t *totp = totp_current(totp_state); | ||
|
||
result = div(totp_state->timestamp, timesteps[totp_state->current_index]); | ||
result = div(totp_state->timestamp, totp->period); | ||
if (result.quot != totp_state->steps) { | ||
totp_state->current_code = getCodeFromTimestamp(totp_state->timestamp); | ||
totp_state->steps = result.quot; | ||
} | ||
valid_for = timesteps[totp_state->current_index] - result.rem; | ||
sprintf(buf, "%c%c%2d%06lu", labels[totp_state->current_index][0], labels[totp_state->current_index][1], valid_for, totp_state->current_code); | ||
valid_for = totp->period - result.rem; | ||
sprintf(buf, "%c%c%2d%06lu", totp->labels[0], totp->labels[1], valid_for, totp_state->current_code); | ||
|
||
watch_display_string(buf, 0); | ||
} | ||
|
||
static void totp_face_decode_secrets(void) { | ||
for (size_t n = totp_total(), i = 0; i < n; ++i) { | ||
totp_t *totp = &credentials[i]; | ||
unsigned char *key = totp->key; | ||
|
||
totp->key = malloc(UNBASE32_LEN(totp->key_length)); | ||
totp->key_length = base32_decode(key, totp->key); | ||
|
||
if (totp->key_length == 0) { | ||
free(totp->key); | ||
continue; | ||
} | ||
} | ||
} | ||
|
||
void totp_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { | ||
(void) settings; | ||
(void) watch_face_index; | ||
if (*context_ptr == NULL) *context_ptr = malloc(sizeof(totp_state_t)); | ||
|
||
if (*context_ptr == NULL) { | ||
totp_state_t *totp = malloc(sizeof(totp_state_t)); | ||
totp_face_decode_secrets(); | ||
*context_ptr = totp; | ||
} | ||
} | ||
|
||
void totp_face_activate(movement_settings_t *settings, void *context) { | ||
(void) settings; | ||
memset(context, 0, sizeof(totp_state_t)); | ||
totp_state_t *totp_state = (totp_state_t *)context; | ||
TOTP(keys, key_sizes[0], timesteps[0], algorithms[0]); | ||
totp_t *totp = totp_current(totp_state); | ||
TOTP(totp->key, totp->key_length, totp->period, totp->algorithm); | ||
totp_state->timestamp = watch_utility_date_time_to_unix_time(watch_rtc_get_date_time(), movement_timezone_offsets[settings->bit.time_zone] * 60); | ||
totp_state->current_code = getCodeFromTimestamp(totp_state->timestamp); | ||
} | ||
|
||
bool totp_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { | ||
(void) settings; | ||
totp_state_t *totp_state = (totp_state_t *)context; | ||
totp_t *totp; | ||
|
||
switch (event.event_type) { | ||
case EVENT_TICK: | ||
totp_state->timestamp++; | ||
// fall through | ||
case EVENT_ACTIVATE: | ||
_update_display(totp_state); | ||
totp_display(totp_state); | ||
break; | ||
case EVENT_TIMEOUT: | ||
movement_move_to_face(0); | ||
break; | ||
case EVENT_ALARM_BUTTON_UP: | ||
if (totp_state->current_index + 1 < num_keys) { | ||
totp_state->current_key_offset += key_sizes[totp_state->current_index]; | ||
if (totp_state->current_index + 1 < totp_total()) { | ||
totp_state->current_index++; | ||
} else { | ||
// wrap around to first key | ||
totp_state->current_key_offset = 0; | ||
totp_state->current_index = 0; | ||
} | ||
TOTP(keys + totp_state->current_key_offset, key_sizes[totp_state->current_index], timesteps[totp_state->current_index], algorithms[totp_state->current_index]); | ||
_update_display(totp_state); | ||
totp = totp_current(totp_state); | ||
TOTP(totp->key, totp->key_length, totp->period, totp->algorithm); | ||
totp_display(totp_state); | ||
break; | ||
case EVENT_LIGHT_BUTTON_UP: | ||
if (totp_state->current_index == 0) { | ||
// Wrap around to the last credential. | ||
totp_state->current_index = totp_total() - 1; | ||
} else { | ||
totp_state->current_index--; | ||
} | ||
totp = totp_current(totp_state); | ||
TOTP(totp->key, totp->key_length, totp->period, totp->algorithm); | ||
totp_display(totp_state); | ||
break; | ||
case EVENT_ALARM_BUTTON_DOWN: | ||
case EVENT_ALARM_LONG_PRESS: | ||
case EVENT_LIGHT_BUTTON_DOWN: | ||
break; | ||
case EVENT_LIGHT_LONG_PRESS: | ||
movement_illuminate_led(); | ||
break; | ||
default: | ||
movement_default_loop_handler(event, settings); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,15 @@ | ||
/* SPDX-License-Identifier: MIT */ | ||
|
||
/* | ||
* MIT License | ||
* | ||
* Copyright (c) 2022 Wesley Ellis (https://github.com/tahnok) | ||
* Copyright © 2021 Wesley Ellis (https://github.com/tahnok) | ||
* Copyright © 2021-2022 Joey Castillo <[email protected]> | ||
* Copyright © 2022 Alexsander Akers <[email protected]> | ||
* Copyright © 2022 Jack Bond-Preston <[email protected]> | ||
* Copyright © 2023 Alex Utter <[email protected]> | ||
* Copyright © 2024 Matheus Afonso Martins Moreira <[email protected]> (https://www.matheusmoreira.com/) | ||
* Copyright © 2024 Max Zettlmeißl <[email protected]> | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
|
@@ -51,6 +59,8 @@ | |
* o Once finished, remove the two provided examples. | ||
* | ||
* If you have more than one secret key, press ALARM to cycle through them. | ||
* Press LIGHT to cycle in the other direction or keep it pressed longer to | ||
* activate the light. | ||
*/ | ||
|
||
#include "movement.h" | ||
|
@@ -60,7 +70,6 @@ typedef struct { | |
uint8_t steps; | ||
uint32_t current_code; | ||
uint8_t current_index; | ||
uint8_t current_key_offset; | ||
} totp_state_t; | ||
|
||
void totp_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters