mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
Update totp
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -41,3 +41,6 @@
|
||||
[submodule "lib/stm32wb_copro"]
|
||||
path = lib/stm32wb_copro
|
||||
url = https://github.com/flipperdevices/stm32wb_copro.git
|
||||
[submodule "applications/external/totp/lib/wolfssl"]
|
||||
path = applications/external/totp/lib/wolfssl
|
||||
url = https://github.com/wolfSSL/wolfssl.git
|
||||
|
||||
26
applications/external/totp/application.fam
vendored
26
applications/external/totp/application.fam
vendored
@@ -4,10 +4,18 @@ App(
|
||||
apptype=FlipperAppType.EXTERNAL,
|
||||
entry_point="totp_app",
|
||||
cdefines=["APP_TOTP"],
|
||||
requires=["gui", "cli", "dialogs", "storage", "input", "notification", "bt"],
|
||||
requires=[
|
||||
"gui",
|
||||
"cli",
|
||||
"dialogs",
|
||||
"storage",
|
||||
"input",
|
||||
"notification",
|
||||
"bt"
|
||||
],
|
||||
stack_size=2 * 1024,
|
||||
order=20,
|
||||
fap_version="3.20",
|
||||
fap_version="4.01",
|
||||
fap_author="Alexander Kopachov (@akopachov)",
|
||||
fap_description="Software-based TOTP authenticator for Flipper Zero device",
|
||||
fap_weburl="https://github.com/akopachov/flipper-zero_authenticator",
|
||||
@@ -33,5 +41,19 @@ App(
|
||||
Lib(
|
||||
name="fonts",
|
||||
),
|
||||
Lib(
|
||||
name="wolfssl",
|
||||
sources=[
|
||||
"wolfcrypt/src/pwdbased.c",
|
||||
"wolfcrypt/src/hmac.c",
|
||||
"wolfcrypt/src/hash.c",
|
||||
"wolfcrypt/src/sha.c",
|
||||
"wolfcrypt/src/sha256.c",
|
||||
"wolfcrypt/src/sha512.c"
|
||||
],
|
||||
cflags=["-Wno-error"],
|
||||
cdefines=["HAVE_CONFIG_H"],
|
||||
cincludes=["config/wolfssl"]
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -79,6 +79,7 @@ static TotpIteratorUpdateTokenResult
|
||||
return TotpIteratorUpdateTokenResultSuccess;
|
||||
}
|
||||
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_add_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_ADD ", " TOTP_CLI_COMMAND_ADD_ALT
|
||||
", " TOTP_CLI_COMMAND_ADD_ALT2 " Add new token\r\n");
|
||||
@@ -155,6 +156,7 @@ void totp_cli_command_add_docopt_options() {
|
||||
TOTP_CLI_PRINTF(" # " TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME
|
||||
" - Type slower\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
|
||||
if(!totp_cli_ensure_authenticated(plugin_state, cli)) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include "../../../config/app/config.h"
|
||||
#include "../../../types/plugin_state.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_ADD "add"
|
||||
@@ -8,7 +9,9 @@
|
||||
#define TOTP_CLI_COMMAND_ADD_ALT2 "new"
|
||||
|
||||
void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_add_docopt_commands();
|
||||
void totp_cli_command_add_docopt_usage();
|
||||
void totp_cli_command_add_docopt_arguments();
|
||||
void totp_cli_command_add_docopt_options();
|
||||
void totp_cli_command_add_docopt_options();
|
||||
#endif
|
||||
@@ -15,6 +15,7 @@
|
||||
#define TOTP_CLI_COMMAND_AUTOMATION_ARG_KB_LAYOUT_PREFIX "-k"
|
||||
#define TOTP_CLI_COMMAND_AUTOMATION_ARG_KB_LAYOUT "layout"
|
||||
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_automation_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_AUTOMATION " Get or set automation settings\r\n");
|
||||
}
|
||||
@@ -45,6 +46,7 @@ void totp_cli_command_automation_docopt_options() {
|
||||
", " TOTP_CLI_COMMAND_AUTOMATION_LAYOUT_AZERTY
|
||||
"\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void print_method(AutomationMethod method, const char* color) {
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../config/app/config.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_AUTOMATION "automation"
|
||||
|
||||
void totp_cli_command_automation_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_automation_docopt_commands();
|
||||
void totp_cli_command_automation_docopt_usage();
|
||||
void totp_cli_command_automation_docopt_arguments();
|
||||
void totp_cli_command_automation_docopt_options();
|
||||
void totp_cli_command_automation_docopt_options();
|
||||
#endif
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#define TOTP_CLI_COMMAND_DELETE_ARG_FORCE_PREFIX "-f"
|
||||
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_delete_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_DELETE ", " TOTP_CLI_COMMAND_DELETE_ALT
|
||||
" Delete existing token\r\n");
|
||||
@@ -30,6 +31,7 @@ void totp_cli_command_delete_docopt_options() {
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_SWITCH(
|
||||
TOTP_CLI_COMMAND_DELETE_ARG_FORCE_PREFIX) " Force command to do not ask user for interactive confirmation\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
|
||||
if(!totp_cli_ensure_authenticated(plugin_state, cli)) {
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../config/app/config.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_DELETE "delete"
|
||||
#define TOTP_CLI_COMMAND_DELETE_ALT "rm"
|
||||
|
||||
void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_delete_docopt_commands();
|
||||
void totp_cli_command_delete_docopt_usage();
|
||||
void totp_cli_command_delete_docopt_arguments();
|
||||
void totp_cli_command_delete_docopt_options();
|
||||
void totp_cli_command_delete_docopt_options();
|
||||
#endif
|
||||
|
||||
@@ -37,6 +37,7 @@ static void print_automation_features(const TokenInfo* token_info) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_details_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_DETAILS ", " TOTP_CLI_COMMAND_DETAILS_ALT
|
||||
" Displays token details\r\n");
|
||||
@@ -47,6 +48,7 @@ void totp_cli_command_details_docopt_usage() {
|
||||
TOTP_CLI_COMMAND_DETAILS
|
||||
" | " TOTP_CLI_COMMAND_DETAILS_ALT) " " DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_INDEX) "\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void totp_cli_command_details_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
|
||||
if(!totp_cli_ensure_authenticated(plugin_state, cli)) {
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../config/app/config.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_DETAILS "lsattr"
|
||||
#define TOTP_CLI_COMMAND_DETAILS_ALT "cat"
|
||||
|
||||
void totp_cli_command_details_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_details_docopt_commands();
|
||||
void totp_cli_command_details_docopt_usage();
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "../automation/automation.h"
|
||||
#include "../details/details.h"
|
||||
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_help_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_HELP ", " TOTP_CLI_COMMAND_HELP_ALT
|
||||
", " TOTP_CLI_COMMAND_HELP_ALT2 " Show command usage help\r\n");
|
||||
@@ -22,8 +23,10 @@ void totp_cli_command_help_docopt_usage() {
|
||||
TOTP_CLI_COMMAND_HELP " | " TOTP_CLI_COMMAND_HELP_ALT
|
||||
" | " TOTP_CLI_COMMAND_HELP_ALT2) "\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void totp_cli_command_help_handle() {
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
TOTP_CLI_PRINTF("Usage:\r\n");
|
||||
totp_cli_command_help_docopt_usage();
|
||||
totp_cli_command_list_docopt_usage();
|
||||
@@ -66,4 +69,8 @@ void totp_cli_command_help_handle() {
|
||||
totp_cli_command_delete_docopt_options();
|
||||
totp_cli_command_pin_docopt_options();
|
||||
totp_cli_command_automation_docopt_options();
|
||||
#else
|
||||
TOTP_CLI_PRINTF(
|
||||
"All the TOTP CLI commands, their arguments, options and usage can be found here https://t.ly/_6pJG");
|
||||
#endif
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../../config/app/config.h"
|
||||
#include <cli/cli.h>
|
||||
|
||||
#define TOTP_CLI_COMMAND_HELP "help"
|
||||
@@ -7,5 +8,7 @@
|
||||
#define TOTP_CLI_COMMAND_HELP_ALT2 "?"
|
||||
|
||||
void totp_cli_command_help_handle();
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_help_docopt_commands();
|
||||
void totp_cli_command_help_docopt_usage();
|
||||
void totp_cli_command_help_docopt_usage();
|
||||
#endif
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "../../../ui/scene_director.h"
|
||||
#include "../../cli_helpers.h"
|
||||
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_list_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_LIST ", " TOTP_CLI_COMMAND_LIST_ALT
|
||||
" List all available tokens\r\n");
|
||||
@@ -15,6 +16,7 @@ void totp_cli_command_list_docopt_usage() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_NAME " " DOCOPT_REQUIRED(
|
||||
TOTP_CLI_COMMAND_LIST " | " TOTP_CLI_COMMAND_LIST_ALT) "\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli) {
|
||||
if(!totp_cli_ensure_authenticated(plugin_state, cli)) {
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../config/app/config.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_LIST "list"
|
||||
#define TOTP_CLI_COMMAND_LIST_ALT "ls"
|
||||
|
||||
void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli);
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_list_docopt_commands();
|
||||
void totp_cli_command_list_docopt_usage();
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#define TOTP_CLI_COMMAND_MOVE_ARG_NEW_INDEX "new_index"
|
||||
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_move_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_MOVE ", " TOTP_CLI_COMMAND_MOVE_ALT
|
||||
" Move token\r\n");
|
||||
@@ -26,6 +27,7 @@ void totp_cli_command_move_docopt_arguments() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_MOVE_ARG_NEW_INDEX
|
||||
" New token index in the list\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void totp_cli_command_move_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
|
||||
if(!totp_cli_ensure_authenticated(plugin_state, cli)) {
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../config/app/config.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_MOVE "move"
|
||||
#define TOTP_CLI_COMMAND_MOVE_ALT "mv"
|
||||
|
||||
void totp_cli_command_move_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_move_docopt_commands();
|
||||
void totp_cli_command_move_docopt_usage();
|
||||
void totp_cli_command_move_docopt_arguments();
|
||||
void totp_cli_command_move_docopt_arguments();
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_SOUND "sound"
|
||||
#define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_VIBRO "vibro"
|
||||
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_notification_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_NOTIFICATION
|
||||
" Get or set notification method\r\n");
|
||||
@@ -27,6 +28,7 @@ void totp_cli_command_notification_docopt_arguments() {
|
||||
", " TOTP_CLI_COMMAND_NOTIFICATION_METHOD_SOUND
|
||||
", " TOTP_CLI_COMMAND_NOTIFICATION_METHOD_VIBRO "\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
totp_cli_command_notification_print_method(NotificationMethod method, const char* color) {
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../config/app/config.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_NOTIFICATION "notify"
|
||||
|
||||
void totp_cli_command_notification_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_notification_docopt_commands();
|
||||
void totp_cli_command_notification_docopt_usage();
|
||||
void totp_cli_command_notification_docopt_arguments();
|
||||
void totp_cli_command_notification_docopt_arguments();
|
||||
#endif
|
||||
@@ -15,6 +15,7 @@
|
||||
#define TOTP_CLI_COMMAND_PIN_ARG_NEW_CRYPTO_KEY_SLOT_PREFIX "-c"
|
||||
#define TOTP_CLI_COMMAND_PIN_ARG_NEW_CRYPTO_KEY_SLOT "slot"
|
||||
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_pin_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_PIN " Set\\change\\remove PIN\r\n");
|
||||
}
|
||||
@@ -37,6 +38,7 @@ void totp_cli_command_pin_docopt_options() {
|
||||
ACCEPTABLE_CRYPTO_KEY_SLOT_START,
|
||||
ACCEPTABLE_CRYPTO_KEY_SLOT_END);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint8_t totp_cli_key_to_pin_code(uint8_t key) {
|
||||
uint8_t code = 0;
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../config/app/config.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_PIN "pin"
|
||||
|
||||
void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_pin_docopt_commands();
|
||||
void totp_cli_command_pin_docopt_usage();
|
||||
void totp_cli_command_pin_docopt_options();
|
||||
void totp_cli_command_pin_docopt_options();
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#define TOTP_CLI_RESET_CONFIRMATION_KEYWORD "YES"
|
||||
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_reset_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_RESET
|
||||
" Reset application to default settings\r\n");
|
||||
@@ -16,6 +17,7 @@ void totp_cli_command_reset_docopt_commands() {
|
||||
void totp_cli_command_reset_docopt_usage() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_NAME " " TOTP_CLI_COMMAND_RESET "\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void totp_cli_command_reset_handle(PluginState* plugin_state, Cli* cli) {
|
||||
TOTP_CLI_LOCK_UI(plugin_state);
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../config/app/config.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_RESET "reset"
|
||||
|
||||
void totp_cli_command_reset_handle(PluginState* plugin_state, Cli* cli);
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_reset_docopt_commands();
|
||||
void totp_cli_command_reset_docopt_usage();
|
||||
void totp_cli_command_reset_docopt_usage();
|
||||
#endif
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#define TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE "timezone"
|
||||
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_timezone_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_TIMEZONE ", " TOTP_CLI_COMMAND_TIMEZONE_ALT
|
||||
" Get or set current timezone\r\n");
|
||||
@@ -22,6 +23,7 @@ void totp_cli_command_timezone_docopt_arguments() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE
|
||||
" Timezone offset in hours to be set\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
|
||||
if(!totp_cli_ensure_authenticated(plugin_state, cli)) {
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../config/app/config.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_TIMEZONE "timezone"
|
||||
#define TOTP_CLI_COMMAND_TIMEZONE_ALT "tz"
|
||||
|
||||
void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_timezone_docopt_commands();
|
||||
void totp_cli_command_timezone_docopt_usage();
|
||||
void totp_cli_command_timezone_docopt_arguments();
|
||||
void totp_cli_command_timezone_docopt_arguments();
|
||||
#endif
|
||||
|
||||
@@ -107,6 +107,7 @@ static TotpIteratorUpdateTokenResult
|
||||
return TotpIteratorUpdateTokenResultSuccess;
|
||||
}
|
||||
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_update_docopt_commands() {
|
||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_UPDATE " Update existing token\r\n");
|
||||
}
|
||||
@@ -129,6 +130,7 @@ void totp_cli_command_update_docopt_options() {
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_SWITCH(
|
||||
TOTP_CLI_COMMAND_UPDATE_ARG_SECRET_PREFIX) " Update token secret\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void totp_cli_command_update_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
|
||||
if(!totp_cli_ensure_authenticated(plugin_state, cli)) {
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
#include <cli/cli.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../config/app/config.h"
|
||||
|
||||
#define TOTP_CLI_COMMAND_UPDATE "update"
|
||||
|
||||
void totp_cli_command_update_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
|
||||
#ifdef TOTP_CLI_RICH_HELP_ENABLED
|
||||
void totp_cli_command_update_docopt_commands();
|
||||
void totp_cli_command_update_docopt_usage();
|
||||
void totp_cli_command_update_docopt_options();
|
||||
void totp_cli_command_update_docopt_options();
|
||||
#endif
|
||||
42
applications/external/totp/config/app/config.h
vendored
Normal file
42
applications/external/totp/config/app/config.h
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// Application automatic lock timeout if user IDLE. (ticks)
|
||||
#ifndef TOTP_AUTO_LOCK_IDLE_TIMEOUT_SEC
|
||||
#define TOTP_AUTO_LOCK_IDLE_TIMEOUT_SEC (60)
|
||||
#endif
|
||||
|
||||
// Enables\disables Bluetooth token input automation
|
||||
#ifndef TOTP_NO_BADBT_AUTOMATION
|
||||
#define TOTP_BADBT_AUTOMATION_ENABLED
|
||||
#endif
|
||||
|
||||
// Enables\disables backward compatibility with crypto algorithms v1
|
||||
#ifndef TOTP_NO_OBSOLETE_CRYPTO_V1_COMPATIBILITY
|
||||
#define TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
|
||||
#endif
|
||||
|
||||
// Enables\disables backward compatibility with crypto algorithms v2
|
||||
#ifndef TOTP_NO_OBSOLETE_CRYPTO_V2_COMPATIBILITY
|
||||
#define TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
|
||||
#endif
|
||||
|
||||
// Enables\disables userfriendly TOTP CLI help text
|
||||
// If disabled, it will print a link to a wiki page
|
||||
#ifndef TOTP_CLI_NO_RICH_HELP
|
||||
#define TOTP_CLI_RICH_HELP_ENABLED
|
||||
#endif
|
||||
|
||||
// Enables\disables "Add new token" UI
|
||||
// If disabled it will print a link to wiki page
|
||||
#ifndef TOTP_UI_NO_ADD_NEW_TOKEN
|
||||
#define TOTP_UI_ADD_NEW_TOKEN_ENABLED
|
||||
#endif
|
||||
|
||||
// List of compatible firmwares
|
||||
#define TOTP_FIRMWARE_OFFICIAL_STABLE (1)
|
||||
#define TOTP_FIRMWARE_OFFICIAL_DEV (2)
|
||||
#define TOTP_FIRMWARE_XTREME_UL (3)
|
||||
// End of list
|
||||
|
||||
// Target firmware
|
||||
#ifndef TOTP_TARGET_FIRMWARE
|
||||
#define TOTP_TARGET_FIRMWARE TOTP_FIRMWARE_XTREME_UL
|
||||
#endif
|
||||
34
applications/external/totp/config/wolfssl/config.h
vendored
Normal file
34
applications/external/totp/config/wolfssl/config.h
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#define NO_OLD_SHA_NAMES
|
||||
#define WOLFCRYPT_ONLY
|
||||
#define NO_SIG_WRAPPER
|
||||
#define NO_AES
|
||||
#define NO_AES_CBC
|
||||
#define NO_DES3
|
||||
#define NO_DSA
|
||||
#define NO_RSA
|
||||
#define NO_DH
|
||||
#define NO_RC4
|
||||
#define NO_MD4
|
||||
#define NO_MD5
|
||||
#define NO_PKCS12
|
||||
#define NO_PKCS8
|
||||
#define WC_NO_RNG
|
||||
#define NO_FILESYSTEM
|
||||
#define NO_WRITEV
|
||||
#define NO_MAIN_DRIVER
|
||||
#define NO_DEV_RANDOM
|
||||
#define WOLFSSL_SHA512
|
||||
#define WOLFSSL_NOSHA512_224
|
||||
#define WOLFSSL_NOSHA512_256
|
||||
#define USE_SLOW_SHA512
|
||||
#define USE_SLOW_SHA256
|
||||
#define USE_SLOW_SHA
|
||||
#define NO_CERTS
|
||||
#define NO_WOLFSSL_MEMORY
|
||||
#define WOLFSSL_NO_PEM
|
||||
#define NO_PSK
|
||||
#define NO_ERROR_STRINGS
|
||||
#define NO_OLD_TLS
|
||||
#define SINGLE_THREADED
|
||||
20
applications/external/totp/features_config.h
vendored
20
applications/external/totp/features_config.h
vendored
@@ -1,20 +0,0 @@
|
||||
// Application automatic lock timeout if user IDLE. (ticks)
|
||||
#ifndef TOTP_AUTO_LOCK_IDLE_TIMEOUT_SEC
|
||||
#define TOTP_AUTO_LOCK_IDLE_TIMEOUT_SEC (60)
|
||||
#endif
|
||||
|
||||
// Include Bluetooth token input automation
|
||||
#ifndef TOTP_NO_BADBT_AUTOMATION
|
||||
#define TOTP_BADBT_AUTOMATION_ENABLED
|
||||
#endif
|
||||
|
||||
// List of compatible firmwares
|
||||
#define TOTP_FIRMWARE_OFFICIAL_STABLE (1)
|
||||
#define TOTP_FIRMWARE_OFFICIAL_DEV (2)
|
||||
#define TOTP_FIRMWARE_XTREME_UL (3)
|
||||
// End of list
|
||||
|
||||
// Target firmware
|
||||
#ifndef TOTP_TARGET_FIRMWARE
|
||||
#define TOTP_TARGET_FIRMWARE TOTP_FIRMWARE_XTREME_UL
|
||||
#endif
|
||||
@@ -25,4 +25,4 @@ TOTP_ROLL_VALUE_FN(int8_t, int8_t)
|
||||
|
||||
TOTP_ROLL_VALUE_FN(uint8_t, int8_t)
|
||||
|
||||
TOTP_ROLL_VALUE_FN(size_t, int16_t)
|
||||
TOTP_ROLL_VALUE_FN(size_t, int16_t);
|
||||
1
applications/external/totp/lib/wolfssl
vendored
Submodule
1
applications/external/totp/lib/wolfssl
vendored
Submodule
Submodule applications/external/totp/lib/wolfssl added at d3d131d08d
@@ -8,7 +8,7 @@
|
||||
#include <memset_s.h>
|
||||
#include "../../types/common.h"
|
||||
#include "../../types/token_info.h"
|
||||
#include "../../features_config.h"
|
||||
#include "../../config/app/config.h"
|
||||
#include "../crypto/crypto_facade.h"
|
||||
#include "../crypto/constants.h"
|
||||
#include "migrations/common_migration.h"
|
||||
@@ -112,7 +112,8 @@ static bool totp_open_config_file(Storage* storage, FlipperFormat** file) {
|
||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
||||
|
||||
bool conf_file_exists = storage_common_stat(storage, CONFIG_FILE_PATH, NULL) == FSE_OK;
|
||||
if(!conf_file_exists) {
|
||||
if(!conf_file_exists &&
|
||||
storage_common_stat(storage, EXT_PATH("authenticator"), NULL) == FSE_OK) {
|
||||
FURI_LOG_I(LOGGING_TAG, "Application catalog needs to be migrated");
|
||||
FS_Error migration_result =
|
||||
storage_common_migrate(storage, EXT_PATH("authenticator"), CONFIG_FILE_DIRECTORY_PATH);
|
||||
@@ -148,7 +149,7 @@ static bool totp_open_config_file(Storage* storage, FlipperFormat** file) {
|
||||
|
||||
flipper_format_write_comment_cstr(
|
||||
fff_data_file,
|
||||
"Config file format specification can be found here: https://github.com/akopachov/flipper-zero_authenticator/blob/master/docs/conf-file_description.md");
|
||||
"Config file format specification can be found here: https://t.ly/zwQjE");
|
||||
|
||||
float tmp_tz = 0;
|
||||
flipper_format_write_float(fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &tmp_tz, 1);
|
||||
@@ -396,10 +397,10 @@ bool totp_config_file_load(PluginState* const plugin_state) {
|
||||
|
||||
if(!flipper_format_read_hex(
|
||||
fff_data_file,
|
||||
TOTP_CONFIG_KEY_BASE_IV,
|
||||
&plugin_state->crypto_settings.base_iv[0],
|
||||
CRYPTO_IV_LENGTH)) {
|
||||
FURI_LOG_D(LOGGING_TAG, "Missing base IV");
|
||||
TOTP_CONFIG_KEY_SALT,
|
||||
&plugin_state->crypto_settings.salt[0],
|
||||
CRYPTO_SALT_LENGTH)) {
|
||||
FURI_LOG_D(LOGGING_TAG, "Missing salt");
|
||||
}
|
||||
|
||||
if(!flipper_format_rewind(fff_data_file)) {
|
||||
@@ -529,9 +530,9 @@ bool totp_config_file_update_crypto_signatures(const PluginState* plugin_state)
|
||||
|
||||
if(!flipper_format_insert_or_update_hex(
|
||||
config_file,
|
||||
TOTP_CONFIG_KEY_BASE_IV,
|
||||
plugin_state->crypto_settings.base_iv,
|
||||
CRYPTO_IV_LENGTH)) {
|
||||
TOTP_CONFIG_KEY_SALT,
|
||||
&plugin_state->crypto_settings.salt[0],
|
||||
CRYPTO_SALT_LENGTH)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -592,7 +593,7 @@ bool totp_config_file_update_encryption(
|
||||
CryptoSettings old_crypto_settings = plugin_state->crypto_settings;
|
||||
|
||||
memset(&plugin_state->crypto_settings.iv[0], 0, CRYPTO_IV_LENGTH);
|
||||
memset(&plugin_state->crypto_settings.base_iv[0], 0, CRYPTO_IV_LENGTH);
|
||||
memset(&plugin_state->crypto_settings.salt[0], 0, CRYPTO_SALT_LENGTH);
|
||||
if(plugin_state->crypto_settings.crypto_verify_data != NULL) {
|
||||
free(plugin_state->crypto_settings.crypto_verify_data);
|
||||
plugin_state->crypto_settings.crypto_verify_data = NULL;
|
||||
@@ -724,4 +725,4 @@ bool totp_config_file_ensure_latest_encryption(
|
||||
|
||||
TokenInfoIteratorContext* totp_config_get_token_iterator_context(const PluginState* plugin_state) {
|
||||
return plugin_state->config_file_context->token_info_iterator_context;
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
#include <storage/storage.h>
|
||||
|
||||
#define CONFIG_FILE_DIRECTORY_PATH STORAGE_APP_DATA_PATH_PREFIX
|
||||
#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("apps_data/totp")
|
||||
#define CONFIG_FILE_HEADER "Flipper TOTP plugin config file"
|
||||
#define CONFIG_FILE_ACTUAL_VERSION (8)
|
||||
#define CONFIG_FILE_ACTUAL_VERSION (9)
|
||||
|
||||
#define TOTP_CONFIG_KEY_TIMEZONE "Timezone"
|
||||
#define TOTP_CONFIG_KEY_TOKEN_NAME "TokenName"
|
||||
@@ -14,7 +14,7 @@
|
||||
#define TOTP_CONFIG_KEY_TOKEN_DURATION "TokenDuration"
|
||||
#define TOTP_CONFIG_KEY_TOKEN_AUTOMATION_FEATURES "TokenAutomationFeatures"
|
||||
#define TOTP_CONFIG_KEY_CRYPTO_VERIFY "Crypto"
|
||||
#define TOTP_CONFIG_KEY_BASE_IV "BaseIV"
|
||||
#define TOTP_CONFIG_KEY_SALT "Salt"
|
||||
#define TOTP_CONFIG_KEY_PINSET "PinIsSet"
|
||||
#define TOTP_CONFIG_KEY_NOTIFICATION_METHOD "NotificationMethod"
|
||||
#define TOTP_CONFIG_KEY_AUTOMATION_METHOD "AutomationMethod"
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include "../../../types/automation_kb_layout.h"
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
|
||||
#define TOTP_OLD_CONFIG_KEY_BASE_IV "BaseIV"
|
||||
|
||||
bool totp_config_migrate_to_latest(
|
||||
FlipperFormat* fff_data_file,
|
||||
FlipperFormat* fff_backup_data_file) {
|
||||
@@ -40,8 +42,13 @@ bool totp_config_migrate_to_latest(
|
||||
|
||||
flipper_format_rewind(fff_backup_data_file);
|
||||
|
||||
if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_BASE_IV, temp_str)) {
|
||||
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_BASE_IV, temp_str);
|
||||
if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_SALT, temp_str)) {
|
||||
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_SALT, temp_str);
|
||||
} else if(
|
||||
flipper_format_rewind(fff_backup_data_file) &&
|
||||
flipper_format_read_string(
|
||||
fff_backup_data_file, TOTP_OLD_CONFIG_KEY_BASE_IV, temp_str)) {
|
||||
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_SALT, temp_str);
|
||||
}
|
||||
|
||||
flipper_format_rewind(fff_backup_data_file);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "../../types/crypto_settings.h"
|
||||
|
||||
#define CONFIG_FILE_PART_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf.part"
|
||||
#define STREAM_COPY_BUFFER_SIZE 128
|
||||
#define STREAM_COPY_BUFFER_SIZE (128)
|
||||
|
||||
struct TokenInfoIteratorContext {
|
||||
size_t total_count;
|
||||
@@ -547,4 +547,6 @@ void totp_token_info_iterator_attach_to_config_file(
|
||||
TokenInfoIteratorContext* context,
|
||||
FlipperFormat* config_file) {
|
||||
context->config_file = config_file;
|
||||
Stream* stream = flipper_format_get_raw_stream(context->config_file);
|
||||
stream_seek(stream, context->last_seek_offset, StreamOffsetFromStart);
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "polyfills.h"
|
||||
|
||||
#define CRYPTO_IV_LENGTH (16)
|
||||
#define CRYPTO_SALT_LENGTH (16)
|
||||
|
||||
// According to this explanation: https://github.com/flipperdevices/flipperzero-firmware/issues/2885#issuecomment-1646664666
|
||||
// disabling usage of any key which is "the same across all devices"
|
||||
#define ACCEPTABLE_CRYPTO_KEY_SLOT_START (12)
|
||||
#define ACCEPTABLE_CRYPTO_KEY_SLOT_END (100)
|
||||
#define ACCEPTABLE_CRYPTO_KEY_SLOT_START FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_START
|
||||
#define ACCEPTABLE_CRYPTO_KEY_SLOT_END FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_END
|
||||
|
||||
#define DEFAULT_CRYPTO_KEY_SLOT ACCEPTABLE_CRYPTO_KEY_SLOT_START
|
||||
#define CRYPTO_LATEST_VERSION (2)
|
||||
#define CRYPTO_LATEST_VERSION (3)
|
||||
@@ -1,8 +1,14 @@
|
||||
#include "crypto_facade.h"
|
||||
#include "../../config/app/config.h"
|
||||
#include <furi_hal_crypto.h>
|
||||
#include <furi/core/check.h>
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
|
||||
#include "crypto_v1.h"
|
||||
#endif
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
|
||||
#include "crypto_v2.h"
|
||||
#endif
|
||||
#include "crypto_v3.h"
|
||||
#include "constants.h"
|
||||
|
||||
bool totp_crypto_check_key_slot(uint8_t key_slot) {
|
||||
@@ -11,9 +17,9 @@ bool totp_crypto_check_key_slot(uint8_t key_slot) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return furi_hal_crypto_verify_key(key_slot) &&
|
||||
furi_hal_crypto_store_load_key(key_slot, empty_iv) &&
|
||||
furi_hal_crypto_store_unload_key(key_slot);
|
||||
return furi_hal_crypto_enclave_ensure_key(key_slot) &&
|
||||
furi_hal_crypto_enclave_load_key(key_slot, empty_iv) &&
|
||||
furi_hal_crypto_enclave_unload_key(key_slot);
|
||||
}
|
||||
|
||||
uint8_t* totp_crypto_encrypt(
|
||||
@@ -21,15 +27,24 @@ uint8_t* totp_crypto_encrypt(
|
||||
const size_t plain_data_length,
|
||||
const CryptoSettings* crypto_settings,
|
||||
size_t* encrypted_data_length) {
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
|
||||
if(crypto_settings->crypto_version == 1) {
|
||||
return totp_crypto_encrypt_v1(
|
||||
plain_data, plain_data_length, crypto_settings, encrypted_data_length);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
|
||||
if(crypto_settings->crypto_version == 2) {
|
||||
return totp_crypto_encrypt_v2(
|
||||
plain_data, plain_data_length, crypto_settings, encrypted_data_length);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(crypto_settings->crypto_version == 3) {
|
||||
return totp_crypto_encrypt_v3(
|
||||
plain_data, plain_data_length, crypto_settings, encrypted_data_length);
|
||||
}
|
||||
|
||||
furi_crash("Unsupported crypto version");
|
||||
}
|
||||
@@ -39,40 +54,65 @@ uint8_t* totp_crypto_decrypt(
|
||||
const size_t encrypted_data_length,
|
||||
const CryptoSettings* crypto_settings,
|
||||
size_t* decrypted_data_length) {
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
|
||||
if(crypto_settings->crypto_version == 1) {
|
||||
return totp_crypto_decrypt_v1(
|
||||
encrypted_data, encrypted_data_length, crypto_settings, decrypted_data_length);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
|
||||
if(crypto_settings->crypto_version == 2) {
|
||||
return totp_crypto_decrypt_v2(
|
||||
encrypted_data, encrypted_data_length, crypto_settings, decrypted_data_length);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(crypto_settings->crypto_version == 3) {
|
||||
return totp_crypto_decrypt_v3(
|
||||
encrypted_data, encrypted_data_length, crypto_settings, decrypted_data_length);
|
||||
}
|
||||
|
||||
furi_crash("Unsupported crypto version");
|
||||
}
|
||||
|
||||
CryptoSeedIVResult
|
||||
totp_crypto_seed_iv(CryptoSettings* crypto_settings, const uint8_t* pin, uint8_t pin_length) {
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
|
||||
if(crypto_settings->crypto_version == 1) {
|
||||
return totp_crypto_seed_iv_v1(crypto_settings, pin, pin_length);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
|
||||
if(crypto_settings->crypto_version == 2) {
|
||||
return totp_crypto_seed_iv_v2(crypto_settings, pin, pin_length);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(crypto_settings->crypto_version == 3) {
|
||||
return totp_crypto_seed_iv_v3(crypto_settings, pin, pin_length);
|
||||
}
|
||||
|
||||
furi_crash("Unsupported crypto version");
|
||||
}
|
||||
|
||||
bool totp_crypto_verify_key(const CryptoSettings* crypto_settings) {
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
|
||||
if(crypto_settings->crypto_version == 1) {
|
||||
return totp_crypto_verify_key_v1(crypto_settings);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
|
||||
if(crypto_settings->crypto_version == 2) {
|
||||
return totp_crypto_verify_key_v2(crypto_settings);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(crypto_settings->crypto_version == 3) {
|
||||
return totp_crypto_verify_key_v3(crypto_settings);
|
||||
}
|
||||
|
||||
furi_crash("Unsupported crypto version");
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "crypto_v1.h"
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
|
||||
#include <stdlib.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal_crypto.h>
|
||||
@@ -6,6 +7,7 @@
|
||||
#include <furi_hal_version.h>
|
||||
#include "../../types/common.h"
|
||||
#include "memset_s.h"
|
||||
#include "polyfills.h"
|
||||
|
||||
#define CRYPTO_KEY_SLOT (2)
|
||||
#define CRYPTO_VERIFY_KEY_LENGTH (16)
|
||||
@@ -32,9 +34,9 @@ uint8_t* totp_crypto_encrypt_v1(
|
||||
furi_check(encrypted_data != NULL);
|
||||
*encrypted_data_length = plain_data_aligned_length;
|
||||
|
||||
furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, crypto_settings->iv);
|
||||
furi_hal_crypto_enclave_load_key(CRYPTO_KEY_SLOT, crypto_settings->iv);
|
||||
furi_hal_crypto_encrypt(plain_data_aligned, encrypted_data, plain_data_aligned_length);
|
||||
furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
|
||||
furi_hal_crypto_enclave_unload_key(CRYPTO_KEY_SLOT);
|
||||
|
||||
memset_s(plain_data_aligned, plain_data_aligned_length, 0, plain_data_aligned_length);
|
||||
free(plain_data_aligned);
|
||||
@@ -43,9 +45,9 @@ uint8_t* totp_crypto_encrypt_v1(
|
||||
furi_check(encrypted_data != NULL);
|
||||
*encrypted_data_length = plain_data_length;
|
||||
|
||||
furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, crypto_settings->iv);
|
||||
furi_hal_crypto_enclave_load_key(CRYPTO_KEY_SLOT, crypto_settings->iv);
|
||||
furi_hal_crypto_encrypt(plain_data, encrypted_data, plain_data_length);
|
||||
furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
|
||||
furi_hal_crypto_enclave_unload_key(CRYPTO_KEY_SLOT);
|
||||
}
|
||||
|
||||
return encrypted_data;
|
||||
@@ -59,9 +61,9 @@ uint8_t* totp_crypto_decrypt_v1(
|
||||
*decrypted_data_length = encrypted_data_length;
|
||||
uint8_t* decrypted_data = malloc(*decrypted_data_length);
|
||||
furi_check(decrypted_data != NULL);
|
||||
furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, crypto_settings->iv);
|
||||
furi_hal_crypto_enclave_load_key(CRYPTO_KEY_SLOT, crypto_settings->iv);
|
||||
furi_hal_crypto_decrypt(encrypted_data, decrypted_data, encrypted_data_length);
|
||||
furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
|
||||
furi_hal_crypto_enclave_unload_key(CRYPTO_KEY_SLOT);
|
||||
return decrypted_data;
|
||||
}
|
||||
|
||||
@@ -72,10 +74,10 @@ CryptoSeedIVResult totp_crypto_seed_iv_v1(
|
||||
CryptoSeedIVResult result;
|
||||
if(crypto_settings->crypto_verify_data == NULL) {
|
||||
FURI_LOG_I(LOGGING_TAG, "Generating new IV");
|
||||
furi_hal_random_fill_buf(&crypto_settings->base_iv[0], TOTP_IV_SIZE);
|
||||
furi_hal_random_fill_buf(&crypto_settings->salt[0], CRYPTO_SALT_LENGTH);
|
||||
}
|
||||
|
||||
memcpy(&crypto_settings->iv[0], &crypto_settings->base_iv[0], TOTP_IV_SIZE);
|
||||
memcpy(&crypto_settings->iv[0], &crypto_settings->salt[0], TOTP_IV_SIZE);
|
||||
if(pin != NULL && pin_length > 0) {
|
||||
uint8_t max_i;
|
||||
if(pin_length > TOTP_IV_SIZE) {
|
||||
@@ -139,4 +141,5 @@ bool totp_crypto_verify_key_v1(const CryptoSettings* crypto_settings) {
|
||||
free(decrypted_key);
|
||||
|
||||
return key_valid;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../config/app/config.h"
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@@ -49,4 +51,5 @@ CryptoSeedIVResult
|
||||
* @param crypto_settings crypto settings
|
||||
* @return \c true if cryptographic information is valid; \c false otherwise
|
||||
*/
|
||||
bool totp_crypto_verify_key_v1(const CryptoSettings* crypto_settings);
|
||||
bool totp_crypto_verify_key_v1(const CryptoSettings* crypto_settings);
|
||||
#endif
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
#include "crypto_v2.h"
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
|
||||
#include <stdlib.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal_crypto.h>
|
||||
#include <furi_hal_random.h>
|
||||
#include <furi_hal_version.h>
|
||||
#include "../../types/common.h"
|
||||
#include "../hmac/hmac_sha512.h"
|
||||
#include "../../config/wolfssl/config.h"
|
||||
#include <wolfssl/wolfcrypt/hmac.h>
|
||||
#include "memset_s.h"
|
||||
#include "constants.h"
|
||||
#include "polyfills.h"
|
||||
|
||||
#define CRYPTO_ALIGNMENT_FACTOR (16)
|
||||
|
||||
@@ -46,14 +49,14 @@ uint8_t* totp_crypto_encrypt_v2(
|
||||
*encrypted_data_length = plain_data_aligned_length;
|
||||
|
||||
furi_check(
|
||||
furi_hal_crypto_store_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
|
||||
"Encryption failed: store_load_key");
|
||||
furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
|
||||
"Encryption failed: enclave_load_key");
|
||||
furi_check(
|
||||
furi_hal_crypto_encrypt(plain_data_aligned, encrypted_data, plain_data_aligned_length),
|
||||
"Encryption failed: encrypt");
|
||||
furi_check(
|
||||
furi_hal_crypto_store_unload_key(crypto_settings->crypto_key_slot),
|
||||
"Encryption failed: store_unload_key");
|
||||
furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
|
||||
"Encryption failed: enclave_unload_key");
|
||||
|
||||
memset_s(plain_data_aligned, plain_data_aligned_length, 0, plain_data_aligned_length);
|
||||
free(plain_data_aligned);
|
||||
@@ -63,13 +66,13 @@ uint8_t* totp_crypto_encrypt_v2(
|
||||
*encrypted_data_length = plain_data_length;
|
||||
|
||||
furi_check(
|
||||
furi_hal_crypto_store_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
|
||||
furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
|
||||
"Encryption failed: store_load_key");
|
||||
furi_check(
|
||||
furi_hal_crypto_encrypt(plain_data, encrypted_data, plain_data_length),
|
||||
"Encryption failed: encrypt");
|
||||
furi_check(
|
||||
furi_hal_crypto_store_unload_key(crypto_settings->crypto_key_slot),
|
||||
furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
|
||||
"Encryption failed: store_unload_key");
|
||||
}
|
||||
|
||||
@@ -85,14 +88,14 @@ uint8_t* totp_crypto_decrypt_v2(
|
||||
uint8_t* decrypted_data = malloc(*decrypted_data_length);
|
||||
furi_check(decrypted_data != NULL);
|
||||
furi_check(
|
||||
furi_hal_crypto_store_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
|
||||
"Decryption failed: store_load_key");
|
||||
furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
|
||||
"Decryption failed: enclave_load_key");
|
||||
furi_check(
|
||||
furi_hal_crypto_decrypt(encrypted_data, decrypted_data, encrypted_data_length),
|
||||
"Decryption failed: decrypt");
|
||||
furi_check(
|
||||
furi_hal_crypto_store_unload_key(crypto_settings->crypto_key_slot),
|
||||
"Decryption failed: store_unload_key");
|
||||
furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
|
||||
"Decryption failed: enclave_unload_key");
|
||||
return decrypted_data;
|
||||
}
|
||||
|
||||
@@ -102,12 +105,10 @@ CryptoSeedIVResult totp_crypto_seed_iv_v2(
|
||||
uint8_t pin_length) {
|
||||
CryptoSeedIVResult result;
|
||||
if(crypto_settings->crypto_verify_data == NULL) {
|
||||
FURI_LOG_I(LOGGING_TAG, "Generating new IV");
|
||||
furi_hal_random_fill_buf(&crypto_settings->base_iv[0], CRYPTO_IV_LENGTH);
|
||||
FURI_LOG_I(LOGGING_TAG, "Generating new salt");
|
||||
furi_hal_random_fill_buf(&crypto_settings->salt[0], CRYPTO_SALT_LENGTH);
|
||||
}
|
||||
|
||||
memcpy(&crypto_settings->iv[0], &crypto_settings->base_iv[0], CRYPTO_IV_LENGTH);
|
||||
|
||||
const uint8_t* device_uid = get_device_uid();
|
||||
uint8_t device_uid_length = get_device_uid_length();
|
||||
|
||||
@@ -125,16 +126,20 @@ CryptoSeedIVResult totp_crypto_seed_iv_v2(
|
||||
memcpy(hmac_key + device_uid_length, pin, pin_length);
|
||||
}
|
||||
|
||||
uint8_t hmac[HMAC_SHA512_RESULT_SIZE] = {0};
|
||||
int hmac_result_code = hmac_sha512(
|
||||
hmac_key, hmac_key_length, &crypto_settings->base_iv[0], CRYPTO_IV_LENGTH, &hmac[0]);
|
||||
uint8_t hmac[WC_SHA512_DIGEST_SIZE] = {0};
|
||||
|
||||
Hmac hmac_context;
|
||||
wc_HmacSetKey(&hmac_context, WC_SHA512, hmac_key, hmac_key_length);
|
||||
wc_HmacUpdate(&hmac_context, &crypto_settings->salt[0], CRYPTO_SALT_LENGTH);
|
||||
int hmac_result_code = wc_HmacFinal(&hmac_context, &hmac[0]);
|
||||
wc_HmacFree(&hmac_context);
|
||||
|
||||
memset_s(hmac_key, hmac_key_length, 0, hmac_key_length);
|
||||
free(hmac_key);
|
||||
|
||||
if(hmac_result_code == 0) {
|
||||
uint8_t offset =
|
||||
hmac[HMAC_SHA512_RESULT_SIZE - 1] % (HMAC_SHA512_RESULT_SIZE - CRYPTO_IV_LENGTH - 1);
|
||||
hmac[WC_SHA512_DIGEST_SIZE - 1] % (WC_SHA512_DIGEST_SIZE - CRYPTO_IV_LENGTH - 1);
|
||||
memcpy(&crypto_settings->iv[0], &hmac[offset], CRYPTO_IV_LENGTH);
|
||||
|
||||
result = CryptoSeedIVResultFlagSuccess;
|
||||
@@ -181,4 +186,5 @@ bool totp_crypto_verify_key_v2(const CryptoSettings* crypto_settings) {
|
||||
free(decrypted_key);
|
||||
|
||||
return key_valid;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../config/app/config.h"
|
||||
#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@@ -49,4 +51,5 @@ CryptoSeedIVResult
|
||||
* @param crypto_settings crypto settings
|
||||
* @return \c true if cryptographic information is valid; \c false otherwise
|
||||
*/
|
||||
bool totp_crypto_verify_key_v2(const CryptoSettings* crypto_settings);
|
||||
bool totp_crypto_verify_key_v2(const CryptoSettings* crypto_settings);
|
||||
#endif
|
||||
|
||||
195
applications/external/totp/services/crypto/crypto_v3.c
vendored
Normal file
195
applications/external/totp/services/crypto/crypto_v3.c
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
#include "crypto_v3.h"
|
||||
#include <stdlib.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal_crypto.h>
|
||||
#include <furi_hal_random.h>
|
||||
#include <furi_hal_version.h>
|
||||
#include "../../types/common.h"
|
||||
#include "../../config/wolfssl/config.h"
|
||||
#include <wolfssl/wolfcrypt/hmac.h>
|
||||
#include <wolfssl/wolfcrypt/pwdbased.h>
|
||||
#include "memset_s.h"
|
||||
#include "constants.h"
|
||||
#include "polyfills.h"
|
||||
|
||||
#define CRYPTO_ALIGNMENT_FACTOR (16)
|
||||
#define PBKDF2_ITERATIONS_COUNT (200)
|
||||
|
||||
static const uint8_t* get_device_uid() {
|
||||
return (const uint8_t*)UID64_BASE; //-V566
|
||||
}
|
||||
|
||||
static uint8_t get_device_uid_length() {
|
||||
return furi_hal_version_uid_size();
|
||||
}
|
||||
|
||||
static const uint8_t* get_crypto_verify_key() {
|
||||
return get_device_uid();
|
||||
}
|
||||
|
||||
static uint8_t get_crypto_verify_key_length() {
|
||||
return get_device_uid_length();
|
||||
}
|
||||
|
||||
uint8_t* totp_crypto_encrypt_v3(
|
||||
const uint8_t* plain_data,
|
||||
const size_t plain_data_length,
|
||||
const CryptoSettings* crypto_settings,
|
||||
size_t* encrypted_data_length) {
|
||||
uint8_t* encrypted_data;
|
||||
size_t remain = plain_data_length % CRYPTO_ALIGNMENT_FACTOR;
|
||||
if(remain) {
|
||||
size_t plain_data_aligned_length = plain_data_length - remain + CRYPTO_ALIGNMENT_FACTOR;
|
||||
uint8_t* plain_data_aligned = malloc(plain_data_aligned_length);
|
||||
furi_check(plain_data_aligned != NULL);
|
||||
memset(plain_data_aligned, 0, plain_data_aligned_length);
|
||||
memcpy(plain_data_aligned, plain_data, plain_data_length);
|
||||
|
||||
encrypted_data = malloc(plain_data_aligned_length);
|
||||
furi_check(encrypted_data != NULL);
|
||||
*encrypted_data_length = plain_data_aligned_length;
|
||||
|
||||
furi_check(
|
||||
furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
|
||||
"Encryption failed: enclave_load_key");
|
||||
furi_check(
|
||||
furi_hal_crypto_encrypt(plain_data_aligned, encrypted_data, plain_data_aligned_length),
|
||||
"Encryption failed: encrypt");
|
||||
furi_check(
|
||||
furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
|
||||
"Encryption failed: enclave_unload_key");
|
||||
|
||||
memset_s(plain_data_aligned, plain_data_aligned_length, 0, plain_data_aligned_length);
|
||||
free(plain_data_aligned);
|
||||
} else {
|
||||
encrypted_data = malloc(plain_data_length);
|
||||
furi_check(encrypted_data != NULL);
|
||||
*encrypted_data_length = plain_data_length;
|
||||
|
||||
furi_check(
|
||||
furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
|
||||
"Encryption failed: enclave_load_key");
|
||||
furi_check(
|
||||
furi_hal_crypto_encrypt(plain_data, encrypted_data, plain_data_length),
|
||||
"Encryption failed: encrypt");
|
||||
furi_check(
|
||||
furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
|
||||
"Encryption failed: enclave_unload_key");
|
||||
}
|
||||
|
||||
return encrypted_data;
|
||||
}
|
||||
|
||||
uint8_t* totp_crypto_decrypt_v3(
|
||||
const uint8_t* encrypted_data,
|
||||
const size_t encrypted_data_length,
|
||||
const CryptoSettings* crypto_settings,
|
||||
size_t* decrypted_data_length) {
|
||||
*decrypted_data_length = encrypted_data_length;
|
||||
uint8_t* decrypted_data = malloc(*decrypted_data_length);
|
||||
furi_check(decrypted_data != NULL);
|
||||
furi_check(
|
||||
furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
|
||||
"Decryption failed: enclave_load_key");
|
||||
furi_check(
|
||||
furi_hal_crypto_decrypt(encrypted_data, decrypted_data, encrypted_data_length),
|
||||
"Decryption failed: decrypt");
|
||||
furi_check(
|
||||
furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
|
||||
"Decryption failed: enclave_unload_key");
|
||||
return decrypted_data;
|
||||
}
|
||||
|
||||
CryptoSeedIVResult totp_crypto_seed_iv_v3(
|
||||
CryptoSettings* crypto_settings,
|
||||
const uint8_t* pin,
|
||||
uint8_t pin_length) {
|
||||
CryptoSeedIVResult result;
|
||||
if(crypto_settings->crypto_verify_data == NULL) {
|
||||
FURI_LOG_I(LOGGING_TAG, "Generating new salt");
|
||||
furi_hal_random_fill_buf(&crypto_settings->salt[0], CRYPTO_SALT_LENGTH);
|
||||
}
|
||||
|
||||
const uint8_t* device_uid = get_device_uid();
|
||||
uint8_t device_uid_length = get_device_uid_length();
|
||||
|
||||
uint8_t pbkdf_key_length = device_uid_length;
|
||||
if(pin != NULL && pin_length > 0) {
|
||||
pbkdf_key_length += pin_length;
|
||||
}
|
||||
|
||||
uint8_t* pbkdf_key = malloc(pbkdf_key_length);
|
||||
furi_check(pbkdf_key != NULL);
|
||||
|
||||
memcpy(pbkdf_key, device_uid, device_uid_length);
|
||||
|
||||
if(pin != NULL && pin_length > 0) {
|
||||
memcpy(pbkdf_key + device_uid_length, pin, pin_length);
|
||||
}
|
||||
|
||||
uint8_t pbkdf_output[WC_SHA512_DIGEST_SIZE] = {0};
|
||||
|
||||
int pbkdf_result_code = wc_PBKDF2(
|
||||
&pbkdf_output[0],
|
||||
pbkdf_key,
|
||||
pbkdf_key_length,
|
||||
&crypto_settings->salt[0],
|
||||
CRYPTO_SALT_LENGTH,
|
||||
PBKDF2_ITERATIONS_COUNT,
|
||||
WC_SHA512_DIGEST_SIZE,
|
||||
WC_SHA512);
|
||||
|
||||
memset_s(pbkdf_key, pbkdf_key_length, 0, pbkdf_key_length);
|
||||
free(pbkdf_key);
|
||||
|
||||
if(pbkdf_result_code == 0) {
|
||||
uint8_t offset = pbkdf_output[WC_SHA512_DIGEST_SIZE - 1] %
|
||||
(WC_SHA512_DIGEST_SIZE - CRYPTO_IV_LENGTH - 1);
|
||||
memcpy(&crypto_settings->iv[0], &pbkdf_output[offset], CRYPTO_IV_LENGTH);
|
||||
result = CryptoSeedIVResultFlagSuccess;
|
||||
if(crypto_settings->crypto_verify_data == NULL) {
|
||||
const uint8_t* crypto_vkey = get_crypto_verify_key();
|
||||
uint8_t crypto_vkey_length = get_crypto_verify_key_length();
|
||||
FURI_LOG_I(LOGGING_TAG, "Generating crypto verify data");
|
||||
crypto_settings->crypto_verify_data = malloc(crypto_vkey_length);
|
||||
furi_check(crypto_settings->crypto_verify_data != NULL);
|
||||
crypto_settings->crypto_verify_data_length = crypto_vkey_length;
|
||||
|
||||
crypto_settings->crypto_verify_data = totp_crypto_encrypt_v3(
|
||||
crypto_vkey,
|
||||
crypto_vkey_length,
|
||||
crypto_settings,
|
||||
&crypto_settings->crypto_verify_data_length);
|
||||
|
||||
crypto_settings->pin_required = pin != NULL && pin_length > 0;
|
||||
|
||||
result |= CryptoSeedIVResultFlagNewCryptoVerifyData;
|
||||
}
|
||||
} else {
|
||||
result = CryptoSeedIVResultFailed;
|
||||
}
|
||||
|
||||
memset_s(&pbkdf_output[0], WC_SHA512_DIGEST_SIZE, 0, WC_SHA512_DIGEST_SIZE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool totp_crypto_verify_key_v3(const CryptoSettings* crypto_settings) {
|
||||
size_t decrypted_key_length;
|
||||
uint8_t* decrypted_key = totp_crypto_decrypt_v3(
|
||||
crypto_settings->crypto_verify_data,
|
||||
crypto_settings->crypto_verify_data_length,
|
||||
crypto_settings,
|
||||
&decrypted_key_length);
|
||||
|
||||
const uint8_t* crypto_vkey = get_crypto_verify_key();
|
||||
uint8_t crypto_vkey_length = get_crypto_verify_key_length();
|
||||
bool key_valid = true;
|
||||
for(uint8_t i = 0; i < crypto_vkey_length && key_valid; i++) {
|
||||
if(decrypted_key[i] != crypto_vkey[i]) key_valid = false;
|
||||
}
|
||||
|
||||
free(decrypted_key);
|
||||
|
||||
return key_valid;
|
||||
}
|
||||
52
applications/external/totp/services/crypto/crypto_v3.h
vendored
Normal file
52
applications/external/totp/services/crypto/crypto_v3.h
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "../../types/crypto_settings.h"
|
||||
#include "common_types.h"
|
||||
|
||||
/**
|
||||
* @brief Encrypts plain data using built-in certificate and given initialization vector (IV)
|
||||
* @param plain_data plain data to be encrypted
|
||||
* @param plain_data_length plain data length
|
||||
* @param crypto_settings crypto settings
|
||||
* @param[out] encrypted_data_length encrypted data length
|
||||
* @return Encrypted data
|
||||
*/
|
||||
uint8_t* totp_crypto_encrypt_v3(
|
||||
const uint8_t* plain_data,
|
||||
const size_t plain_data_length,
|
||||
const CryptoSettings* crypto_settings,
|
||||
size_t* encrypted_data_length);
|
||||
|
||||
/**
|
||||
* @brief Decrypts encrypted data using built-in certificate and given initialization vector (IV)
|
||||
* @param encrypted_data encrypted data to be decrypted
|
||||
* @param encrypted_data_length encrypted data length
|
||||
* @param crypto_settings crypto settings
|
||||
* @param[out] decrypted_data_length decrypted data length
|
||||
* @return Decrypted data
|
||||
*/
|
||||
uint8_t* totp_crypto_decrypt_v3(
|
||||
const uint8_t* encrypted_data,
|
||||
const size_t encrypted_data_length,
|
||||
const CryptoSettings* crypto_settings,
|
||||
size_t* decrypted_data_length);
|
||||
|
||||
/**
|
||||
* @brief Seed initialization vector (IV) using user's PIN
|
||||
* @param crypto_settings crypto settings
|
||||
* @param pin user's PIN
|
||||
* @param pin_length user's PIN length
|
||||
* @return Results of seeding IV
|
||||
*/
|
||||
CryptoSeedIVResult
|
||||
totp_crypto_seed_iv_v3(CryptoSettings* crypto_settings, const uint8_t* pin, uint8_t pin_length);
|
||||
|
||||
/**
|
||||
* @brief Verifies whether cryptographic information (certificate + IV) is valid and can be used for encryption and decryption
|
||||
* @param crypto_settings crypto settings
|
||||
* @return \c true if cryptographic information is valid; \c false otherwise
|
||||
*/
|
||||
bool totp_crypto_verify_key_v3(const CryptoSettings* crypto_settings);
|
||||
14
applications/external/totp/services/crypto/polyfills.h
vendored
Normal file
14
applications/external/totp/services/crypto/polyfills.h
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <furi_hal_crypto.h>
|
||||
|
||||
#ifndef FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_START
|
||||
|
||||
// FW Crypto API is outdated, let's polyfill it
|
||||
#define FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_START (12u)
|
||||
#define FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_END (100u)
|
||||
#define furi_hal_crypto_enclave_ensure_key furi_hal_crypto_verify_key
|
||||
#define furi_hal_crypto_enclave_load_key furi_hal_crypto_store_load_key
|
||||
#define furi_hal_crypto_enclave_unload_key furi_hal_crypto_store_unload_key
|
||||
|
||||
#endif
|
||||
@@ -1,12 +0,0 @@
|
||||
#include "byteswap.h"
|
||||
|
||||
uint32_t swap_uint32(uint32_t val) {
|
||||
val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF);
|
||||
return (val << 16) | (val >> 16);
|
||||
}
|
||||
|
||||
uint64_t swap_uint64(uint64_t val) {
|
||||
val = ((val << 8) & 0xFF00FF00FF00FF00ULL) | ((val >> 8) & 0x00FF00FF00FF00FFULL);
|
||||
val = ((val << 16) & 0xFFFF0000FFFF0000ULL) | ((val >> 16) & 0x0000FFFF0000FFFFULL);
|
||||
return (val << 32) | (val >> 32);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Swap bytes in 32-bit value
|
||||
* @param val value to swap bytes in
|
||||
* @return Value with bytes swapped
|
||||
*/
|
||||
uint32_t swap_uint32(uint32_t val);
|
||||
|
||||
/**
|
||||
* @brief Swap bytes in 64-bit value
|
||||
* @param val value to swap bytes in
|
||||
* @return Value with bytes swapped
|
||||
*/
|
||||
uint64_t swap_uint64(uint64_t val);
|
||||
@@ -1,59 +0,0 @@
|
||||
#include <string.h>
|
||||
#include "memxor.h"
|
||||
|
||||
#define IPAD 0x36
|
||||
#define OPAD 0x5c
|
||||
|
||||
/* Concatenate two preprocessor tokens. */
|
||||
#define _GLHMAC_CONCAT_(prefix, suffix) prefix##suffix
|
||||
#define _GLHMAC_CONCAT(prefix, suffix) _GLHMAC_CONCAT_(prefix, suffix)
|
||||
|
||||
#define HMAC_ALG _GLHMAC_CONCAT(sha, GL_HMAC_NAME)
|
||||
|
||||
#define GL_HMAC_CTX _GLHMAC_CONCAT(HMAC_ALG, _ctx)
|
||||
#define GL_HMAC_FN _GLHMAC_CONCAT(hmac_, HMAC_ALG)
|
||||
#define GL_HMAC_FN_INIT _GLHMAC_CONCAT(HMAC_ALG, _init_ctx)
|
||||
#define GL_HMAC_FN_BLOC _GLHMAC_CONCAT(HMAC_ALG, _process_block)
|
||||
#define GL_HMAC_FN_PROC _GLHMAC_CONCAT(HMAC_ALG, _process_bytes)
|
||||
#define GL_HMAC_FN_FINI _GLHMAC_CONCAT(HMAC_ALG, _finish_ctx)
|
||||
|
||||
static void
|
||||
hmac_hash(const void* key, size_t keylen, const void* in, size_t inlen, int pad, void* resbuf) {
|
||||
struct GL_HMAC_CTX hmac_ctx;
|
||||
char block[GL_HMAC_BLOCKSIZE];
|
||||
|
||||
memset(block, pad, sizeof block);
|
||||
memxor(block, key, keylen);
|
||||
|
||||
GL_HMAC_FN_INIT(&hmac_ctx);
|
||||
GL_HMAC_FN_BLOC(block, sizeof block, &hmac_ctx);
|
||||
GL_HMAC_FN_PROC(in, inlen, &hmac_ctx);
|
||||
GL_HMAC_FN_FINI(&hmac_ctx, resbuf);
|
||||
}
|
||||
|
||||
int GL_HMAC_FN(const void* key, size_t keylen, const void* in, size_t inlen, void* resbuf) {
|
||||
char optkeybuf[GL_HMAC_HASHSIZE];
|
||||
char innerhash[GL_HMAC_HASHSIZE];
|
||||
|
||||
/* Ensure key size is <= block size. */
|
||||
if(keylen > GL_HMAC_BLOCKSIZE) {
|
||||
struct GL_HMAC_CTX keyhash;
|
||||
|
||||
GL_HMAC_FN_INIT(&keyhash);
|
||||
GL_HMAC_FN_PROC(key, keylen, &keyhash);
|
||||
GL_HMAC_FN_FINI(&keyhash, optkeybuf);
|
||||
|
||||
key = optkeybuf;
|
||||
/* zero padding of the key to the block size
|
||||
is implicit in the memxor. */
|
||||
keylen = sizeof optkeybuf;
|
||||
}
|
||||
|
||||
/* Compute INNERHASH from KEY and IN. */
|
||||
hmac_hash(key, keylen, in, inlen, IPAD, innerhash);
|
||||
|
||||
/* Compute result from KEY and INNERHASH. */
|
||||
hmac_hash(key, keylen, innerhash, sizeof innerhash, OPAD, resbuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/* hmac-sha1.c -- hashed message authentication codes
|
||||
Copyright (C) 2018-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "hmac_sha1.h"
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
#define GL_HMAC_NAME 1
|
||||
#define GL_HMAC_BLOCKSIZE 64
|
||||
#define GL_HMAC_HASHSIZE 20
|
||||
#include "hmac_common.h"
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define HMAC_SHA1_RESULT_SIZE 20
|
||||
|
||||
/* Compute Hashed Message Authentication Code with SHA-1, over BUFFER
|
||||
data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the
|
||||
output to pre-allocated 20 byte minimum RESBUF buffer. Return 0 on
|
||||
success. */
|
||||
int hmac_sha1(const void* key, size_t keylen, const void* in, size_t inlen, void* restrict resbuf);
|
||||
@@ -1,24 +0,0 @@
|
||||
/* hmac-sha256.c -- hashed message authentication codes
|
||||
Copyright (C) 2018-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "hmac_sha256.h"
|
||||
#include "sha256.h"
|
||||
|
||||
#define GL_HMAC_NAME 256
|
||||
#define GL_HMAC_BLOCKSIZE 64
|
||||
#define GL_HMAC_HASHSIZE 32
|
||||
|
||||
#include "hmac_common.h"
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define HMAC_SHA256_RESULT_SIZE 32
|
||||
|
||||
/* Compute Hashed Message Authentication Code with SHA-256, over BUFFER
|
||||
data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the
|
||||
output to pre-allocated 32 byte minimum RESBUF buffer. Return 0 on
|
||||
success. */
|
||||
int hmac_sha256(const void* key, size_t keylen, const void* in, size_t inlen, void* restrict resbuf);
|
||||
@@ -1,24 +0,0 @@
|
||||
/* hmac-sha512.c -- hashed message authentication codes
|
||||
Copyright (C) 2018-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "hmac_sha512.h"
|
||||
|
||||
#include "sha512.h"
|
||||
|
||||
#define GL_HMAC_NAME 512
|
||||
#define GL_HMAC_BLOCKSIZE 128
|
||||
#define GL_HMAC_HASHSIZE 64
|
||||
#include "hmac_common.h"
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define HMAC_SHA512_RESULT_SIZE 64
|
||||
|
||||
/* Compute Hashed Message Authentication Code with SHA-512, over BUFFER
|
||||
data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the
|
||||
output to pre-allocated 64 byte minimum RESBUF buffer. Return 0 on
|
||||
success. */
|
||||
int hmac_sha512(const void* key, size_t keylen, const void* in, size_t inlen, void* restrict resbuf);
|
||||
@@ -1,30 +0,0 @@
|
||||
/* memxor.c -- perform binary exclusive OR operation of two memory blocks.
|
||||
Copyright (C) 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* Written by Simon Josefsson. The interface was inspired by memxor
|
||||
in Niels Möller's Nettle. */
|
||||
|
||||
#include "memxor.h"
|
||||
|
||||
void* memxor(void* /*restrict*/ dest, const void* /*restrict*/ src, size_t n) {
|
||||
char const* s = (char const*)src;
|
||||
char* d = (char*)dest;
|
||||
|
||||
for(; n > 0; n--) *d++ ^= *s++;
|
||||
|
||||
return dest;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/* memxor.h -- perform binary exclusive OR operation on memory blocks.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* Written by Simon Josefsson. The interface was inspired by memxor
|
||||
in Niels Möller's Nettle. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* Compute binary exclusive OR of memory areas DEST and SRC, putting
|
||||
the result in DEST, of length N bytes. Returns a pointer to
|
||||
DEST. */
|
||||
void* memxor(void* /*restrict*/ dest, const void* /*restrict*/ src, size_t n);
|
||||
251
applications/external/totp/services/hmac/sha1.c
vendored
251
applications/external/totp/services/hmac/sha1.c
vendored
@@ -1,251 +0,0 @@
|
||||
/* sha1.c - Functions to compute SHA1 message digest of files or
|
||||
memory blocks according to the NIST specification FIPS-180-1.
|
||||
|
||||
Copyright (C) 2000-2001, 2003-2006, 2008-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Scott G. Miller
|
||||
Credits:
|
||||
Robert Klep <robert@ilse.nl> -- Expansion function fix
|
||||
*/
|
||||
|
||||
/* Specification. */
|
||||
#include "sha1.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sha_pad_buffer.h"
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define SWAP(n) (n)
|
||||
#else
|
||||
#include "byteswap.h"
|
||||
#define SWAP(n) swap_uint32(n)
|
||||
#endif
|
||||
|
||||
/* Take a pointer to a 160 bit block of data (five 32 bit ints) and
|
||||
initialize it to the start constants of the SHA1 algorithm. This
|
||||
must be called before using hash in the call to sha1_hash. */
|
||||
void sha1_init_ctx(struct sha1_ctx* ctx) {
|
||||
ctx->A = 0x67452301;
|
||||
ctx->B = 0xefcdab89;
|
||||
ctx->C = 0x98badcfe;
|
||||
ctx->D = 0x10325476;
|
||||
ctx->E = 0xc3d2e1f0;
|
||||
|
||||
ctx->total[0] = ctx->total[1] = 0;
|
||||
ctx->buflen = 0;
|
||||
}
|
||||
|
||||
/* Copy the 4 byte value from v into the memory location pointed to by *cp,
|
||||
If your architecture allows unaligned access this is equivalent to
|
||||
* (uint32_t *) cp = v */
|
||||
static void set_uint32(char* cp, uint32_t v) {
|
||||
memcpy(cp, &v, sizeof v);
|
||||
}
|
||||
|
||||
/* Put result from CTX in first 20 bytes following RESBUF. The result
|
||||
must be in little endian byte order. */
|
||||
void* sha1_read_ctx(const struct sha1_ctx* ctx, void* resbuf) {
|
||||
char* r = resbuf;
|
||||
set_uint32(r + 0 * sizeof ctx->A, SWAP(ctx->A));
|
||||
set_uint32(r + 1 * sizeof ctx->B, SWAP(ctx->B));
|
||||
set_uint32(r + 2 * sizeof ctx->C, SWAP(ctx->C));
|
||||
set_uint32(r + 3 * sizeof ctx->D, SWAP(ctx->D));
|
||||
set_uint32(r + 4 * sizeof ctx->E, SWAP(ctx->E));
|
||||
|
||||
return resbuf;
|
||||
}
|
||||
|
||||
/* Process the remaining bytes in the internal buffer and the usual
|
||||
prolog according to the standard and write the result to RESBUF. */
|
||||
void* sha1_finish_ctx(struct sha1_ctx* ctx, void* resbuf) {
|
||||
/* Take yet unprocessed bytes into account. */
|
||||
uint32_t bytes = ctx->buflen;
|
||||
size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
|
||||
|
||||
/* Now count remaining bytes. */
|
||||
ctx->total[0] += bytes;
|
||||
if(ctx->total[0] < bytes) ++ctx->total[1];
|
||||
|
||||
/* Put the 64-bit file length in *bits* at the end of the buffer. */
|
||||
ctx->buffer[size - 2] = SWAP((ctx->total[1] << 3) | (ctx->total[0] >> 29));
|
||||
ctx->buffer[size - 1] = SWAP(ctx->total[0] << 3);
|
||||
|
||||
sha_pad_buffer(&((uint8_t*)ctx->buffer)[bytes], (size - 2) * 4 - bytes);
|
||||
|
||||
/* Process last bytes. */
|
||||
sha1_process_block(ctx->buffer, size * 4, ctx);
|
||||
|
||||
return sha1_read_ctx(ctx, resbuf);
|
||||
}
|
||||
|
||||
/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The
|
||||
result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest. */
|
||||
void* sha1_buffer(const char* buffer, size_t len, void* resblock) {
|
||||
struct sha1_ctx ctx;
|
||||
|
||||
/* Initialize the computation context. */
|
||||
sha1_init_ctx(&ctx);
|
||||
|
||||
/* Process whole buffer but last len % 64 bytes. */
|
||||
sha1_process_bytes(buffer, len, &ctx);
|
||||
|
||||
/* Put result in desired memory area. */
|
||||
return sha1_finish_ctx(&ctx, resblock);
|
||||
}
|
||||
|
||||
void sha1_process_bytes(const void* buffer, size_t len, struct sha1_ctx* ctx) {
|
||||
/* When we already have some bits in our internal buffer concatenate
|
||||
both inputs first. */
|
||||
if(ctx->buflen != 0) {
|
||||
size_t left_over = ctx->buflen;
|
||||
size_t add = 128 - left_over > len ? len : 128 - left_over;
|
||||
|
||||
memcpy(&((char*)ctx->buffer)[left_over], buffer, add);
|
||||
ctx->buflen += add;
|
||||
|
||||
if(ctx->buflen > 64) {
|
||||
sha1_process_block(ctx->buffer, ctx->buflen & ~63, ctx);
|
||||
|
||||
ctx->buflen &= 63;
|
||||
/* The regions in the following copy operation cannot overlap,
|
||||
because ctx->buflen < 64 ≤ (left_over + add) & ~63. */
|
||||
memcpy(ctx->buffer, &((char*)ctx->buffer)[(left_over + add) & ~63], ctx->buflen);
|
||||
}
|
||||
|
||||
buffer = (const char*)buffer + add;
|
||||
len -= add;
|
||||
}
|
||||
|
||||
/* Process available complete blocks. */
|
||||
if(len >= 64) {
|
||||
#if !(_STRING_ARCH_unaligned || _STRING_INLINE_unaligned)
|
||||
#define UNALIGNED_P(p) ((uintptr_t)(p) % sizeof(uint32_t) != 0)
|
||||
if(UNALIGNED_P(buffer))
|
||||
while(len > 64) {
|
||||
sha1_process_block(memcpy(ctx->buffer, buffer, 64), 64, ctx); //-V1086
|
||||
buffer = (const char*)buffer + 64;
|
||||
len -= 64;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
sha1_process_block(buffer, len & ~63, ctx);
|
||||
buffer = (const char*)buffer + (len & ~63);
|
||||
len &= 63;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move remaining bytes in internal buffer. */
|
||||
if(len > 0) {
|
||||
size_t left_over = ctx->buflen;
|
||||
|
||||
memcpy(&((char*)ctx->buffer)[left_over], buffer, len);
|
||||
left_over += len;
|
||||
if(left_over >= 64) {
|
||||
sha1_process_block(ctx->buffer, 64, ctx);
|
||||
left_over -= 64;
|
||||
/* The regions in the following copy operation cannot overlap,
|
||||
because left_over ≤ 64. */
|
||||
memcpy(ctx->buffer, &ctx->buffer[16], left_over);
|
||||
}
|
||||
ctx->buflen = left_over;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- Code below is the primary difference between md5.c and sha1.c --- */
|
||||
|
||||
/* SHA1 round constants */
|
||||
static const int sha1_round_constants[4] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6};
|
||||
|
||||
/* Round functions. Note that F2 is the same as F4. */
|
||||
#define F1(B, C, D) (D ^ (B & (C ^ D)))
|
||||
#define F2_4(B, C, D) (B ^ C ^ D)
|
||||
#define F3(B, C, D) ((B & C) | (D & (B | C)))
|
||||
#define FN(I, B, C, D) (I == 0 ? F1(B, C, D) : (I == 2 ? F3(B, C, D) : F2_4(B, C, D)))
|
||||
|
||||
/* Process LEN bytes of BUFFER, accumulating context into CTX.
|
||||
It is assumed that LEN % 64 == 0.
|
||||
Most of this code comes from GnuPG's cipher/sha1.c. */
|
||||
|
||||
void sha1_process_block(const void* buffer, size_t len, struct sha1_ctx* ctx) {
|
||||
const uint32_t* words = buffer;
|
||||
size_t nwords = len / sizeof(uint32_t);
|
||||
const uint32_t* endp = words + nwords;
|
||||
uint32_t x[16];
|
||||
uint32_t a = ctx->A;
|
||||
uint32_t b = ctx->B;
|
||||
uint32_t c = ctx->C;
|
||||
uint32_t d = ctx->D;
|
||||
uint32_t e = ctx->E;
|
||||
uint32_t lolen = len;
|
||||
|
||||
/* First increment the byte count. RFC 1321 specifies the possible
|
||||
length of the file up to 2^64 bits. Here we only compute the
|
||||
number of bytes. Do a double word increment. */
|
||||
ctx->total[0] += lolen;
|
||||
ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen);
|
||||
|
||||
#define rol(x, n) (((x) << (n)) | ((uint32_t)(x) >> (32 - (n))))
|
||||
|
||||
#define M(I) \
|
||||
(tm = x[I & 0x0f] ^ x[(I - 14) & 0x0f] ^ x[(I - 8) & 0x0f] ^ x[(I - 3) & 0x0f], \
|
||||
(x[I & 0x0f] = rol(tm, 1)))
|
||||
|
||||
#define R(A, B, C, D, E, F, K, M, KI) \
|
||||
do { \
|
||||
E += rol(A, 5) + F(KI, B, C, D) + K + M; \
|
||||
B = rol(B, 30); \
|
||||
} while(0)
|
||||
|
||||
while(words < endp) {
|
||||
uint32_t tm;
|
||||
int t;
|
||||
for(t = 0; t < 16; t++) {
|
||||
x[t] = SWAP(*words);
|
||||
words++;
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < 80; i++) {
|
||||
uint32_t m = i < 16 ? x[i] : M(i);
|
||||
uint8_t ki = i / 20;
|
||||
int k_const = sha1_round_constants[ki];
|
||||
R(a, b, c, d, e, FN, k_const, m, ki);
|
||||
uint32_t tt = a;
|
||||
a = e;
|
||||
e = d;
|
||||
d = c;
|
||||
c = b;
|
||||
b = tt;
|
||||
}
|
||||
|
||||
a = ctx->A += a;
|
||||
b = ctx->B += b;
|
||||
c = ctx->C += c;
|
||||
d = ctx->D += d;
|
||||
e = ctx->E += e;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Hey Emacs!
|
||||
* Local Variables:
|
||||
* coding: utf-8
|
||||
* End:
|
||||
*/
|
||||
84
applications/external/totp/services/hmac/sha1.h
vendored
84
applications/external/totp/services/hmac/sha1.h
vendored
@@ -1,84 +0,0 @@
|
||||
/* Declarations of functions and data types used for SHA1 sum
|
||||
library functions.
|
||||
Copyright (C) 2000-2001, 2003, 2005-2006, 2008-2022 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
/* Structure to save state of computation between the single steps. */
|
||||
struct sha1_ctx {
|
||||
uint32_t A;
|
||||
uint32_t B;
|
||||
uint32_t C;
|
||||
uint32_t D;
|
||||
uint32_t E;
|
||||
|
||||
uint32_t total[2];
|
||||
uint32_t buflen; /* ≥ 0, ≤ 128 */
|
||||
uint32_t buffer[32]; /* 128 bytes; the first buflen bytes are in use */
|
||||
};
|
||||
|
||||
/* Initialize structure containing state of computation. */
|
||||
extern void sha1_init_ctx(struct sha1_ctx* ctx);
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
It is necessary that LEN is a multiple of 64!!! */
|
||||
extern void sha1_process_block(const void* buffer, size_t len, struct sha1_ctx* ctx);
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
It is NOT required that LEN is a multiple of 64. */
|
||||
extern void sha1_process_bytes(const void* buffer, size_t len, struct sha1_ctx* ctx);
|
||||
|
||||
/* Process the remaining bytes in the buffer and put result from CTX
|
||||
in first 20 bytes following RESBUF. The result is always in little
|
||||
endian byte order, so that a byte-wise output yields to the wanted
|
||||
ASCII representation of the message digest. */
|
||||
extern void* sha1_finish_ctx(struct sha1_ctx* ctx, void* restrict resbuf);
|
||||
|
||||
/* Put result from CTX in first 20 bytes following RESBUF. The result is
|
||||
always in little endian byte order, so that a byte-wise output yields
|
||||
to the wanted ASCII representation of the message digest. */
|
||||
extern void* sha1_read_ctx(const struct sha1_ctx* ctx, void* restrict resbuf);
|
||||
|
||||
/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The
|
||||
result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest. */
|
||||
extern void* sha1_buffer(const char* buffer, size_t len, void* restrict resblock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hey Emacs!
|
||||
* Local Variables:
|
||||
* coding: utf-8
|
||||
* End:
|
||||
*/
|
||||
283
applications/external/totp/services/hmac/sha256.c
vendored
283
applications/external/totp/services/hmac/sha256.c
vendored
@@ -1,283 +0,0 @@
|
||||
/* sha256.c - Functions to compute SHA256 message digest of files or
|
||||
memory blocks according to the NIST specification FIPS-180-2.
|
||||
|
||||
Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by David Madore, considerably copypasting from
|
||||
Scott G. Miller's sha1.c
|
||||
*/
|
||||
|
||||
/* Specification. */
|
||||
#include "sha256.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "sha_pad_buffer.h"
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define SWAP(n) (n)
|
||||
#else
|
||||
#include "byteswap.h"
|
||||
#define SWAP(n) swap_uint32(n)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Takes a pointer to a 256 bit block of data (eight 32 bit ints) and
|
||||
initializes it to the start constants of the SHA256 algorithm. This
|
||||
must be called before using hash in the call to sha256_hash
|
||||
*/
|
||||
void sha256_init_ctx(struct sha256_ctx* ctx) {
|
||||
ctx->state[0] = 0x6a09e667UL;
|
||||
ctx->state[1] = 0xbb67ae85UL;
|
||||
ctx->state[2] = 0x3c6ef372UL;
|
||||
ctx->state[3] = 0xa54ff53aUL;
|
||||
ctx->state[4] = 0x510e527fUL;
|
||||
ctx->state[5] = 0x9b05688cUL;
|
||||
ctx->state[6] = 0x1f83d9abUL;
|
||||
ctx->state[7] = 0x5be0cd19UL;
|
||||
|
||||
ctx->total[0] = ctx->total[1] = 0;
|
||||
ctx->buflen = 0;
|
||||
}
|
||||
|
||||
/* Copy the value from v into the memory location pointed to by *CP,
|
||||
If your architecture allows unaligned access, this is equivalent to
|
||||
* (__typeof__ (v) *) cp = v */
|
||||
static void set_uint32(char* cp, uint32_t v) {
|
||||
memcpy(cp, &v, sizeof v);
|
||||
}
|
||||
|
||||
/* Put result from CTX in first 32 bytes following RESBUF.
|
||||
The result must be in little endian byte order. */
|
||||
void* sha256_read_ctx(const struct sha256_ctx* ctx, void* resbuf) {
|
||||
int i;
|
||||
char* r = resbuf;
|
||||
|
||||
for(i = 0; i < 8; i++) set_uint32(r + i * sizeof ctx->state[0], SWAP(ctx->state[i]));
|
||||
|
||||
return resbuf;
|
||||
}
|
||||
|
||||
/* Process the remaining bytes in the internal buffer and the usual
|
||||
prolog according to the standard and write the result to RESBUF. */
|
||||
static void sha256_conclude_ctx(struct sha256_ctx* ctx) {
|
||||
/* Take yet unprocessed bytes into account. */
|
||||
size_t bytes = ctx->buflen;
|
||||
size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
|
||||
|
||||
/* Now count remaining bytes. */
|
||||
ctx->total[0] += bytes;
|
||||
if(ctx->total[0] < bytes) ++ctx->total[1];
|
||||
|
||||
/* Put the 64-bit file length in *bits* at the end of the buffer.
|
||||
Use set_uint32 rather than a simple assignment, to avoid risk of
|
||||
unaligned access. */
|
||||
set_uint32((char*)&ctx->buffer[size - 2], SWAP((ctx->total[1] << 3) | (ctx->total[0] >> 29)));
|
||||
set_uint32((char*)&ctx->buffer[size - 1], SWAP(ctx->total[0] << 3));
|
||||
|
||||
sha_pad_buffer(&((uint8_t*)ctx->buffer)[bytes], (size - 2) * 4 - bytes);
|
||||
|
||||
/* Process last bytes. */
|
||||
sha256_process_block(ctx->buffer, size * 4, ctx);
|
||||
}
|
||||
|
||||
void* sha256_finish_ctx(struct sha256_ctx* ctx, void* resbuf) {
|
||||
sha256_conclude_ctx(ctx);
|
||||
return sha256_read_ctx(ctx, resbuf);
|
||||
}
|
||||
|
||||
/* Compute SHA256 message digest for LEN bytes beginning at BUFFER. The
|
||||
result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest. */
|
||||
void* sha256_buffer(const char* buffer, size_t len, void* resblock) {
|
||||
struct sha256_ctx ctx;
|
||||
|
||||
/* Initialize the computation context. */
|
||||
sha256_init_ctx(&ctx);
|
||||
|
||||
/* Process whole buffer but last len % 64 bytes. */
|
||||
sha256_process_bytes(buffer, len, &ctx);
|
||||
|
||||
/* Put result in desired memory area. */
|
||||
return sha256_finish_ctx(&ctx, resblock);
|
||||
}
|
||||
|
||||
void sha256_process_bytes(const void* buffer, size_t len, struct sha256_ctx* ctx) {
|
||||
/* When we already have some bits in our internal buffer concatenate
|
||||
both inputs first. */
|
||||
if(ctx->buflen != 0) {
|
||||
size_t left_over = ctx->buflen;
|
||||
size_t add = 128 - left_over > len ? len : 128 - left_over;
|
||||
|
||||
memcpy(&((char*)ctx->buffer)[left_over], buffer, add);
|
||||
ctx->buflen += add;
|
||||
|
||||
if(ctx->buflen > 64) {
|
||||
sha256_process_block(ctx->buffer, ctx->buflen & ~63, ctx);
|
||||
|
||||
ctx->buflen &= 63;
|
||||
/* The regions in the following copy operation cannot overlap,
|
||||
because ctx->buflen < 64 ≤ (left_over + add) & ~63. */
|
||||
memcpy(ctx->buffer, &((char*)ctx->buffer)[(left_over + add) & ~63], ctx->buflen);
|
||||
}
|
||||
|
||||
buffer = (const char*)buffer + add;
|
||||
len -= add;
|
||||
}
|
||||
|
||||
/* Process available complete blocks. */
|
||||
if(len >= 64) {
|
||||
#if !(_STRING_ARCH_unaligned || _STRING_INLINE_unaligned)
|
||||
#define UNALIGNED_P(p) ((uintptr_t)(p) % sizeof(uint32_t) != 0)
|
||||
if(UNALIGNED_P(buffer))
|
||||
while(len > 64) {
|
||||
sha256_process_block(memcpy(ctx->buffer, buffer, 64), 64, ctx); //-V1086
|
||||
buffer = (const char*)buffer + 64;
|
||||
len -= 64;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
sha256_process_block(buffer, len & ~63, ctx);
|
||||
buffer = (const char*)buffer + (len & ~63);
|
||||
len &= 63;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move remaining bytes in internal buffer. */
|
||||
if(len > 0) {
|
||||
size_t left_over = ctx->buflen;
|
||||
|
||||
memcpy(&((char*)ctx->buffer)[left_over], buffer, len);
|
||||
left_over += len;
|
||||
if(left_over >= 64) {
|
||||
sha256_process_block(ctx->buffer, 64, ctx);
|
||||
left_over -= 64;
|
||||
/* The regions in the following copy operation cannot overlap,
|
||||
because left_over ≤ 64. */
|
||||
memcpy(ctx->buffer, &ctx->buffer[16], left_over);
|
||||
}
|
||||
ctx->buflen = left_over;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- Code below is the primary difference between sha1.c and sha256.c --- */
|
||||
|
||||
/* SHA256 round constants */
|
||||
#define K(I) sha256_round_constants[I]
|
||||
static const uint32_t sha256_round_constants[64] = {
|
||||
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL,
|
||||
0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
|
||||
0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL,
|
||||
0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
|
||||
0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
|
||||
0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
|
||||
0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 0xa2bfe8a1UL, 0xa81a664bUL,
|
||||
0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
|
||||
0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL,
|
||||
0x5b9cca4fUL, 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
|
||||
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL,
|
||||
};
|
||||
|
||||
/* Round functions. */
|
||||
#define F2(A, B, C) ((A & B) | (C & (A | B)))
|
||||
#define F1(E, F, G) (G ^ (E & (F ^ G)))
|
||||
|
||||
/* Process LEN bytes of BUFFER, accumulating context into CTX.
|
||||
It is assumed that LEN % 64 == 0.
|
||||
Most of this code comes from GnuPG's cipher/sha1.c. */
|
||||
|
||||
void sha256_process_block(const void* buffer, size_t len, struct sha256_ctx* ctx) {
|
||||
const uint32_t* words = buffer;
|
||||
size_t nwords = len / sizeof(uint32_t);
|
||||
const uint32_t* endp = words + nwords;
|
||||
uint32_t x[16];
|
||||
uint32_t a = ctx->state[0];
|
||||
uint32_t b = ctx->state[1];
|
||||
uint32_t c = ctx->state[2];
|
||||
uint32_t d = ctx->state[3];
|
||||
uint32_t e = ctx->state[4];
|
||||
uint32_t f = ctx->state[5];
|
||||
uint32_t g = ctx->state[6];
|
||||
uint32_t h = ctx->state[7];
|
||||
uint32_t lolen = len;
|
||||
|
||||
/* First increment the byte count. FIPS PUB 180-2 specifies the possible
|
||||
length of the file up to 2^64 bits. Here we only compute the
|
||||
number of bytes. Do a double word increment. */
|
||||
ctx->total[0] += lolen;
|
||||
ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen);
|
||||
|
||||
#define rol(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
#define S0(x) (rol(x, 25) ^ rol(x, 14) ^ (x >> 3))
|
||||
#define S1(x) (rol(x, 15) ^ rol(x, 13) ^ (x >> 10))
|
||||
#define SS0(x) (rol(x, 30) ^ rol(x, 19) ^ rol(x, 10))
|
||||
#define SS1(x) (rol(x, 26) ^ rol(x, 21) ^ rol(x, 7))
|
||||
|
||||
#define M(I) \
|
||||
(tm = S1(x[(I - 2) & 0x0f]) + x[(I - 7) & 0x0f] + S0(x[(I - 15) & 0x0f]) + x[I & 0x0f], \
|
||||
x[I & 0x0f] = tm)
|
||||
|
||||
#define R(A, B, C, D, E, F, G, H, K, M) \
|
||||
do { \
|
||||
t0 = SS0(A) + F2(A, B, C); \
|
||||
t1 = H + SS1(E) + F1(E, F, G) + K + M; \
|
||||
D += t1; \
|
||||
H = t0 + t1; \
|
||||
} while(0)
|
||||
|
||||
while(words < endp) {
|
||||
uint32_t tm;
|
||||
uint32_t t0, t1;
|
||||
int t;
|
||||
/* FIXME: see sha1.c for a better implementation. */
|
||||
for(t = 0; t < 16; t++) {
|
||||
x[t] = SWAP(*words);
|
||||
words++;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 64; i++) {
|
||||
uint32_t xx = i < 16 ? x[i] : M(i);
|
||||
R(a, b, c, d, e, f, g, h, K(i), xx);
|
||||
uint32_t tt = a;
|
||||
a = h;
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d;
|
||||
d = c;
|
||||
c = b;
|
||||
b = tt;
|
||||
}
|
||||
|
||||
a = ctx->state[0] += a;
|
||||
b = ctx->state[1] += b;
|
||||
c = ctx->state[2] += c;
|
||||
d = ctx->state[3] += d;
|
||||
e = ctx->state[4] += e;
|
||||
f = ctx->state[5] += f;
|
||||
g = ctx->state[6] += g;
|
||||
h = ctx->state[7] += h;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Hey Emacs!
|
||||
* Local Variables:
|
||||
* coding: utf-8
|
||||
* End:
|
||||
*/
|
||||
@@ -1,79 +0,0 @@
|
||||
/* Declarations of functions and data types used for SHA256 sum
|
||||
library functions.
|
||||
Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum { SHA256_DIGEST_SIZE = 256 / 8 };
|
||||
|
||||
/* Structure to save state of computation between the single steps. */
|
||||
struct sha256_ctx {
|
||||
uint32_t state[8];
|
||||
|
||||
uint32_t total[2];
|
||||
size_t buflen; /* ≥ 0, ≤ 128 */
|
||||
uint32_t buffer[32]; /* 128 bytes; the first buflen bytes are in use */
|
||||
};
|
||||
|
||||
/* Initialize structure containing state of computation. */
|
||||
extern void sha256_init_ctx(struct sha256_ctx* ctx);
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
It is necessary that LEN is a multiple of 64!!! */
|
||||
extern void sha256_process_block(const void* buffer, size_t len, struct sha256_ctx* ctx);
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
It is NOT required that LEN is a multiple of 64. */
|
||||
extern void sha256_process_bytes(const void* buffer, size_t len, struct sha256_ctx* ctx);
|
||||
|
||||
/* Process the remaining bytes in the buffer and put result from CTX
|
||||
in first 32 (28) bytes following RESBUF. The result is always in little
|
||||
endian byte order, so that a byte-wise output yields to the wanted
|
||||
ASCII representation of the message digest. */
|
||||
extern void* sha256_finish_ctx(struct sha256_ctx* ctx, void* restrict resbuf);
|
||||
|
||||
/* Put result from CTX in first 32 (28) bytes following RESBUF. The result is
|
||||
always in little endian byte order, so that a byte-wise output yields
|
||||
to the wanted ASCII representation of the message digest. */
|
||||
extern void* sha256_read_ctx(const struct sha256_ctx* ctx, void* restrict resbuf);
|
||||
|
||||
/* Compute SHA256 message digest for LEN bytes beginning at BUFFER.
|
||||
The result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest. */
|
||||
extern void* sha256_buffer(const char* buffer, size_t len, void* restrict resblock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hey Emacs!
|
||||
* Local Variables:
|
||||
* coding: utf-8
|
||||
* End:
|
||||
*/
|
||||
309
applications/external/totp/services/hmac/sha512.c
vendored
309
applications/external/totp/services/hmac/sha512.c
vendored
@@ -1,309 +0,0 @@
|
||||
/* sha512.c - Functions to compute SHA512 message digest of files or
|
||||
memory blocks according to the NIST specification FIPS-180-2.
|
||||
|
||||
Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by David Madore, considerably copypasting from
|
||||
Scott G. Miller's sha1.c
|
||||
*/
|
||||
|
||||
/* Specification. */
|
||||
#include "sha512.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "byteswap.h"
|
||||
#include "sha_pad_buffer.h"
|
||||
|
||||
#define SWAP(n) swap_uint64(n)
|
||||
|
||||
/*
|
||||
Takes a pointer to a 512 bit block of data (eight 64 bit ints) and
|
||||
initializes it to the start constants of the SHA512 algorithm. This
|
||||
must be called before using hash in the call to sha512_hash
|
||||
*/
|
||||
void sha512_init_ctx(struct sha512_ctx* ctx) {
|
||||
ctx->state[0] = u64hilo(0x6a09e667, 0xf3bcc908);
|
||||
ctx->state[1] = u64hilo(0xbb67ae85, 0x84caa73b);
|
||||
ctx->state[2] = u64hilo(0x3c6ef372, 0xfe94f82b);
|
||||
ctx->state[3] = u64hilo(0xa54ff53a, 0x5f1d36f1);
|
||||
ctx->state[4] = u64hilo(0x510e527f, 0xade682d1);
|
||||
ctx->state[5] = u64hilo(0x9b05688c, 0x2b3e6c1f);
|
||||
ctx->state[6] = u64hilo(0x1f83d9ab, 0xfb41bd6b);
|
||||
ctx->state[7] = u64hilo(0x5be0cd19, 0x137e2179);
|
||||
|
||||
ctx->total[0] = ctx->total[1] = u64lo(0);
|
||||
ctx->buflen = 0;
|
||||
}
|
||||
|
||||
/* Copy the value from V into the memory location pointed to by *CP,
|
||||
If your architecture allows unaligned access, this is equivalent to
|
||||
* (__typeof__ (v) *) cp = v */
|
||||
static void set_uint64(char* cp, u64 v) {
|
||||
memcpy(cp, &v, sizeof v);
|
||||
}
|
||||
|
||||
/* Put result from CTX in first 64 bytes following RESBUF.
|
||||
The result must be in little endian byte order. */
|
||||
void* sha512_read_ctx(const struct sha512_ctx* ctx, void* resbuf) {
|
||||
int i;
|
||||
char* r = resbuf;
|
||||
|
||||
for(i = 0; i < 8; i++) set_uint64(r + i * sizeof ctx->state[0], SWAP(ctx->state[i]));
|
||||
|
||||
return resbuf;
|
||||
}
|
||||
|
||||
/* Process the remaining bytes in the internal buffer and the usual
|
||||
prolog according to the standard and write the result to RESBUF. */
|
||||
static void sha512_conclude_ctx(struct sha512_ctx* ctx) {
|
||||
/* Take yet unprocessed bytes into account. */
|
||||
size_t bytes = ctx->buflen;
|
||||
size_t size = (bytes < 112) ? 128 / 8 : 128 * 2 / 8;
|
||||
|
||||
/* Now count remaining bytes. */
|
||||
ctx->total[0] = u64plus(ctx->total[0], u64lo(bytes));
|
||||
if(u64lt(ctx->total[0], u64lo(bytes))) ctx->total[1] = u64plus(ctx->total[1], u64lo(1));
|
||||
|
||||
/* Put the 128-bit file length in *bits* at the end of the buffer.
|
||||
Use set_uint64 rather than a simple assignment, to avoid risk of
|
||||
unaligned access. */
|
||||
set_uint64(
|
||||
(char*)&ctx->buffer[size - 2],
|
||||
SWAP(u64or(u64shl(ctx->total[1], 3), u64shr(ctx->total[0], 61))));
|
||||
set_uint64((char*)&ctx->buffer[size - 1], SWAP(u64shl(ctx->total[0], 3)));
|
||||
|
||||
sha_pad_buffer(&((uint8_t*)ctx->buffer)[bytes], (size - 2) * 8 - bytes);
|
||||
|
||||
/* Process last bytes. */
|
||||
sha512_process_block(ctx->buffer, size * 8, ctx);
|
||||
}
|
||||
|
||||
void* sha512_finish_ctx(struct sha512_ctx* ctx, void* resbuf) {
|
||||
sha512_conclude_ctx(ctx);
|
||||
return sha512_read_ctx(ctx, resbuf);
|
||||
}
|
||||
|
||||
/* Compute SHA512 message digest for LEN bytes beginning at BUFFER. The
|
||||
result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest. */
|
||||
void* sha512_buffer(const char* buffer, size_t len, void* resblock) {
|
||||
struct sha512_ctx ctx;
|
||||
|
||||
/* Initialize the computation context. */
|
||||
sha512_init_ctx(&ctx);
|
||||
|
||||
/* Process whole buffer but last len % 128 bytes. */
|
||||
sha512_process_bytes(buffer, len, &ctx);
|
||||
|
||||
/* Put result in desired memory area. */
|
||||
return sha512_finish_ctx(&ctx, resblock);
|
||||
}
|
||||
|
||||
void sha512_process_bytes(const void* buffer, size_t len, struct sha512_ctx* ctx) {
|
||||
/* When we already have some bits in our internal buffer concatenate
|
||||
both inputs first. */
|
||||
if(ctx->buflen != 0) {
|
||||
size_t left_over = ctx->buflen;
|
||||
size_t add = 256 - left_over > len ? len : 256 - left_over;
|
||||
|
||||
memcpy(&((char*)ctx->buffer)[left_over], buffer, add);
|
||||
ctx->buflen += add;
|
||||
|
||||
if(ctx->buflen > 128) {
|
||||
sha512_process_block(ctx->buffer, ctx->buflen & ~127, ctx);
|
||||
|
||||
ctx->buflen &= 127;
|
||||
/* The regions in the following copy operation cannot overlap,
|
||||
because ctx->buflen < 128 ≤ (left_over + add) & ~127. */
|
||||
memcpy(ctx->buffer, &((char*)ctx->buffer)[(left_over + add) & ~127], ctx->buflen);
|
||||
}
|
||||
|
||||
buffer = (const char*)buffer + add;
|
||||
len -= add;
|
||||
}
|
||||
|
||||
/* Process available complete blocks. */
|
||||
if(len >= 128) {
|
||||
#if !(_STRING_ARCH_unaligned || _STRING_INLINE_unaligned)
|
||||
#define UNALIGNED_P(p) ((uintptr_t)(p) % sizeof(u64) != 0)
|
||||
if(UNALIGNED_P(buffer))
|
||||
while(len > 128) {
|
||||
sha512_process_block(memcpy(ctx->buffer, buffer, 128), 128, ctx); //-V1086
|
||||
buffer = (const char*)buffer + 128;
|
||||
len -= 128;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
sha512_process_block(buffer, len & ~127, ctx);
|
||||
buffer = (const char*)buffer + (len & ~127);
|
||||
len &= 127;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move remaining bytes in internal buffer. */
|
||||
if(len > 0) {
|
||||
size_t left_over = ctx->buflen;
|
||||
|
||||
memcpy(&((char*)ctx->buffer)[left_over], buffer, len);
|
||||
left_over += len;
|
||||
if(left_over >= 128) {
|
||||
sha512_process_block(ctx->buffer, 128, ctx);
|
||||
left_over -= 128;
|
||||
/* The regions in the following copy operation cannot overlap,
|
||||
because left_over ≤ 128. */
|
||||
memcpy(ctx->buffer, &ctx->buffer[16], left_over);
|
||||
}
|
||||
ctx->buflen = left_over;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- Code below is the primary difference between sha1.c and sha512.c --- */
|
||||
|
||||
/* SHA512 round constants */
|
||||
#define K(I) sha512_round_constants[I]
|
||||
static u64 const sha512_round_constants[80] = {
|
||||
u64init(0x428a2f98, 0xd728ae22), u64init(0x71374491, 0x23ef65cd),
|
||||
u64init(0xb5c0fbcf, 0xec4d3b2f), u64init(0xe9b5dba5, 0x8189dbbc),
|
||||
u64init(0x3956c25b, 0xf348b538), u64init(0x59f111f1, 0xb605d019),
|
||||
u64init(0x923f82a4, 0xaf194f9b), u64init(0xab1c5ed5, 0xda6d8118),
|
||||
u64init(0xd807aa98, 0xa3030242), u64init(0x12835b01, 0x45706fbe),
|
||||
u64init(0x243185be, 0x4ee4b28c), u64init(0x550c7dc3, 0xd5ffb4e2),
|
||||
u64init(0x72be5d74, 0xf27b896f), u64init(0x80deb1fe, 0x3b1696b1),
|
||||
u64init(0x9bdc06a7, 0x25c71235), u64init(0xc19bf174, 0xcf692694),
|
||||
u64init(0xe49b69c1, 0x9ef14ad2), u64init(0xefbe4786, 0x384f25e3),
|
||||
u64init(0x0fc19dc6, 0x8b8cd5b5), u64init(0x240ca1cc, 0x77ac9c65),
|
||||
u64init(0x2de92c6f, 0x592b0275), u64init(0x4a7484aa, 0x6ea6e483),
|
||||
u64init(0x5cb0a9dc, 0xbd41fbd4), u64init(0x76f988da, 0x831153b5),
|
||||
u64init(0x983e5152, 0xee66dfab), u64init(0xa831c66d, 0x2db43210),
|
||||
u64init(0xb00327c8, 0x98fb213f), u64init(0xbf597fc7, 0xbeef0ee4),
|
||||
u64init(0xc6e00bf3, 0x3da88fc2), u64init(0xd5a79147, 0x930aa725),
|
||||
u64init(0x06ca6351, 0xe003826f), u64init(0x14292967, 0x0a0e6e70),
|
||||
u64init(0x27b70a85, 0x46d22ffc), u64init(0x2e1b2138, 0x5c26c926),
|
||||
u64init(0x4d2c6dfc, 0x5ac42aed), u64init(0x53380d13, 0x9d95b3df),
|
||||
u64init(0x650a7354, 0x8baf63de), u64init(0x766a0abb, 0x3c77b2a8),
|
||||
u64init(0x81c2c92e, 0x47edaee6), u64init(0x92722c85, 0x1482353b),
|
||||
u64init(0xa2bfe8a1, 0x4cf10364), u64init(0xa81a664b, 0xbc423001),
|
||||
u64init(0xc24b8b70, 0xd0f89791), u64init(0xc76c51a3, 0x0654be30),
|
||||
u64init(0xd192e819, 0xd6ef5218), u64init(0xd6990624, 0x5565a910),
|
||||
u64init(0xf40e3585, 0x5771202a), u64init(0x106aa070, 0x32bbd1b8),
|
||||
u64init(0x19a4c116, 0xb8d2d0c8), u64init(0x1e376c08, 0x5141ab53),
|
||||
u64init(0x2748774c, 0xdf8eeb99), u64init(0x34b0bcb5, 0xe19b48a8),
|
||||
u64init(0x391c0cb3, 0xc5c95a63), u64init(0x4ed8aa4a, 0xe3418acb),
|
||||
u64init(0x5b9cca4f, 0x7763e373), u64init(0x682e6ff3, 0xd6b2b8a3),
|
||||
u64init(0x748f82ee, 0x5defb2fc), u64init(0x78a5636f, 0x43172f60),
|
||||
u64init(0x84c87814, 0xa1f0ab72), u64init(0x8cc70208, 0x1a6439ec),
|
||||
u64init(0x90befffa, 0x23631e28), u64init(0xa4506ceb, 0xde82bde9),
|
||||
u64init(0xbef9a3f7, 0xb2c67915), u64init(0xc67178f2, 0xe372532b),
|
||||
u64init(0xca273ece, 0xea26619c), u64init(0xd186b8c7, 0x21c0c207),
|
||||
u64init(0xeada7dd6, 0xcde0eb1e), u64init(0xf57d4f7f, 0xee6ed178),
|
||||
u64init(0x06f067aa, 0x72176fba), u64init(0x0a637dc5, 0xa2c898a6),
|
||||
u64init(0x113f9804, 0xbef90dae), u64init(0x1b710b35, 0x131c471b),
|
||||
u64init(0x28db77f5, 0x23047d84), u64init(0x32caab7b, 0x40c72493),
|
||||
u64init(0x3c9ebe0a, 0x15c9bebc), u64init(0x431d67c4, 0x9c100d4c),
|
||||
u64init(0x4cc5d4be, 0xcb3e42b6), u64init(0x597f299c, 0xfc657e2a),
|
||||
u64init(0x5fcb6fab, 0x3ad6faec), u64init(0x6c44198c, 0x4a475817),
|
||||
};
|
||||
|
||||
/* Round functions. */
|
||||
#define F2(A, B, C) u64or(u64and(A, B), u64and(C, u64or(A, B)))
|
||||
#define F1(E, F, G) u64xor(G, u64and(E, u64xor(F, G)))
|
||||
|
||||
/* Process LEN bytes of BUFFER, accumulating context into CTX.
|
||||
It is assumed that LEN % 128 == 0.
|
||||
Most of this code comes from GnuPG's cipher/sha1.c. */
|
||||
|
||||
void sha512_process_block(const void* buffer, size_t len, struct sha512_ctx* ctx) {
|
||||
u64 const* words = buffer;
|
||||
u64 const* endp = words + len / sizeof(u64);
|
||||
u64 x[16];
|
||||
u64 a = ctx->state[0];
|
||||
u64 b = ctx->state[1];
|
||||
u64 c = ctx->state[2];
|
||||
u64 d = ctx->state[3];
|
||||
u64 e = ctx->state[4];
|
||||
u64 f = ctx->state[5];
|
||||
u64 g = ctx->state[6];
|
||||
u64 h = ctx->state[7];
|
||||
u64 lolen = u64size(len);
|
||||
|
||||
/* First increment the byte count. FIPS PUB 180-2 specifies the possible
|
||||
length of the file up to 2^128 bits. Here we only compute the
|
||||
number of bytes. Do a double word increment. */
|
||||
ctx->total[0] = u64plus(ctx->total[0], lolen);
|
||||
ctx->total[1] = u64plus(
|
||||
ctx->total[1], u64plus(u64size(len >> 31 >> 31 >> 2), u64lo(u64lt(ctx->total[0], lolen))));
|
||||
|
||||
#define S0(x) u64xor(u64rol(x, 63), u64xor(u64rol(x, 56), u64shr(x, 7)))
|
||||
#define S1(x) u64xor(u64rol(x, 45), u64xor(u64rol(x, 3), u64shr(x, 6)))
|
||||
#define SS0(x) u64xor(u64rol(x, 36), u64xor(u64rol(x, 30), u64rol(x, 25)))
|
||||
#define SS1(x) u64xor(u64rol(x, 50), u64xor(u64rol(x, 46), u64rol(x, 23)))
|
||||
|
||||
#define M(I) \
|
||||
(x[(I)&15] = u64plus( \
|
||||
x[(I)&15], \
|
||||
u64plus(S1(x[((I)-2) & 15]), u64plus(x[((I)-7) & 15], S0(x[((I)-15) & 15])))))
|
||||
|
||||
#define R(A, B, C, D, E, F, G, H, K, M) \
|
||||
do { \
|
||||
u64 t0 = u64plus(SS0(A), F2(A, B, C)); \
|
||||
u64 t1 = u64plus(H, u64plus(SS1(E), u64plus(F1(E, F, G), u64plus(K, M)))); \
|
||||
D = u64plus(D, t1); \
|
||||
H = u64plus(t0, t1); \
|
||||
} while(0)
|
||||
|
||||
while(words < endp) {
|
||||
int t;
|
||||
/* FIXME: see sha1.c for a better implementation. */
|
||||
for(t = 0; t < 16; t++) {
|
||||
x[t] = SWAP(*words);
|
||||
words++;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 80; i++) {
|
||||
u64 xx = i < 16 ? x[i] : M(i);
|
||||
R(a, b, c, d, e, f, g, h, K(i), xx);
|
||||
u64 tt = a;
|
||||
a = h;
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d;
|
||||
d = c;
|
||||
c = b;
|
||||
b = tt;
|
||||
}
|
||||
|
||||
a = ctx->state[0] = u64plus(ctx->state[0], a);
|
||||
b = ctx->state[1] = u64plus(ctx->state[1], b);
|
||||
c = ctx->state[2] = u64plus(ctx->state[2], c);
|
||||
d = ctx->state[3] = u64plus(ctx->state[3], d);
|
||||
e = ctx->state[4] = u64plus(ctx->state[4], e);
|
||||
f = ctx->state[5] = u64plus(ctx->state[5], f);
|
||||
g = ctx->state[6] = u64plus(ctx->state[6], g);
|
||||
h = ctx->state[7] = u64plus(ctx->state[7], h);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Hey Emacs!
|
||||
* Local Variables:
|
||||
* coding: utf-8
|
||||
* End:
|
||||
*/
|
||||
@@ -1,82 +0,0 @@
|
||||
/* Declarations of functions and data types used for SHA512 and SHA384 sum
|
||||
library functions.
|
||||
Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include "u64.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum { SHA512_DIGEST_SIZE = 512 / 8 };
|
||||
|
||||
/* Structure to save state of computation between the single steps. */
|
||||
struct sha512_ctx {
|
||||
u64 state[8];
|
||||
|
||||
u64 total[2];
|
||||
size_t buflen; /* ≥ 0, ≤ 256 */
|
||||
u64 buffer[32]; /* 256 bytes; the first buflen bytes are in use */
|
||||
};
|
||||
|
||||
/* Initialize structure containing state of computation. */
|
||||
extern void sha512_init_ctx(struct sha512_ctx* ctx);
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
It is necessary that LEN is a multiple of 128!!! */
|
||||
extern void sha512_process_block(const void* buffer, size_t len, struct sha512_ctx* ctx);
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
It is NOT required that LEN is a multiple of 128. */
|
||||
extern void sha512_process_bytes(const void* buffer, size_t len, struct sha512_ctx* ctx);
|
||||
|
||||
/* Process the remaining bytes in the buffer and put result from CTX
|
||||
in first 64 (48) bytes following RESBUF. The result is always in little
|
||||
endian byte order, so that a byte-wise output yields to the wanted
|
||||
ASCII representation of the message digest. */
|
||||
extern void* sha512_finish_ctx(struct sha512_ctx* ctx, void* restrict resbuf);
|
||||
|
||||
/* Put result from CTX in first 64 (48) bytes following RESBUF. The result is
|
||||
always in little endian byte order, so that a byte-wise output yields
|
||||
to the wanted ASCII representation of the message digest.
|
||||
|
||||
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||
aligned for a 32 bits value. */
|
||||
extern void* sha512_read_ctx(const struct sha512_ctx* ctx, void* restrict resbuf);
|
||||
|
||||
/* Compute SHA512 message digest for LEN bytes beginning at BUFFER.
|
||||
The result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest. */
|
||||
extern void* sha512_buffer(const char* buffer, size_t len, void* restrict resblock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hey Emacs!
|
||||
* Local Variables:
|
||||
* coding: utf-8
|
||||
* End:
|
||||
*/
|
||||
@@ -1,11 +0,0 @@
|
||||
#include "sha_pad_buffer.h"
|
||||
#include <string.h>
|
||||
|
||||
void sha_pad_buffer(uint8_t* buffer, size_t size) {
|
||||
if(size > 0) {
|
||||
buffer[0] = 0x80;
|
||||
if(size > 1) {
|
||||
memset(&buffer[1], 0, size - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void sha_pad_buffer(uint8_t* buffer, size_t size);
|
||||
44
applications/external/totp/services/hmac/u64.h
vendored
44
applications/external/totp/services/hmac/u64.h
vendored
@@ -1,44 +0,0 @@
|
||||
/* uint64_t-like operations that work even on hosts lacking uint64_t
|
||||
|
||||
Copyright (C) 2006, 2009-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef _GL_U64_INLINE
|
||||
#define _GL_U64_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
/* Return X rotated left by N bits, where 0 < N < 64. */
|
||||
#define u64rol(x, n) u64or(u64shl(x, n), u64shr(x, 64 - (n)))
|
||||
|
||||
/* Native implementations are trivial. See below for comments on what
|
||||
these operations do. */
|
||||
typedef uint64_t u64;
|
||||
#define u64hilo(hi, lo) ((u64)(((u64)(hi) << 32) + (lo)))
|
||||
#define u64init(hi, lo) u64hilo(hi, lo)
|
||||
#define u64lo(x) ((u64)(x))
|
||||
#define u64size(x) u64lo(x)
|
||||
#define u64lt(x, y) ((x) < (y))
|
||||
#define u64and(x, y) ((x) & (y))
|
||||
#define u64or(x, y) ((x) | (y))
|
||||
#define u64xor(x, y) ((x) ^ (y))
|
||||
#define u64plus(x, y) ((x) + (y))
|
||||
#define u64shl(x, n) ((x) << (n))
|
||||
#define u64shr(x, n) ((x) >> (n))
|
||||
44
applications/external/totp/services/totp/totp.c
vendored
44
applications/external/totp/services/totp/totp.c
vendored
@@ -4,12 +4,16 @@
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <timezone_utils.h>
|
||||
#include "../hmac/hmac_sha1.h"
|
||||
#include "../hmac/hmac_sha256.h"
|
||||
#include "../hmac/hmac_sha512.h"
|
||||
#include "../hmac/byteswap.h"
|
||||
#include "../../config/wolfssl/config.h"
|
||||
#include <wolfssl/wolfcrypt/hmac.h>
|
||||
|
||||
#define HMAC_MAX_RESULT_SIZE HMAC_SHA512_RESULT_SIZE
|
||||
#define HMAC_MAX_RESULT_SIZE WC_SHA512_DIGEST_SIZE
|
||||
|
||||
static uint64_t swap_uint64(uint64_t val) {
|
||||
val = ((val << 8) & 0xFF00FF00FF00FF00ULL) | ((val >> 8) & 0x00FF00FF00FF00FFULL);
|
||||
val = ((val << 16) & 0xFFFF0000FFFF0000ULL) | ((val >> 16) & 0x0000FFFF0000FFFFULL);
|
||||
return (val << 32) | (val >> 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generates the timeblock for a time in seconds.
|
||||
@@ -68,14 +72,34 @@ uint64_t totp_at(
|
||||
algo, plain_secret, plain_secret_length, totp_timecode(interval, for_time_adjusted));
|
||||
}
|
||||
|
||||
static int totp_algo_common(
|
||||
int type,
|
||||
const uint8_t* key,
|
||||
size_t key_length,
|
||||
const uint8_t* input,
|
||||
size_t input_length,
|
||||
uint8_t* output) {
|
||||
Hmac hmac;
|
||||
int ret = wc_HmacSetKey(&hmac, type, key, key_length);
|
||||
if(ret == 0) {
|
||||
ret = wc_HmacUpdate(&hmac, input, input_length);
|
||||
}
|
||||
|
||||
if(ret == 0) {
|
||||
ret = wc_HmacFinal(&hmac, output);
|
||||
}
|
||||
|
||||
wc_HmacFree(&hmac);
|
||||
return ret == 0 ? wc_HmacSizeByType(type) : 0;
|
||||
}
|
||||
|
||||
static int totp_algo_sha1(
|
||||
const uint8_t* key,
|
||||
size_t key_length,
|
||||
const uint8_t* input,
|
||||
size_t input_length,
|
||||
uint8_t* output) {
|
||||
hmac_sha1(key, key_length, input, input_length, output);
|
||||
return HMAC_SHA1_RESULT_SIZE;
|
||||
return totp_algo_common(WC_SHA, key, key_length, input, input_length, output);
|
||||
}
|
||||
|
||||
static int totp_algo_sha256(
|
||||
@@ -84,8 +108,7 @@ static int totp_algo_sha256(
|
||||
const uint8_t* input,
|
||||
size_t input_length,
|
||||
uint8_t* output) {
|
||||
hmac_sha256(key, key_length, input, input_length, output);
|
||||
return HMAC_SHA256_RESULT_SIZE;
|
||||
return totp_algo_common(WC_SHA256, key, key_length, input, input_length, output);
|
||||
}
|
||||
|
||||
static int totp_algo_sha512(
|
||||
@@ -94,8 +117,7 @@ static int totp_algo_sha512(
|
||||
const uint8_t* input,
|
||||
size_t input_length,
|
||||
uint8_t* output) {
|
||||
hmac_sha512(key, key_length, input, input_length, output);
|
||||
return HMAC_SHA512_RESULT_SIZE;
|
||||
return totp_algo_common(WC_SHA512, key, key_length, input, input_length, output);
|
||||
}
|
||||
|
||||
const TOTP_ALGO TOTP_ALGO_SHA1 = (TOTP_ALGO)(&totp_algo_sha1);
|
||||
|
||||
5
applications/external/totp/totp_app.c
vendored
5
applications/external/totp/totp_app.c
vendored
@@ -4,7 +4,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <notification/notification.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include "features_config.h"
|
||||
#include "config/app/config.h"
|
||||
#include "services/config/config.h"
|
||||
#include "types/plugin_state.h"
|
||||
#include "types/token_info.h"
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "services/crypto/crypto_facade.h"
|
||||
#include "cli/cli.h"
|
||||
#include "version.h"
|
||||
#include <wolfssl/version.h>
|
||||
|
||||
struct TotpRenderCallbackContext {
|
||||
FuriMutex* mutex;
|
||||
@@ -217,6 +218,8 @@ int32_t totp_app() {
|
||||
TOTP_APP_VERSION_MAJOR,
|
||||
TOTP_APP_VERSION_MINOR,
|
||||
TOTP_APP_VERSION_PATCH);
|
||||
FURI_LOG_I(LOGGING_TAG, "WolfSSL version: " LIBWOLFSSL_VERSION_STRING);
|
||||
|
||||
PluginState* plugin_state = malloc(sizeof(PluginState));
|
||||
furi_check(plugin_state != NULL);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../features_config.h"
|
||||
#include "../config/app/config.h"
|
||||
|
||||
typedef uint8_t AutomationMethod;
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ typedef struct {
|
||||
uint8_t iv[CRYPTO_IV_LENGTH];
|
||||
|
||||
/**
|
||||
* @brief Basic randomly-generated initialization vector (IV)
|
||||
* @brief Randomly-generated salt
|
||||
*/
|
||||
uint8_t base_iv[CRYPTO_IV_LENGTH];
|
||||
uint8_t salt[CRYPTO_SALT_LENGTH];
|
||||
|
||||
/**
|
||||
* @brief Encrypted well-known data
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <notification/notification.h>
|
||||
#include <gui/gui.h>
|
||||
#include <dialogs/dialogs.h>
|
||||
#include "../features_config.h"
|
||||
#include "../config/app/config.h"
|
||||
#include "../ui/totp_scenes_enum.h"
|
||||
#include "../services/config/config_file_context.h"
|
||||
#include "../services/idle_timeout/idle_timeout.h"
|
||||
|
||||
11
applications/external/totp/ui/scene_director.c
vendored
11
applications/external/totp/ui/scene_director.c
vendored
@@ -1,8 +1,11 @@
|
||||
#include "../types/common.h"
|
||||
#include "../config/app/config.h"
|
||||
#include "scene_director.h"
|
||||
#include "scenes/authenticate/totp_scene_authenticate.h"
|
||||
#include "scenes/generate_token/totp_scene_generate_token.h"
|
||||
#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
|
||||
#include "scenes/add_new_token/totp_scene_add_new_token.h"
|
||||
#endif
|
||||
#include "scenes/token_menu/totp_scene_token_menu.h"
|
||||
#include "scenes/app_settings/totp_app_settings.h"
|
||||
#include "scenes/standby/standby.h"
|
||||
@@ -16,9 +19,11 @@ void totp_scene_director_activate_scene(PluginState* const plugin_state, Scene s
|
||||
case TotpSceneAuthentication:
|
||||
totp_scene_authenticate_activate(plugin_state);
|
||||
break;
|
||||
#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
|
||||
case TotpSceneAddNewToken:
|
||||
totp_scene_add_new_token_activate(plugin_state);
|
||||
break;
|
||||
#endif
|
||||
case TotpSceneTokenMenu:
|
||||
totp_scene_token_menu_activate(plugin_state);
|
||||
break;
|
||||
@@ -45,9 +50,11 @@ void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state
|
||||
case TotpSceneAuthentication:
|
||||
totp_scene_authenticate_deactivate(plugin_state);
|
||||
break;
|
||||
#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
|
||||
case TotpSceneAddNewToken:
|
||||
totp_scene_add_new_token_deactivate(plugin_state);
|
||||
break;
|
||||
#endif
|
||||
case TotpSceneTokenMenu:
|
||||
totp_scene_token_menu_deactivate(plugin_state);
|
||||
break;
|
||||
@@ -70,9 +77,11 @@ void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_
|
||||
case TotpSceneAuthentication:
|
||||
totp_scene_authenticate_render(canvas, plugin_state);
|
||||
break;
|
||||
#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
|
||||
case TotpSceneAddNewToken:
|
||||
totp_scene_add_new_token_render(canvas, plugin_state);
|
||||
break;
|
||||
#endif
|
||||
case TotpSceneTokenMenu:
|
||||
totp_scene_token_menu_render(canvas, plugin_state);
|
||||
break;
|
||||
@@ -98,9 +107,11 @@ bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* con
|
||||
case TotpSceneAuthentication:
|
||||
processing = totp_scene_authenticate_handle_event(event, plugin_state);
|
||||
break;
|
||||
#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
|
||||
case TotpSceneAddNewToken:
|
||||
processing = totp_scene_add_new_token_handle_event(event, plugin_state);
|
||||
break;
|
||||
#endif
|
||||
case TotpSceneTokenMenu:
|
||||
processing = totp_scene_token_menu_handle_event(event, plugin_state);
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "totp_input_text.h"
|
||||
|
||||
#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/modules/text_input.h>
|
||||
|
||||
@@ -50,3 +51,4 @@ void totp_input_text(Gui* gui, const char* header_text, InputTextResult* result)
|
||||
view_dispatcher_free(view_dispatcher);
|
||||
text_input_free(text_input);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../../config/app/config.h"
|
||||
#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
|
||||
#include <gui/gui.h>
|
||||
|
||||
#define INPUT_BUFFER_SIZE (255)
|
||||
@@ -11,3 +13,4 @@ typedef struct {
|
||||
} InputTextResult;
|
||||
|
||||
void totp_input_text(Gui* gui, const char* header_text, InputTextResult* result);
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "totp_scene_add_new_token.h"
|
||||
#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
|
||||
#include "../../../types/common.h"
|
||||
#include "../../constants.h"
|
||||
#include "../../scene_director.h"
|
||||
@@ -8,7 +9,6 @@
|
||||
#include "../../ui_controls.h"
|
||||
#include "../../common_dialogs.h"
|
||||
#include <roll_value.h>
|
||||
#include "../generate_token/totp_scene_generate_token.h"
|
||||
|
||||
char* TOKEN_ALGO_LIST[] = {"SHA1", "SHA256", "SHA512", "Steam"};
|
||||
char* TOKEN_DIGITS_TEXT_LIST[] = {"5 digits", "6 digits", "8 digits"};
|
||||
@@ -318,3 +318,4 @@ void totp_scene_add_new_token_deactivate(PluginState* plugin_state) {
|
||||
free(plugin_state->current_scene_state);
|
||||
plugin_state->current_scene_state = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../../config/app/config.h"
|
||||
#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
|
||||
#include <gui/gui.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../types/plugin_event.h"
|
||||
@@ -10,3 +12,4 @@ bool totp_scene_add_new_token_handle_event(
|
||||
const PluginEvent* const event,
|
||||
PluginState* plugin_state);
|
||||
void totp_scene_add_new_token_deactivate(PluginState* plugin_state);
|
||||
#endif
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
#include "totp_app_settings.h"
|
||||
#include <math.h>
|
||||
#include <totp_icons.h>
|
||||
#include <assets_icons.h>
|
||||
#include <available_fonts.h>
|
||||
#include "../../canvas_extensions.h"
|
||||
#include "../../ui_controls.h"
|
||||
#include "../../common_dialogs.h"
|
||||
#include "../../scene_director.h"
|
||||
#include "../token_menu/totp_scene_token_menu.h"
|
||||
#include "../../constants.h"
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../../services/convert/convert.h"
|
||||
#include <roll_value.h>
|
||||
#include "../../../features_config.h"
|
||||
#include "../../../config/app/config.h"
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
#include "../../../workers/bt_type_code/bt_type_code.h"
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "totp_scene_generate_token.h"
|
||||
#include <gui/gui.h>
|
||||
#include <notification/notification.h>
|
||||
#include <notification/notification_messages.h>
|
||||
@@ -5,15 +6,13 @@
|
||||
#include <assets_icons.h>
|
||||
#include <roll_value.h>
|
||||
#include <available_fonts.h>
|
||||
#include "totp_scene_generate_token.h"
|
||||
#include "../../canvas_extensions.h"
|
||||
#include "../../../types/token_info.h"
|
||||
#include "../../../types/common.h"
|
||||
#include "../../constants.h"
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../scene_director.h"
|
||||
#include "../token_menu/totp_scene_token_menu.h"
|
||||
#include "../../../features_config.h"
|
||||
#include "../../../config/app/config.h"
|
||||
#include "../../../workers/generate_totp_code/generate_totp_code.h"
|
||||
#include "../../../workers/usb_type_code/usb_type_code.h"
|
||||
#ifdef TOTP_BADBT_AUTOMATION_ENABLED
|
||||
@@ -247,7 +246,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
||||
SCREEN_HEIGHT_CENTER + 10,
|
||||
AlignCenter,
|
||||
AlignCenter,
|
||||
"Press OK button to add");
|
||||
"Press OK button to access menu");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
#include "../../scene_director.h"
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../../types/token_info.h"
|
||||
#include "../generate_token/totp_scene_generate_token.h"
|
||||
#include "../add_new_token/totp_scene_add_new_token.h"
|
||||
#include "../app_settings/totp_app_settings.h"
|
||||
#include "../../../config/app/config.h"
|
||||
#include <roll_value.h>
|
||||
|
||||
#define SCREEN_HEIGHT_THIRD (SCREEN_HEIGHT / 3)
|
||||
@@ -130,7 +128,22 @@ bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginSt
|
||||
} else if(event->input.type == InputTypeRelease && event->input.key == InputKeyOk) {
|
||||
switch(scene_state->selected_control) {
|
||||
case AddNewToken: {
|
||||
#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneAddNewToken);
|
||||
#else
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
dialog_message_set_buttons(message, "Back", NULL, NULL);
|
||||
dialog_message_set_header(message, "Information", 0, 0, AlignLeft, AlignTop);
|
||||
dialog_message_set_text(
|
||||
message,
|
||||
"Read here\nhttps://t.ly/8ZOtj\n how to add new token",
|
||||
SCREEN_WIDTH_CENTER,
|
||||
SCREEN_HEIGHT_CENTER,
|
||||
AlignCenter,
|
||||
AlignCenter);
|
||||
dialog_message_show(plugin_state->dialogs_app, message);
|
||||
dialog_message_free(message);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case DeleteToken: {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../config/app/config.h"
|
||||
|
||||
typedef uint8_t Scene;
|
||||
|
||||
/**
|
||||
@@ -21,10 +23,12 @@ enum Scenes {
|
||||
*/
|
||||
TotpSceneGenerateToken,
|
||||
|
||||
#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
|
||||
/**
|
||||
* @brief Scene where user can add new token
|
||||
*/
|
||||
TotpSceneAddNewToken,
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Scene with a menu for given token, allowing user to do multiple actions
|
||||
|
||||
6
applications/external/totp/version.h
vendored
6
applications/external/totp/version.h
vendored
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define TOTP_APP_VERSION_MAJOR (3)
|
||||
#define TOTP_APP_VERSION_MINOR (2)
|
||||
#define TOTP_APP_VERSION_PATCH (0)
|
||||
#define TOTP_APP_VERSION_MAJOR (4)
|
||||
#define TOTP_APP_VERSION_MINOR (0)
|
||||
#define TOTP_APP_VERSION_PATCH (1)
|
||||
@@ -11,7 +11,8 @@
|
||||
#include "../../types/common.h"
|
||||
#include "../../types/token_info.h"
|
||||
#include "../type_code_common.h"
|
||||
#include "../../features_config.h"
|
||||
#include "../../config/app/config.h"
|
||||
#include "../../services/config/constants.h"
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
#define TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN FURI_HAL_BT_ADV_NAME_LENGTH
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <stdbool.h>
|
||||
#include <furi/core/mutex.h>
|
||||
#include "../../types/automation_kb_layout.h"
|
||||
#include "../../services/config/constants.h"
|
||||
|
||||
#define TOTP_BT_KEYS_STORAGE_PATH EXT_PATH("apps_data/totp/.bt_hid.keys")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user