Temporarily backport app updates from apps repo

This commit is contained in:
Willy-JL
2023-11-12 11:06:02 +00:00
parent 79e7f491fe
commit e309fa8a88
1498 changed files with 1325977 additions and 20227 deletions

View File

@@ -6,6 +6,10 @@
#include "constants.h"
#include "token_info_iterator.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef uint8_t TotpConfigFileOpenResult;
typedef uint8_t TotpConfigFileUpdateResult;
@@ -101,4 +105,8 @@ bool totp_config_file_ensure_latest_encryption(
* @param plugin_state application state
* @return token info iterator context
*/
TokenInfoIteratorContext* totp_config_get_token_iterator_context(const PluginState* plugin_state);
TokenInfoIteratorContext* totp_config_get_token_iterator_context(const PluginState* plugin_state);
#ifdef __cplusplus
}
#endif

View File

@@ -4,7 +4,7 @@
#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("apps_data/totp")
#define CONFIG_FILE_HEADER "Flipper TOTP plugin config file"
#define CONFIG_FILE_ACTUAL_VERSION (9)
#define CONFIG_FILE_ACTUAL_VERSION (10)
#define TOTP_CONFIG_KEY_TIMEZONE "Timezone"
#define TOTP_CONFIG_KEY_TOKEN_NAME "TokenName"
@@ -13,6 +13,8 @@
#define TOTP_CONFIG_KEY_TOKEN_DIGITS "TokenDigits"
#define TOTP_CONFIG_KEY_TOKEN_DURATION "TokenDuration"
#define TOTP_CONFIG_KEY_TOKEN_AUTOMATION_FEATURES "TokenAutomationFeatures"
#define TOTP_CONFIG_KEY_TOKEN_TYPE "TokenType"
#define TOTP_CONFIG_KEY_TOKEN_COUNTER "TokenCounter"
#define TOTP_CONFIG_KEY_CRYPTO_VERIFY "Crypto"
#define TOTP_CONFIG_KEY_SALT "Salt"
#define TOTP_CONFIG_KEY_PINSET "PinIsSet"

View File

@@ -182,6 +182,26 @@ bool totp_config_migrate_to_latest(
&default_automation_features,
1);
}
if(current_version > 9) {
flipper_format_read_string(
fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_TYPE, temp_str);
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_TYPE, temp_str);
flipper_format_read_string(
fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_COUNTER, temp_str);
flipper_format_write_string(
fff_data_file, TOTP_CONFIG_KEY_TOKEN_COUNTER, temp_str);
} else {
const uint32_t default_token_type = TokenTypeTOTP;
flipper_format_write_uint32(
fff_data_file, TOTP_CONFIG_KEY_TOKEN_TYPE, &default_token_type, 1);
const uint64_t default_counter = 0;
flipper_format_write_hex(
fff_data_file,
TOTP_CONFIG_KEY_TOKEN_COUNTER,
(const uint8_t*)&default_counter,
sizeof(default_counter));
}
}
Stream* stream = flipper_format_get_raw_stream(fff_data_file);
@@ -196,4 +216,4 @@ bool totp_config_migrate_to_latest(
furi_string_free(temp_str);
return result;
}
}

View File

@@ -199,6 +199,19 @@ static bool
break;
}
tmp_uint32 = token_info->type;
if(!flipper_format_write_uint32(temp_ff, TOTP_CONFIG_KEY_TOKEN_TYPE, &tmp_uint32, 1)) {
break;
}
if(!flipper_format_write_hex(
temp_ff,
TOTP_CONFIG_KEY_TOKEN_COUNTER,
(uint8_t*)&token_info->counter,
sizeof(token_info->counter))) {
break;
}
Stream* temp_stream = flipper_format_get_raw_stream(temp_ff);
if(!stream_rewind(temp_stream)) {
@@ -398,6 +411,54 @@ TotpIteratorUpdateTokenResult totp_token_info_iterator_update_current_token(
return result;
}
TotpIteratorUpdateTokenResult
totp_token_info_iterator_current_token_inc_counter(TokenInfoIteratorContext* context) {
if(!seek_to_token(context->current_index, context)) {
return TotpIteratorUpdateTokenResultFileUpdateFailed;
}
Stream* stream = flipper_format_get_raw_stream(context->config_file);
size_t offset_start = stream_tell(stream);
TokenInfo* token_info = context->current_token;
token_info->counter++;
char buffer[sizeof(TOTP_CONFIG_KEY_TOKEN_COUNTER) + 1];
bool found = false;
while(!found) {
if(!stream_seek_to_char(stream, '\n', StreamDirectionForward)) {
break;
}
size_t buffer_read_size;
if((buffer_read_size = stream_read(stream, (uint8_t*)&buffer[0], sizeof(buffer))) == 0) {
break;
}
if(!stream_seek(stream, -(int32_t)buffer_read_size, StreamOffsetFromCurrent)) {
break;
}
if(strncmp(buffer, "\n" TOTP_CONFIG_KEY_TOKEN_COUNTER ":", sizeof(buffer)) == 0) {
found = true;
}
}
TotpIteratorUpdateTokenResult result = TotpIteratorUpdateTokenResultFileUpdateFailed;
if(found && stream_seek(stream, 1, StreamOffsetFromCurrent) &&
flipper_format_write_hex(
context->config_file,
TOTP_CONFIG_KEY_TOKEN_COUNTER,
(uint8_t*)&token_info->counter,
sizeof(token_info->counter))) {
result = TotpIteratorUpdateTokenResultSuccess;
}
stream_seek(stream, offset_start, StreamOffsetFromStart);
return result;
}
TotpIteratorUpdateTokenResult totp_token_info_iterator_add_new_token(
TokenInfoIteratorContext* context,
TOTP_ITERATOR_UPDATE_TOKEN_ACTION update,
@@ -521,6 +582,21 @@ bool totp_token_info_iterator_go_to(TokenInfoIteratorContext* context, size_t to
tokenInfo->automation_features = TokenAutomationFeatureNone;
}
if(flipper_format_read_uint32(
context->config_file, TOTP_CONFIG_KEY_TOKEN_TYPE, &temp_data32, 1)) {
tokenInfo->type = temp_data32;
} else {
tokenInfo->type = TokenTypeTOTP;
}
if(!flipper_format_read_hex(
context->config_file,
TOTP_CONFIG_KEY_TOKEN_COUNTER,
(uint8_t*)&tokenInfo->counter,
sizeof(tokenInfo->counter))) {
tokenInfo->counter = 0;
}
stream_seek(stream, original_offset, StreamOffsetFromStart);
if(token_update_needed && !totp_token_info_iterator_save_current_token_info_changes(context)) {
@@ -549,4 +625,4 @@ void totp_token_info_iterator_attach_to_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);
}
}

View File

@@ -4,6 +4,10 @@
#include <flipper_format/flipper_format.h>
#include "constants.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef int TotpIteratorUpdateTokenResult;
typedef TotpIteratorUpdateTokenResult (
@@ -66,6 +70,14 @@ TotpIteratorUpdateTokenResult totp_token_info_iterator_update_current_token(
TOTP_ITERATOR_UPDATE_TOKEN_ACTION update,
const void* update_context);
/**
* @brief Increments token counter
* @param context token info iterator context
* @return \c true if operation succeeded; \c false otherwise
*/
TotpIteratorUpdateTokenResult
totp_token_info_iterator_current_token_inc_counter(TokenInfoIteratorContext* context);
/**
* @brief Adds new token info to the end of the list using given update action
* @param context token info iterator context
@@ -121,3 +133,7 @@ size_t totp_token_info_iterator_get_total_count(const TokenInfoIteratorContext*
void totp_token_info_iterator_attach_to_config_file(
TokenInfoIteratorContext* context,
FlipperFormat* config_file);
#ifdef __cplusplus
}
#endif

View File

@@ -1,6 +1,6 @@
#pragma once
#include "polyfills.h"
#include <furi_hal_crypto.h>
#define CRYPTO_IV_LENGTH (16)
#define CRYPTO_SALT_LENGTH (16)
@@ -11,4 +11,4 @@
#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 (3)
#define CRYPTO_LATEST_VERSION (3)

View File

@@ -6,6 +6,10 @@
#include "../../types/crypto_settings.h"
#include "common_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Checks whether key slot can be used for encryption purposes
* @param key_slot key slot index
@@ -57,3 +61,7 @@ CryptoSeedIVResult
* @return \c true if cryptographic information is valid; \c false otherwise
*/
bool totp_crypto_verify_key(const CryptoSettings* crypto_settings);
#ifdef __cplusplus
}
#endif

View File

@@ -7,7 +7,6 @@
#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)
@@ -142,4 +141,4 @@ bool totp_crypto_verify_key_v1(const CryptoSettings* crypto_settings) {
return key_valid;
}
#endif
#endif

View File

@@ -10,7 +10,6 @@
#include <wolfssl/wolfcrypt/hmac.h>
#include "memset_s.h"
#include "constants.h"
#include "polyfills.h"
#define CRYPTO_ALIGNMENT_FACTOR (16)

View File

@@ -10,7 +10,6 @@
#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)
@@ -192,4 +191,4 @@ bool totp_crypto_verify_key_v3(const CryptoSettings* crypto_settings) {
free(decrypted_key);
return key_valid;
}
}

View File

@@ -1,14 +0,0 @@
#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

View File

@@ -0,0 +1,27 @@
#include "font_info.h"
#include <furi/core/check.h>
FontInfo* totp_font_info_alloc() {
FontInfo* font_info = malloc(sizeof(FontInfo));
furi_check(font_info != NULL);
font_info->data = NULL;
font_info->char_info = NULL;
return font_info;
}
void totp_font_info_free(FontInfo* font_info) {
if(font_info == NULL) return;
if(font_info->char_info != NULL) {
free(font_info->char_info);
}
if(font_info->data != NULL) {
free(font_info->data);
}
if(font_info->name != NULL) {
free(font_info->name);
}
free(font_info);
}

View File

@@ -0,0 +1,66 @@
#pragma once
#include <stdint.h>
struct FontCharInfo_s {
/**
* @brief Width of the character
*/
uint8_t width;
/**
* @brief Offset of the character's bitmap, in bytes, into the the data array
*/
uint16_t offset;
} __attribute__((packed));
typedef struct FontCharInfo_s FontCharInfo;
typedef struct {
/**
* @brief Font name
*/
char* name;
/**
* @brief Font characters height
*/
uint8_t height;
/**
* @brief The first character available in the font
*/
uint8_t start_char;
/**
* @brief The last character available in the font
*/
uint8_t end_char;
/**
* @brief Space character width
*/
uint8_t space_width;
/**
* @brief Pointer to array of char information
*/
FontCharInfo* char_info;
/**
* @brief Pointer to generated array of character visual representation
*/
uint8_t* data;
} FontInfo;
/**
* @brief Allocates a new instance of \c FontInfo
* @return pointer to allocated instance
*/
FontInfo* totp_font_info_alloc();
/**
* @brief Disposes all the resources allocated by the given \c FontInfo instance
* @param font_info instance to dispose
*/
void totp_font_info_free(FontInfo* font_info);

View File

@@ -0,0 +1,114 @@
#include "font_provider.h"
#include <inttypes.h>
#include <toolbox/dir_walk.h>
#include <toolbox/path.h>
#include <toolbox/stream/stream.h>
#include <toolbox/stream/file_stream.h>
#define FONT_BASE_PATH EXT_PATH("apps_assets/totp/fonts")
#define FONT_FILE_EXTENSION ".font"
size_t totp_font_provider_get_fonts_count() {
size_t result = 0;
Storage* storage = furi_record_open(RECORD_STORAGE);
FuriString* path_src = furi_string_alloc();
DirWalk* dir_walk = dir_walk_alloc(storage);
dir_walk_set_recursive(dir_walk, false);
if(dir_walk_open(dir_walk, FONT_BASE_PATH)) {
char extension[sizeof(FONT_FILE_EXTENSION)];
while(dir_walk_read(dir_walk, path_src, NULL) == DirWalkOK) {
path_extract_extension(path_src, &extension[0], sizeof(extension));
if(strncmp(&extension[0], FONT_FILE_EXTENSION, sizeof(FONT_FILE_EXTENSION)) == 0) {
result++;
}
}
}
furi_string_free(path_src);
dir_walk_free(dir_walk);
furi_record_close(RECORD_STORAGE);
return result;
}
bool totp_font_provider_get_font(size_t font_index, FontInfo* font_info) {
Storage* storage = furi_record_open(RECORD_STORAGE);
Stream* stream = file_stream_alloc(storage);
bool loaded = false;
FuriString* font_path = furi_string_alloc_printf(
"%s/%02" PRIu16 "%s", FONT_BASE_PATH, font_index, FONT_FILE_EXTENSION);
do {
if(!file_stream_open(
stream, furi_string_get_cstr(font_path), FSAM_READ, FSOM_OPEN_EXISTING) ||
!stream_rewind(stream)) {
break;
}
uint8_t font_name_length;
if(!stream_read(stream, &font_name_length, 1)) {
break;
}
if(font_info->name != NULL) {
free(font_info->name);
}
font_info->name = malloc(font_name_length + 1);
furi_check(font_info->name);
if(!stream_read(stream, (uint8_t*)font_info->name, font_name_length)) {
break;
}
font_info->name[font_name_length] = '\0';
if(!stream_read(stream, &font_info->height, 1) ||
!stream_read(stream, &font_info->start_char, 1) ||
!stream_read(stream, &font_info->end_char, 1) ||
!stream_read(stream, &font_info->space_width, 1)) {
break;
}
uint16_t bitmap_data_length;
if(!stream_read(stream, (uint8_t*)&bitmap_data_length, 2)) {
break;
}
if(font_info->data != NULL) {
free(font_info->data);
}
font_info->data = malloc(bitmap_data_length);
furi_check(font_info->data);
if(!stream_read(stream, font_info->data, bitmap_data_length)) {
break;
}
uint8_t descriptors_length;
if(!stream_read(stream, &descriptors_length, 1)) {
break;
}
if(font_info->char_info != NULL) {
free(font_info->char_info);
}
uint16_t char_info_array_size = descriptors_length * sizeof(FontCharInfo);
font_info->char_info = malloc(char_info_array_size);
furi_check(font_info->char_info);
if(!stream_read(stream, (uint8_t*)font_info->char_info, char_info_array_size)) {
break;
}
loaded = true;
} while(false);
furi_string_free(font_path);
file_stream_close(stream);
stream_free(stream);
furi_record_close(RECORD_STORAGE);
return loaded;
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include "font_info.h"
#include <stdbool.h>
#include <stddef.h>
/**
* @brief Gets total fonts available
* @return total fonts available
*/
size_t totp_font_provider_get_fonts_count();
/**
* @brief Load font with given index
* @param font_index font index
* @param[out] font_info font info to populate
* @return \c true if font successfully load; \c false otherwise
*/
bool totp_font_provider_get_font(size_t font_index, FontInfo* font_info);

View File

@@ -6,15 +6,15 @@
#include <timezone_utils.h>
#include "../../config/wolfssl/config.h"
#include <wolfssl/wolfcrypt/hmac.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
#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.
* Timeblocks are the amount of intervals in a given time. For example,
@@ -43,7 +43,7 @@ uint64_t otp_generate(
uint64_t input) {
uint8_t hmac[HMAC_MAX_RESULT_SIZE] = {0};
uint64_t input_swapped = swap_uint64(input);
uint64_t input_swapped = ByteReverseWord64(input);
int hmac_len =
(*algo)(plain_secret, plain_secret_length, (uint8_t*)&input_swapped, 8, &hmac[0]);
@@ -72,6 +72,14 @@ uint64_t totp_at(
algo, plain_secret, plain_secret_length, totp_timecode(interval, for_time_adjusted));
}
uint64_t hotp_at(
TOTP_ALGO algo,
const uint8_t* plain_secret,
size_t plain_secret_length,
uint64_t counter) {
return otp_generate(algo, plain_secret, plain_secret_length, counter);
}
static int totp_algo_common(
int type,
const uint8_t* key,

View File

@@ -37,7 +37,7 @@ extern const TOTP_ALGO TOTP_ALGO_SHA256;
extern const TOTP_ALGO TOTP_ALGO_SHA512;
/**
* @brief Generates a OTP key using the totp algorithm.
* @brief Generates a TOTP key using the totp algorithm.
* @param algo hashing algorithm to be used
* @param plain_secret plain token secret
* @param plain_secret_length plain token secret length
@@ -53,3 +53,17 @@ uint64_t totp_at(
uint64_t for_time,
float timezone,
uint8_t interval);
/**
* @brief Generates a HOTP key using the hotp algorithm.
* @param algo hashing algorithm to be used
* @param plain_secret plain token secret
* @param plain_secret_length plain token secret length
* @param counter the HOTP counter
* @return HOTP code if code was successfully generated; 0 otherwise
*/
uint64_t hotp_at(
TOTP_ALGO algo,
const uint8_t* plain_secret,
size_t plain_secret_length,
uint64_t counter);