Просмотр исходного кода

Refactoring

* Dropped useless polyfill
* Replaced `swap_uint64` with WolfSSL alternative
* Replaced `base64_decode` with WolfSSL alternative
* Better estimation for Base32/Base64 output buffer size
alex.kopachov 2 лет назад
Родитель
Сommit
ed54bda8c0

+ 1 - 3
application.fam

@@ -19,9 +19,6 @@ App(
         Lib(
             name="base32",
         ),
-        Lib(
-            name="base64",
-        ),
         Lib(
             name="timezone_utils",
         ),
@@ -40,6 +37,7 @@ App(
                 "wolfcrypt/src/sha.c",
                 "wolfcrypt/src/sha256.c",
                 "wolfcrypt/src/sha512.c",
+                "wolfcrypt/src/coding.c",
             ],
             cflags=["-Wno-error"],
             cdefines=["HAVE_CONFIG_H"],

+ 2 - 0
config/wolfssl/config.h

@@ -32,3 +32,5 @@
 #define NO_ERROR_STRINGS
 #define NO_OLD_TLS
 #define SINGLE_THREADED
+#define WORD64_AVAILABLE
+#define WOLF_ALLOW_BUILTIN

+ 0 - 73
lib/base64/base64.c

@@ -1,73 +0,0 @@
-/*
- * Base64 encoding/decoding (RFC1341)
- * Copyright (c) 2005, Jouni Malinen <j@w1.fi>
- * Modified and optimized for Flipepr Zero device purposes by Alex Kopachov (@akopachov)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- */
-
-#include "base64.h"
-#include <string.h>
-
-static const uint8_t dtable[] = {0x3e, 0x80, 0x80, 0x80, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38,
-                                 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x80, 0x80, 0x80, 0x0,  0x80,
-                                 0x80, 0x80, 0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7,
-                                 0x8,  0x9,  0xa,  0xb,  0xc,  0xd,  0xe,  0xf,  0x10, 0x11,
-                                 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x80, 0x80,
-                                 0x80, 0x80, 0x80, 0x80, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-                                 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
-                                 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33};
-
-static uint8_t get_dtable_value(uint8_t index) {
-    return (index < 43 || index > 122) ? 0x80 : dtable[index - 43];
-}
-
-uint8_t* base64_decode(const uint8_t* src, size_t len, size_t* out_len, size_t* out_size) {
-    uint8_t* out;
-    uint8_t* pos;
-    uint8_t in[4];
-    uint8_t block[4];
-    uint8_t tmp;
-    size_t i;
-    size_t count;
-    size_t olen;
-
-    count = 0;
-    for(i = 0; i < len; i++) {
-        if(get_dtable_value(src[i]) != 0x80) count++;
-    }
-
-    if(count == 0 || count % 4) return NULL;
-    olen = count / 4 * 3;
-    pos = out = malloc(olen);
-    *out_size = olen;
-    if(out == NULL) return NULL;
-    count = 0;
-    for(i = 0; i < len; i++) {
-        tmp = get_dtable_value(src[i]);
-        if(tmp == 0x80) continue;
-        in[count] = src[i];
-        block[count] = tmp;
-        count++;
-        if(count == 4) {
-            *pos++ = (block[0] << 2) | (block[1] >> 4);
-            *pos++ = (block[1] << 4) | (block[2] >> 2);
-            *pos++ = (block[2] << 6) | block[3];
-            count = 0;
-        }
-    }
-    if(pos > out) {
-        if(in[2] == '=')
-            pos -= 2;
-        else if(in[3] == '=')
-            pos--;
-    }
-    *out_len = pos - out;
-    return out;
-}

+ 0 - 14
lib/base64/base64.h

@@ -1,14 +0,0 @@
-#pragma once
-
-#include <stdlib.h>
-#include <stdint.h>
-
-/**
- * @brief Decodes Base-64 encoded bytes into plain bytes.
- * @param src Base-64 encoded bytes
- * @param len Base-64 encoded bytes count
- * @param[out] out_len decoded buffer length
- * @param[out] out_size decoded buffer allocated size
- * @return Decoded result buffer if successfully decoded; \c NULL otherwise
- */
-uint8_t* base64_decode(const uint8_t* src, size_t len, size_t* out_len, size_t* out_size);

+ 2 - 2
services/crypto/constants.h

@@ -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)

+ 1 - 2
services/crypto/crypto_v1.c

@@ -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

+ 0 - 1
services/crypto/crypto_v2.c

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

+ 1 - 2
services/crypto/crypto_v3.c

@@ -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;
-}
+}

+ 0 - 14
services/crypto/polyfills.h

@@ -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

+ 7 - 7
services/totp/totp.c

@@ -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]);

+ 12 - 8
types/token_info.c

@@ -1,12 +1,16 @@
 #include "token_info.h"
 #include <furi/core/check.h>
 #include <base32.h>
-#include <base64.h>
+#include "../../config/wolfssl/config.h"
+#include <wolfssl/wolfcrypt/coding.h>
 #include <memset_s.h>
 #include <inttypes.h>
 #include "common.h"
 #include "../services/crypto/crypto_facade.h"
 
+#define ESTIMATE_BASE32_PLAIN_LENGTH(base32_length) ((base32_length) * 0.625f)
+#define ESTIMATE_BASE64_PLAIN_LENGTH(base64_length) ((base64_length) * 0.75f)
+
 TokenInfo* token_info_alloc() {
     TokenInfo* tokenInfo = malloc(sizeof(TokenInfo));
     furi_check(tokenInfo != NULL);
@@ -33,19 +37,19 @@ bool token_info_set_secret(
     size_t plain_secret_length;
     size_t plain_secret_size;
     if(plain_token_secret_encoding == PlainTokenSecretEncodingBase32) {
-        plain_secret_size = token_secret_length;
+        plain_secret_size = ESTIMATE_BASE32_PLAIN_LENGTH(token_secret_length);
         plain_secret = malloc(plain_secret_size);
         furi_check(plain_secret != NULL);
         plain_secret_length =
             base32_decode((const uint8_t*)plain_token_secret, plain_secret, plain_secret_size);
     } else if(plain_token_secret_encoding == PlainTokenSecretEncodingBase64) {
-        plain_secret_length = 0;
-        plain_secret = base64_decode(
-            (const uint8_t*)plain_token_secret,
-            token_secret_length,
-            &plain_secret_length,
-            &plain_secret_size);
+        plain_secret_size = ESTIMATE_BASE64_PLAIN_LENGTH(token_secret_length);
+        plain_secret_length = plain_secret_size;
+        plain_secret = malloc(plain_secret_size);
         furi_check(plain_secret != NULL);
+        if (Base64_Decode((const uint8_t*)plain_token_secret, token_secret_length, plain_secret, &plain_secret_length) != 0) {
+            plain_secret_length = 0;
+        }
     } else {
         return false;
     }