What changed, and why it matters
This commit is a large firmware update for the Keystone 3 hardware wallet, primarily adding a bootloader update mechanism and hardening the USB stack. It introduces a way to overwrite the device's bootloader from a specially formatted region of flash memory, enables hardware-level flash encryption for production builds, and adds many bounds checks and validation routines to the USB device driver to prevent malformed host requests from crashing or confusing the device. The commit also removes the MD5 checksum code entirely and improves I2C and secure-element error handling.
Review the bootloader update protocol for supply-chain and downgrade risks: ensure the embedded bootloader image is signed (not just hashed) and that version anti-rollback checks are enforced before writing. Verify that the AES key/IV read from OTP cannot be extracted by production firmware and that the new USB hardening covers all class drivers. Test the boot-update path against malformed headers, truncated images, and flash-write failures. Confirm removal of MD5 does not break any remaining dependencies.
Security signals we found
New bootloader self-update path from application flash with magic-number header, SHA-256 hash, and CRC32 verification
Flash encryption enabled for production builds using OTP-derived AES-CBC key/IV
USB control endpoint hardening: request length validation, descriptor bounds checks, endpoint address validation, stall-on-invalid requests
USB OUT endpoint receive path hardened against buffer overflows and NULL/oversized transfers
MSC SCSI layer LBA range check fixed to prevent integer overflow/wrap-around
Removal of AUTO_REBOOT_AFTER_COPY_FILE MSC behavior that rebooted device after file copy
I2C HAL now returns ATCA_COMM_FAIL on bus errors instead of ignoring return value
ATECC608B KDF retry loop added for transient secure-element failures
MD5 implementation removed from firmware
Evidence from the diff
The patch adds src/boot_update.c/h implementing UpdateBootFromFlash(), which scans application flash for a magic header (‘mh1903bootupdate’), validates a SHA-256 hash and CRC32 over the embedded bootloader image, and writes it to QSPI flash at 0x01000000. It enables ENABLE_CACHE_AES in mhscpu_qspi.h and adds mhscpu_cache.c plus a production-only mhscpu_qspi.c with AES-CBC flash encryption using keys/IV read from OTP addresses 0x40009128/0x40009138. The USB stack receives extensive hardening: endpoint address validation, control-request length checks, descriptor bounds checking, and stall-on-error behavior in usbd_cdc_core.c, usbd_req.c, usb_dcd.c, usb_dcd_int.c, and usb_core.c. The MSC SCSI layer removes an auto-reboot-after-file-copy feature and fixes integer overflow in LBA range checks. I2C send/receive now propagate errors, and ATECC608B KDF operations retry on failure. MD5 implementation files are deleted.
Changed components
src/boot_update.c/hsrc/config/version.c/hsrc/driver/drv_qspi_flash.c/hsrc/driver/drv_atecc608b.cexternal/mh1903_lib/MHSCPU_Driver/src/mhscpu_qspi.cexternal/mh1903_lib/MHSCPU_Driver/src/mhscpu_cache.cexternal/mh1903_lib/MHSCPU_Driver/inc/mhscpu_qspi.hexternal/mh1903_lib/MHSCPU_Driver/src/mh_rand.cexternal/cryptoauthlib/lib/hal/hal_mh1903_i2c.cexternal/mh1903_lib/SCPU_USB_Lib device/core/otg driverssrc/crypto/checksum/md5.c/h (deleted)Inspect captured patch +3369 / −731
diff --git a/external/cryptoauthlib/lib/hal/hal_mh1903_i2c.c b/external/cryptoauthlib/lib/hal/hal_mh1903_i2c.c
index ad6be5e..d8d9d3a 100644
--- a/external/cryptoauthlib/lib/hal/hal_mh1903_i2c.c
+++ b/external/cryptoauthlib/lib/hal/hal_mh1903_i2c.c
@@ -64,7 +64,10 @@ ATCA_STATUS hal_i2c_post_init(ATCAIface iface)
*/
ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t address, uint8_t *txdata, int txlength)
{
- I2CIO_SendData(&g_i2cIoCfg, address >> 1, txdata, txlength);
+ int32_t ret = I2CIO_SendData(&g_i2cIoCfg, address >> 1, txdata, txlength);
+ if (ret != 0) {
+ return ATCA_COMM_FAIL;
+ }
return ATCA_SUCCESS;
}
@@ -79,7 +82,10 @@ ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t address, uint8_t *txdata, int
*/
ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t address, uint8_t *rxdata, uint16_t *rxlength)
{
- I2CIO_ReceiveData(&g_i2cIoCfg, address >> 1, rxdata, *rxlength);
+ int32_t ret = I2CIO_ReceiveData(&g_i2cIoCfg, address >> 1, rxdata, *rxlength);
+ if (ret != 0) {
+ return ATCA_COMM_FAIL;
+ }
return ATCA_SUCCESS;
}
diff --git a/external/mh1903_lib/MHSCPU_Driver/inc/mhscpu_qspi.h b/external/mh1903_lib/MHSCPU_Driver/inc/mhscpu_qspi.h
index 03bc090..bf7e22b 100644
--- a/external/mh1903_lib/MHSCPU_Driver/inc/mhscpu_qspi.h
+++ b/external/mh1903_lib/MHSCPU_Driver/inc/mhscpu_qspi.h
@@ -179,7 +179,7 @@ typedef struct {
-#define ENABLE_CACHE_AES 0
+#define ENABLE_CACHE_AES 1
void QSPI_Init(QSPI_InitTypeDef *mhqspi);
diff --git a/external/mh1903_lib/MHSCPU_Driver/src/mh_rand.c b/external/mh1903_lib/MHSCPU_Driver/src/mh_rand.c
new file mode 100644
index 0000000..7c9f4a2
--- /dev/null
+++ b/external/mh1903_lib/MHSCPU_Driver/src/mh_rand.c
@@ -0,0 +1,589 @@
+/* srand.c - random operation routines
+ */
+
+#include <math.h>
+#include <stdio.h>
+//#include "mh_crypt_cm3.h"
+#include "mh_rand.h"
+//#include "mh_cephes.h"
+//#include "mh_crypt_config.h"
+#include "mh_misc.h"
+#include "mhscpu.h"
+
+#ifdef __CC_ARM
+#pragma diag_suppress 177
+#endif
+
+const int8_t mh_freq_tab[] = {-8, -6, -6, -4, -6, -4, -4, -2, -6, -4, -4, -2, -4, -2, -2, 0,
+ -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, 0, 2,
+ -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, 0, 2,
+ -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4,
+ -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, 0, 2,
+ -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4,
+ -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4,
+ -2, 0, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6,
+ -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, 0, 2,
+ -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4,
+ -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4,
+ -2, 0, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6,
+ -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4,
+ -2, 0, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6,
+ -2, 0, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6,
+ 0, 2, 2, 4, 2, 4, 4, 6, 2, 4, 4, 6, 4, 6, 6, 8
+ };
+
+double mh_frequency(uint8_t *s, uint32_t n)
+{
+ int i;
+ double s_obs, p_value, sum, sqrt2 = 1.41421356237309504880;
+
+ if (n * 8 < 100)
+ return 0.0;
+
+ sum = 0.0;
+ for (i = 0; i < n; i++)
+ sum += mh_freq_tab[s[i]];
+
+ s_obs = (double)fabs(sum) / (double)sqrt(n * 8) / sqrt2;
+ p_value = erfc(s_obs);
+
+ return p_value;
+}
+
+const int8_t mh_blk_freq_tab[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+ };
+//����û��ʹ��
+double mh_block_frequency(uint8_t *s, uint32_t n)
+{
+// int i, j, N, M;
+// double p_value, sum, pi, v, x_obs;
+//// if (n * 8 < 100)
+//// return 0.0;
+//// //M �� 0.1n
+//// M = n * 8 / 10 / 8 * 8;
+//// //N = n / M
+//// N = n * 8 / M;
+//
+//// sum = 0.0;
+//
+//// for ( i=0; i<N; i++ )
+//// {
+//// pi = 0;
+//// for (j=0; j<M/8; j++)
+//// pi += (double)mh_blk_freq_tab[s[i*(M/8)+j]];
+//// pi = pi/(double)M;
+//// v = pi-0.5;
+//// sum += v*v;
+//// }
+//// x_obs = 4.0 * M * sum;
+//// p_value = mh_cephes_igamc(N/2.0, x_obs/2.0);
+//
+// return p_value;
+ return 0;
+}
+
+const int8_t mh_runs_tab[] = {0, 1, 2, 1, 2, 3, 2, 1, 2, 3, 4, 3, 2, 3, 2, 1,
+ 2, 3, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 3, 2, 1,
+ 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 4, 3,
+ 2, 3, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 3, 2, 1,
+ 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 4, 3,
+ 4, 5, 6, 5, 6, 7, 6, 5, 4, 5, 6, 5, 4, 5, 4, 3,
+ 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 4, 3,
+ 2, 3, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 3, 2, 1,
+ 1, 2, 3, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 3, 2,
+ 3, 4, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 4, 3, 2,
+ 3, 4, 5, 4, 5, 6, 5, 4, 5, 6, 7, 6, 5, 6, 5, 4,
+ 3, 4, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 4, 3, 2,
+ 1, 2, 3, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 3, 2,
+ 3, 4, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 4, 3, 2,
+ 1, 2, 3, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 3, 2,
+ 1, 2, 3, 2, 3, 4, 3, 2, 1, 2, 3, 2, 1, 2, 1, 0
+ };
+
+
+double mh_runs(uint8_t *s, uint32_t n)
+{
+ int S, i, N = (n * 8);
+ double pi, V, x_obs, p_value;
+
+ if (n * 8 < 100)
+ return 0.0;
+
+ S = 0;
+ for (i = 0; i < n; i++)
+ S += mh_blk_freq_tab[s[i]];
+ pi = (double)S / (double)N;
+
+ if (fabs(pi - 0.5) > (2.0 / sqrt(N))) {
+ p_value = 0.0;
+ } else {
+ V = 0;
+
+ for (i = 0; i < n; i++) {
+ V += mh_runs_tab[s[i]];
+ if (i < n - 1)
+ if (((s[i] & 0x80) && !(s[i + 1] & 0x01)) || (!(s[i] & 0x80) && (s[i + 1] & 0x01)))
+ V++;
+ }
+ x_obs = fabs(V - 2.0 * N * pi * (1 - pi)) / (2.0 * pi * (1 - pi) * sqrt(2 * N));
+ p_value = erfc(x_obs);
+ }
+
+ return p_value;
+}
+
+const int8_t mh_longest_run_tab[] = {0, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4,
+ 1, 1, 1, 2, 1, 1, 2, 3, 2, 2, 2, 2, 3, 3, 4, 5,
+ 1, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4,
+ 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 5, 6,
+ 1, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4,
+ 1, 1, 1, 2, 1, 1, 2, 3, 2, 2, 2, 2, 3, 3, 4, 5,
+ 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7,
+ 1, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4,
+ 1, 1, 1, 2, 1, 1, 2, 3, 2, 2, 2, 2, 3, 3, 4, 5,
+ 1, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4,
+ 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 5, 6,
+ 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 4,
+ 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 3, 4, 5,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8
+ };
+//����û��ʹ��
+//double mh_longest_run_of_ones(uint8_t *s, uint32_t N)
+//{
+// double p_value, chi2, pi[7];
+// int v_n_obs, n, i, j, K, M, V[7];
+// unsigned int nu[7] = { 0, 0, 0, 0, 0, 0, 0 };
+
+// K = 3;
+// M = 8;
+// V[0] = 1; V[1] = 2; V[2] = 3; V[3] = 4;
+// pi[0] = 0.21484375;
+// pi[1] = 0.3671875;
+// pi[2] = 0.23046875;
+// pi[3] = 0.1875;
+
+// n = N * M;
+
+// if (6272 <= n || n < 128)
+// return 0.0;
+
+// for ( i=0; i<N; i++ ) {
+// v_n_obs = mh_longest_run_tab[s[i]];
+// if ( v_n_obs < V[0] )
+// nu[0]++;
+// for ( j=0; j<=K; j++ )
+// {
+// if ( v_n_obs == V[j] )
+// nu[j]++;
+// }
+// if ( v_n_obs > V[K] )
+// nu[K]++;
+// }
+
+// chi2 = 0.0;
+// for ( i=0; i<=K; i++ )
+// chi2 += ((nu[i] - N * pi[i]) * (nu[i] - N * pi[i])) / (N * pi[i]);
+
+// p_value = mh_cephes_igamc((double)(K/2.0), chi2 / 2.0);
+
+// return p_value;
+//}
+
+
+uint32_t mh_rand_check(void *rand, uint32_t bytes)
+{
+ uint32_t ret = MH_RET_RAND_CHECK_SUCCESS;
+ if (6272 <= bytes * 8 || bytes * 8 < 128)
+ ret = MH_RET_RAND_CHECK_DATA_LENGTH_ERROR;
+
+#ifdef MH_RAND_USE_CHECK_FREQUENCY
+ if (ret == MH_RET_RAND_CHECK_SUCCESS)
+ if (mh_frequency((uint8_t*)rand, bytes) < 0.01)
+ ret = MH_RET_RAND_CHECK_FAILURE;
+#endif
+
+#ifdef MH_RAND_USE_CHECK_BLOCK_FREQUENCY
+ if (ret == MH_RET_RAND_CHECK_SUCCESS)
+ if (mh_block_frequency((uint8_t*)rand, bytes) < 0.01)
+ ret = MH_RET_RAND_CHECK_FAILURE;
+#endif
+
+#ifdef MH_RAND_USE_CHECK_RUNS
+ if (ret == MH_RET_RAND_CHECK_SUCCESS)
+ if (mh_runs((uint8_t*)rand, bytes) < 0.01)
+ ret = MH_RET_RAND_CHECK_FAILURE;
+#endif
+
+//#ifdef MH_RAND_USE_CHECK_LONGEST_RUN
+// if (ret == MH_RET_RAND_CHECK_SUCCESS)
+// if (mh_longest_run_of_ones((uint8_t*)rand, bytes) < 0.01)
+// ret = MH_RET_RAND_CHECK_FAILURE;
+//#endif
+
+ return ret;
+}
+
+#define MH_RAND_BUFFER_SIZE 256
+#define MH_RAND_BUFFER_INITED (0x5A5A5A5A)
+#define MH_RAND_BUFFER_ATTACKED (0xA5A5A5A5)
+
+typedef struct RingBuffer {
+ uint32_t buf[MH_RAND_BUFFER_SIZE];
+ uint32_t put_index, get_index;
+ volatile uint32_t count;
+ uint32_t inited;
+ uint32_t attacked;
+} RingBufferTypeDef;
+
+void mh_trand_buf_init(RingBufferTypeDef * buf);
+uint32_t mh_trand_buf_put(RingBufferTypeDef * buf, void *rand, uint32_t size);
+
+RingBufferTypeDef g_trng_buf = {0};
+
+void mh_trand_buf_init(RingBufferTypeDef *buf)
+{
+ memset(buf->buf, 0, sizeof(buf->buf));
+ buf->get_index = 0;
+ buf->put_index = 0;
+ buf->count = 0;
+ buf->inited = MH_RAND_BUFFER_INITED;
+ buf->attacked = 0;
+}
+
+
+
+#define MH_RAND_USE_TRNG 1
+
+/************ bit definition for TRNG RNG_AMA REGISTER ************/
+#define MH_TRNG_RNG_AMA_PD_TRNG0_Pos (12)
+#define MH_TRNG_RNG_AMA_PD_TRNG0_Mask (0x0FU<<MH_TRNG_RNG_AMA_PD_TRNG0_Pos)
+
+
+/************ bit definition for TRNG RNG_CSR REGISTER ************/
+#define MH_TRNG_RNG0_CSR_S128_Pos (0)
+#define MH_TRNG_RNG0_CSR_S128_Mask (0x01U<<MH_TRNG_RNG0_CSR_S128_Pos)
+
+#define MH_TRNG_RNG0_CSR_ATTACK_Pos (2)
+#define MH_TRNG_RNG0_CSR_ATTACK_Mask (0x01U<<MH_TRNG_RNG0_CSR_ATTACK_Pos)
+
+#define MH_TRNG_RNG_CSR_INTP_EN_Pos (4)
+#define MH_TRNG_RNG_CSR_INTP_EN_Mask (0x01U<<MH_TRNG_RNG_CSR_INTP_EN_Pos)
+
+typedef struct {
+ volatile uint32_t RNG_CSR;
+ volatile uint32_t RNG0_DATA;
+ volatile uint32_t rsvd;
+ volatile uint32_t RNG_AMA;
+ volatile uint32_t RNG_PN;
+} mh_trng_type_def;
+
+
+#define MH_TRNG ((mh_trng_type_def *)(0x4001E000UL))
+#define MH_TRNG_WORDS (4)
+#define MH_TRNG_BYTES (MH_TRNG_WORDS*4)
+
+
+
+__STATIC_INLINE void mh_trand_init(void)
+{
+ MH_TRNG->RNG_CSR |= 0x10; //ʹ���ж�
+ MH_TRNG->RNG_AMA &= ~TRNG_RNG_AMA_PD_ALL_Mask;
+
+}
+
+__STATIC_INLINE void mh_trand_start(void)
+{
+ MH_TRNG->RNG_CSR &= ~MH_TRNG_RNG0_CSR_S128_Mask;
+
+}
+
+__STATIC_INLINE uint32_t mh_trand_get(uint32_t rand[4])
+{
+ uint32_t ret;
+
+ /*
+ * check until the random number has been generated
+ */
+ while (!(MH_TRNG->RNG_CSR & MH_TRNG_RNG0_CSR_S128_Mask));
+ /*
+ * check if the TRNG is attacked
+ */
+ if (MH_TRNG->RNG_CSR & MH_TRNG_RNG0_CSR_ATTACK_Mask) {
+ ret = 0;
+ goto cleanup;
+ }
+ /*
+ * copy random number to RNG_Buf
+ */
+ rand[0] = MH_TRNG->RNG0_DATA;
+ rand[1] = MH_TRNG->RNG0_DATA;
+ rand[2] = MH_TRNG->RNG0_DATA;
+ rand[3] = MH_TRNG->RNG0_DATA;
+
+ ret = sizeof(uint32_t) * 4;
+
+cleanup:
+ return ret;
+
+}
+
+
+uint32_t mh_trand_polling(void *rand, uint32_t bytes)
+{
+ uint32_t ret = 0;
+ uint32_t m, r, i, check;
+ uint8_t *_rand = (uint8_t *)rand;
+ uint32_t rand_buf[4];
+
+ memset(rand, 0, bytes);
+
+ m = bytes / MH_TRNG_BYTES;
+ r = bytes % MH_TRNG_BYTES;
+ if (r)
+ m++;
+
+ mh_trand_init();
+ mh_trand_start();
+
+ for (i = 0, check = 0; i < m; i++) {
+ if (i != check) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (0 == mh_trand_get(rand_buf)) {
+ ret = 0;
+ goto cleanup;
+ }
+ mh_trand_start();
+
+ if (i < (m - 1)) {
+ memcpy(_rand, &rand_buf[0], sizeof(rand_buf));
+ _rand = _rand + sizeof(rand_buf);
+ ret += sizeof(rand_buf);
+ } else if (r == 0) {
+ memcpy(_rand, &rand_buf[0], sizeof(rand_buf));
+ _rand = _rand + sizeof(rand_buf);
+ ret += sizeof(rand_buf);
+ } else {
+ memcpy(_rand, &rand_buf[0], r);
+ ret += r;
+ }
+
+ check++;
+ }
+
+cleanup:
+ if (ret != bytes) {
+ memset(rand, 0, bytes);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+
+uint32_t mh_trand_buf_attack_get(RingBufferTypeDef * buf)
+{
+ if (buf->attacked == MH_RAND_BUFFER_ATTACKED)
+ return 1;
+ else
+ return 0;
+}
+
+void mh_trand_buf_attack_clean(RingBufferTypeDef * buf)
+{
+ buf->attacked = 0;
+}
+
+uint32_t mh_trand_buf_count(RingBufferTypeDef * buf)
+{
+ return buf->count;
+}
+
+//static uint32_t mh_trand_buf_get()
+//{
+// uint32_t r;
+//
+// if (g_trng_buf.count == 0) {
+// NVIC_EnableIRQ(TRNG_IRQn);
+// }
+// while (g_trng_buf.count == 0) {
+// }
+// r = g_trng_buf.buf[g_trng_buf.get_index++];
+// if (g_trng_buf.get_index >= MH_RAND_BUFFER_SIZE) {
+// g_trng_buf.get_index = 0;
+// }
+// NVIC_DisableIRQ(TRNG_IRQn);
+// g_trng_buf.count--;
+// NVIC_EnableIRQ(TRNG_IRQn);
+//
+// return r;
+//}
+
+typedef struct trng_ext_buf_s {
+ int len;
+ unsigned char buf[32];
+} trng_ext_buf;
+
+trng_ext_buf g_trng_ext_buf = {0};
+
+uint32_t mh_trand(void *rand, uint32_t bytes)
+{
+ uint32_t rbytes = 0;
+ uint32_t _bytes = bytes;
+// int n = 0;
+ typedef union dword_u {
+ uint32_t n;
+ uint8_t c[4];
+ } dword;
+ dword *p = (dword *)rand;
+
+
+ if (mh_trand_buf_attack_get(&g_trng_buf)) {
+ rbytes = 0;
+ goto cleanup;
+ }
+ if (g_trng_buf.count == 0) {
+ mh_trand_init();
+ NVIC_EnableIRQ(TRNG_IRQn);
+ }
+ do {
+ //printf("wait...\n");
+ while (g_trng_buf.count == 0);
+ //printf("bytes = %d\n", bytes);
+ while (_bytes >= 4 && g_trng_buf.count) {
+ p->n = g_trng_buf.buf[g_trng_buf.get_index++];
+ g_trng_buf.get_index %= MH_RAND_BUFFER_SIZE;
+ NVIC_DisableIRQ(TRNG_IRQn);
+ g_trng_buf.count--;
+ NVIC_EnableIRQ(TRNG_IRQn);
+ _bytes -= 4;
+ rbytes += 4;
+ p++;
+ }
+ if (_bytes < 4 && g_trng_buf.count) {
+ unsigned char *pbyte = (unsigned char *)(g_trng_buf.buf + g_trng_buf.get_index);
+ int i = 0;
+
+ //printf("tail:%08X\n", g_trng_buf.buf[g_trng_buf.get_index]);
+ g_trng_buf.get_index++;
+ for (i = 0; i < _bytes; i++) {
+ p->c[i] = *pbyte++;
+ rbytes++;
+ }
+ _bytes = 0;
+ g_trng_buf.get_index %= MH_RAND_BUFFER_SIZE;
+
+ NVIC_DisableIRQ(TRNG_IRQn);
+ g_trng_buf.count--;
+ NVIC_EnableIRQ(TRNG_IRQn);
+ }
+ } while (_bytes > 0);
+
+cleanup:
+ if (rbytes != bytes) {
+ memset(rand, 0, bytes);
+ rbytes = 0;
+ }
+
+ return rbytes;
+}
+
+//extern uint32_t g_count;
+
+uint32_t mh_frand(void *rand, uint32_t bytes)
+{
+ uint32_t i;
+
+ for (i = 0; i < bytes; i++) {
+ if (i % 2)
+ ((uint8_t*)rand)[i] = (MH_TRNG->RNG_PN) & 0xFF;
+ else
+ ((uint8_t*)rand)[i] = ((MH_TRNG->RNG_PN) >> 3) & 0xFF;
+ }
+ return i;
+}
+
+
+
+uint32_t mh_rand(void *rand, uint32_t bytes)
+{
+ //memset(rand, 0x18, bytes);
+
+ //return bytes;
+#if MH_RAND_USE_TRNG
+ return mh_trand(rand, bytes);
+// return mh_trand_polling(rand, bytes);
+#else
+ return mh_frand(rand, bytes);
+#endif
+}
+
+/*
+void TRNG_ClearITPendingBit(uint32_t TRNG_IT)
+{
+ MH_TRNG->RNG_CSR &= ~TRNG_IT;
+}
+*/
+#define TRNG_IT_RNG0_S128 ((uint32_t)0x00000001)
+
+void TRNG_IRQHandler(void)
+{
+ int i;
+ /***************************************
+ * check if the TRNG is attacked
+ **************************************/
+ if ((MH_TRNG->RNG_CSR & MH_TRNG_RNG0_CSR_ATTACK_Mask)) {
+ g_trng_buf.attacked = MH_RAND_BUFFER_ATTACKED;
+ } else {
+ volatile uint32_t *p = &MH_TRNG->RNG0_DATA;
+ for (i = 0; i < 4; i ++) {
+ if (g_trng_buf.count < MH_RAND_BUFFER_SIZE) {
+ g_trng_buf.buf[g_trng_buf.put_index++] = *p;
+ if (g_trng_buf.put_index >= MH_RAND_BUFFER_SIZE) {
+ g_trng_buf.put_index = 0;
+ }
+ g_trng_buf.count++;
+ }
+ }
+ TRNG_ClearITPendingBit(TRNG_IT_RNG0_S128);
+ if (g_trng_buf.count == MH_RAND_BUFFER_SIZE) {
+ NVIC_DisableIRQ(TRNG_IRQn);
+ }
+ }
+// printf("come into trand interrupt\n");
+// TRNG_ClearITPendingBit(TRNG_IT_RNG0_S128);
+}
+
+uint32_t mh_rand_init(void)
+{
+ mh_trand_buf_init(&g_trng_buf);
+ mh_trand_init();
+ mh_trand_start();
+ return 0;
+}
+
+uint32_t mh_rand_p(void *rand, uint32_t bytes, void *p_rng)
+{
+ //memset(rand, 0x01, bytes);
+ //return bytes;
+ return mh_rand(rand, bytes);
+}
diff --git a/external/mh1903_lib/MHSCPU_Driver/src/mhscpu_cache.c b/external/mh1903_lib/MHSCPU_Driver/src/mhscpu_cache.c
new file mode 100644
index 0000000..070b7c9
--- /dev/null
+++ b/external/mh1903_lib/MHSCPU_Driver/src/mhscpu_cache.c
@@ -0,0 +1,91 @@
+/************************ (C) COPYRIGHT Megahuntmicro *************************
+ * @file : mhscpu_cache.c
+ * @author : Megahuntmicro
+ * @version : V1.0.0
+ * @date : 21-October-2014
+ * @brief : This file provides all the CACHE firmware functions
+ *****************************************************************************/
+
+/* Includes ----------------------------------------------------------------*/
+#include "mhscpu_cache.h"
+
+
+void CACHE_Init(CACHE_TypeDef *Cache, CACHE_InitTypeDef *CACHE_InitStruct)
+{
+ int i;
+
+ if (CACHE_InitStruct->aes_enable == ENABLE) {
+ assert_param(IS_CACHE_ENCRYPT_MODE(CACHE_InitStruct->encrypt_mode));
+
+ for (i = 0; i < 5000; i++) {
+ if (Cache->CACHE_AES_CS & CACHE_IS_BUSY) { //cache���ڴ�Flash��ȡָ
+ continue;
+ }
+ break;
+ }
+ Cache->CACHE_AES_CS = (Cache->CACHE_AES_CS & ~0xFF) | CACHE_KEY_GEN; //AES��Կ����ģʽ
+
+ Cache->CACHE_AES_I3 = CACHE_InitStruct->I[3];
+ Cache->CACHE_AES_I2 = CACHE_InitStruct->I[2];
+ Cache->CACHE_AES_I1 = CACHE_InitStruct->I[1];
+ Cache->CACHE_AES_I0 = CACHE_InitStruct->I[0];
+
+ Cache->CACHE_AES_K3 = CACHE_InitStruct->K[3];
+ Cache->CACHE_AES_K2 = CACHE_InitStruct->K[2];
+ Cache->CACHE_AES_K1 = CACHE_InitStruct->K[1];
+ Cache->CACHE_AES_K0 = CACHE_InitStruct->K[0];
+
+ Cache->CACHE_AES_CS |= CACHE_KEY_GEN_START;
+ for (i = 0; i < 5000; i++) {
+ if ((Cache->CACHE_AES_CS & CACHE_KEY_GEN_START) == 0) {
+ Cache->CACHE_AES_CS = 0x0;
+ break;
+ }
+ }
+ Cache->CACHE_AES_CS = 0;
+ Cache->CACHE_CONFIG = (Cache->CACHE_CONFIG & ~0xFF00FFFF);
+
+ if (CACHE_Encrypt_Mode_Zone == CACHE_InitStruct->encrypt_mode) {
+ uint32_t saddr_align = CACHE_InitStruct->encrypt_saddr & ~(CACHE_PARTICLE_SIZE - 1);
+ uint32_t eaddr_align = CACHE_InitStruct->encrypt_eaddr & ~(CACHE_PARTICLE_SIZE - 1);
+
+ assert_param(IS_CACHE_ADDR_VALID(saddr_align));
+ assert_param(IS_CACHE_ADDR_VALID(eaddr_align));
+ assert_param(saddr_align <= eaddr_align);
+
+ Cache->CACHE_SADDR = saddr_align;
+ Cache->CACHE_EADDR = eaddr_align;
+ Cache->CACHE_CONFIG = (Cache->CACHE_CONFIG & ~0xFF000000) | CACHE_ZONE_ENCRYPT;
+ }
+ } else {
+ Cache->CACHE_CONFIG = (Cache->CACHE_CONFIG & ~0xFF00FFFF) | CACHE_AES_BYPASS;
+ }
+
+}
+
+/*clean cache flash data/instructions*/
+void CACHE_Clean(CACHE_TypeDef *Cache, CACHE_InitTypeDef *CACHE_InitStruct)
+{
+ uint32_t i, address;
+ address = (CACHE_InitStruct->Address & ~(CACHE_PARTICLE_SIZE - 1)) & CACHE_ADDRESS_MAX;
+
+ for (i = 0; i < CACHE_InitStruct->size; i += CACHE_PARTICLE_SIZE) {
+ //flush cache line
+ Cache->CACHE_REF = (address + i);
+ Cache->CACHE_REF |= CACHE_REFRESH;
+ while ((Cache->CACHE_REF & CACHE_REFRESH));
+ }
+}
+
+void CACHE_CleanAll(CACHE_TypeDef *Cache)
+{
+ //flush cache all
+ while (Cache->CACHE_AES_CS & CACHE_IS_BUSY);
+
+ Cache->CACHE_REF = CACHE_REFRESH_ALLTAG;
+ Cache->CACHE_REF |= CACHE_REFRESH;
+ while ((Cache->CACHE_REF & CACHE_REFRESH));
+}
+
+
+/************************** (C) COPYRIGHT Megahunt *****END OF FILE****/
diff --git a/external/mh1903_lib/MHSCPU_Driver/src/mhscpu_qspi.c b/external/mh1903_lib/MHSCPU_Driver/src/mhscpu_qspi.c
new file mode 100644
index 0000000..6ddda07
--- /dev/null
+++ b/external/mh1903_lib/MHSCPU_Driver/src/mhscpu_qspi.c
@@ -0,0 +1,1130 @@
+#ifdef BUILD_PRODUCTION
+/************************ (C) COPYRIGHT Megahuntmicro *************************
+ * @file : mhscpu_qspi.c
+ * @author : Megahuntmicro
+ * @version : V1.0.0
+ * @date : 21-October-2014
+ * @brief : This file provides all the QSPI firmware functions
+ *****************************************************************************/
+
+/* Includes ----------------------------------------------------------------*/
+#include <stdlib.h>
+#include <string.h>
+#include "mhscpu.h"
+#include "mhscpu_cache.h"
+#include "mhscpu_qspi.h"
+#include "mhscpu_dma.h"
+#include "stdio.h"
+#include "log_print.h"
+#include "user_delay.h"
+#include "mh_aes.h"
+#include "mh_rand.h"
+#include "assert.h"
+#include "ctaes.h"
+#include "user_utils.h"
+#include "mhscpu_conf.h"
+
+#define QSPI_DEVICE_PARA_FLASH_READY_Mask (BIT(3))
+
+
+typedef enum {
+ MH_OK = 0x00,
+ MH_ERROR = 0x01,
+ MH_BUSY = 0x02,
+ MH_TIMEOUT = 0x03
+} MH_StatusTypeDef;
+
+typedef struct {
+ uint8_t Instruction;
+ QSPI_BusModeTypeDef BusMode;
+ QSPI_CmdFormatTypeDef CmdFormat;
+ uint32_t Address;
+
+ uint32_t WrData;
+ uint32_t RdData;
+
+} MH_CommandTypeDef;
+
+
+//命令完成中断标志置位的最大是就是编程命令耗时
+//(PP_CMD(1B) + PP_ADDR(3B) + PP_MAX_BYTES(256B) + Cache_line(32B) + Cache_CMD(1B)+Cache_ADDR(3B)) * 8(bits) * 8(CPU主频最大是QSPI频率的8倍)
+//(1+ 3 + 256 + 32 + 1 + 3) * 8 * 8
+#define MH_QSPI_TIMEOUT_DEFAULT_CNT (19000) //18944
+
+#define MH_QSPI_ACCESS_REQ_ENABLE (0x00000001U)
+#define MH_QSPI_FLASH_READY_ENABLE (0x0000006BU)
+
+
+#define IS_PARAM_NOTNULL(PARAM) ((PARAM) != NULL)
+
+#define IS_QSPI_ADDR(ADDR) ((((int32_t)(ADDR) ) >= (uint32_t)(0x00000000)) &&\
+ (((int32_t)(ADDR) ) <= (uint32_t)(0x00FFFFFF)))
+
+#define IS_QSPI_ADDR_ADD_SZ(ADDR, SZ) ((((int32_t)((ADDR) + (SZ))) >= (uint32_t)(0x00000000)) && \
+ (((int32_t)((ADDR) + (SZ))) <= (uint32_t)(0x01000000)))
+
+
+static bool EncryptedFlash(void);
+
+
+static void delay_40ms(void)
+{
+ int i, j;
+ for (i = 7; i > 0; i --)
+ for (j = SYSCTRL->HCLK_1MS_VAL; j > 0; j --);
+}
+
+static MH_StatusTypeDef MH_QSPI_Command(MH_CommandTypeDef *cmd, int32_t timeout)
+{
+ //int32_t i;
+ MH_StatusTypeDef status = MH_ERROR;
+
+ assert_param(IS_PARAM_NOTNULL(cmd));
+
+ MHSCPU_MODIFY_REG32(&(QSPI->REG_WDATA), (QUADSPI_REG_WDATA), (cmd->WrData));
+ MHSCPU_MODIFY_REG32(&(QSPI->ADDRES), (QUADSPI_ADDRESS_ADR), (cmd->Address << 8));
+ MHSCPU_MODIFY_REG32(&(QSPI->FCU_CMD),
+ (QUADSPI_FCU_CMD_CODE | QUADSPI_FCU_CMD_BUS_MODE | QUADSPI_FCU_CMD_CMD_FORMAT | QUADSPI_FCU_CMD_ACCESS_REQ),
+ (((uint32_t)(cmd->Instruction << 24)) | ((uint32_t)(cmd->BusMode << 8)) | ((uint32_t)(cmd->CmdFormat << 4)) | (MH_QSPI_ACCESS_REQ_ENABLE)));
+
+ //Wait For CMD done
+ //for (i = 0; i < timeout; i += 4) {
+ //i = 0;
+ while (1) {
+ if (QSPI->INT_RAWSTATUS & QUADSPI_INT_RAWSTATUS_DONE_IR) {
+ QSPI->INT_CLEAR = QUADSPI_INT_CLEAR_DONE;
+ status = MH_OK;
+ break;
+ }
+ UserDelayUs(20);
+ }
+
+ MHSCPU_WRITE_REG32(&(cmd->RdData), QSPI->REG_RDATA);
+ return status;
+}
+
+static QSPI_StatusTypeDef QSPI_WriteEnable(QSPI_BusModeTypeDef bus_mode)
+{
+ MH_CommandTypeDef sCommand = {0};
+
+ sCommand.Instruction = WRITE_ENABLE_CMD;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8;
+
+ if (QSPI_BUSMODE_444 == bus_mode) {
+ sCommand.BusMode = QSPI_BUSMODE_444;
+ } else {
+ sCommand.BusMode = QSPI_BUSMODE_111;
+ }
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ return QSPI_STATUS_OK;
+}
+
+//PP,QPP,Sector Erase,Block Erase, Chip Erase, Write Status Reg, Erase Security Reg
+static QSPI_StatusTypeDef QSPI_IsBusy(QSPI_BusModeTypeDef bus_mode)
+{
+ MH_CommandTypeDef sCommand = {0};
+
+ sCommand.Instruction = READ_STATUS_REG1_CMD;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_RREG8;
+
+ if (QSPI_BUSMODE_444 == bus_mode) {
+ sCommand.BusMode = QSPI_BUSMODE_444;
+ } else {
+ sCommand.BusMode = QSPI_BUSMODE_111;
+ }
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ if (sCommand.RdData & BIT0) {
+ return QSPI_STATUS_ERROR;
+ }
+ return QSPI_STATUS_OK;
+}
+
+#define MAX_RD_DATA_LEN 0x10
+#define MAX_WR_DATA_LEN 0x04
+
+uint8_t QSPI_Read(QSPI_CommandTypeDef *cmdParam, uint8_t* buf, uint32_t addr, uint32_t sz)
+{
+ uint32_t read_times = 0, i = 0, j = 0, rxCount = 0;
+ uint8_t end_len = 0;
+ MH_CommandTypeDef sCommand = {0};
+
+ while (CACHE->CACHE_AES_CS & CACHE_IS_BUSY);
+
+ addr &= (uint32_t)(0x00FFFFFF);
+ assert_param(IS_QSPI_ADDR(addr));
+ assert_param(IS_QSPI_ADDR_ADD_SZ(addr, sz));
+
+ if (cmdParam == NULL) {
+ sCommand.Instruction = READ_CMD;
+ sCommand.BusMode = QSPI_BUSMODE_111;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24_RDAT;
+ } else {
+ sCommand.Instruction = cmdParam->Instruction;
+ sCommand.BusMode = cmdParam->BusMode;
+ sCommand.CmdFormat = cmdParam->CmdFormat;
+ }
+
+ read_times = sz / MAX_RD_DATA_LEN;
+ end_len = sz % MAX_RD_DATA_LEN;
+
+ for (i = 0; i < read_times; i ++) {
+ QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_RFFH;
+ QSPI->BYTE_NUM = MAX_RD_DATA_LEN;
+
+ sCommand.Address = addr;
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ rxCount = (QSPI->FIFO_CNTL & 0x7);
+ for (j = 0; j < rxCount; j++) {
+ *(uint32_t *)(buf) = QSPI->RD_FIFO;
+ buf += 4;
+ }
+
+ addr += MAX_RD_DATA_LEN;
+ }
+
+ QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_RFFH;
+ sCommand.Address = addr;
+ if (end_len > 0) {
+ QSPI->BYTE_NUM = end_len;
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ rxCount = (QSPI->FIFO_CNTL & 0x7);
+ for (j = 0; j < rxCount; j++) {
+ *(uint32_t *)(buf) = QSPI->RD_FIFO;
+ buf += 4;
+ }
+ }
+
+ return QSPI_STATUS_OK;
+}
+
+
+static uint8_t QSPI_ProgramPage_Ex(QSPI_CommandTypeDef *cmdParam, uint32_t adr, uint32_t sz, uint8_t *buf)
+{
+ uint32_t i, j;
+ uint32_t end_addr, current_size, current_addr, current_dat, loop_addr;
+ MH_CommandTypeDef sCommand = {0};
+
+ adr &= (uint32_t)0x00FFFFFF;
+ assert_param(IS_QSPI_ADDR(adr));
+ assert_param(IS_QSPI_ADDR_ADD_SZ(adr, sz));
+
+ current_addr = 0;
+
+ while (current_addr <= adr) {
+ current_addr += X25Q_PAGE_SIZE;
+ }
+ current_size = current_addr - adr;
+
+ /* Check if the size of the data is less than the remaining place in the page */
+ if (current_size > sz) {
+ current_size = sz;
+ }
+
+ /* Initialize the adress variables */
+ current_addr = adr;
+ loop_addr = adr;
+ end_addr = adr + sz;
+
+ QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_TFFH;
+ QSPI->BYTE_NUM = MAX_WR_DATA_LEN << 16;
+ sCommand.Address = current_addr;
+
+ if (cmdParam == NULL) {
+ sCommand.Instruction = QUAD_INPUT_PAGE_PROG_CMD;
+ sCommand.BusMode = QSPI_BUSMODE_114;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24_PDAT;
+ } else {
+ sCommand.Instruction = cmdParam->Instruction;
+ sCommand.BusMode = cmdParam->BusMode;
+ sCommand.CmdFormat = cmdParam->CmdFormat;
+ }
+
+ do {
+ QSPI->BYTE_NUM = MAX_WR_DATA_LEN << 16;
+
+ for (i = 0; i < (current_size / MAX_WR_DATA_LEN); i++) {
+ QSPI->WR_FIFO = (*(buf + 3) << 24) | (*(buf + 2) << 16) | (*(buf + 1) << 8) | (*(buf + 0));
+
+ if (QSPI_WriteEnable(sCommand.BusMode) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ while (QSPI_IsBusy(sCommand.BusMode));
+
+ QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_TFFH;
+ buf += 4;
+
+ current_addr += MAX_WR_DATA_LEN;
+ sCommand.Address = current_addr;
+ }
+
+ if (current_size % MAX_WR_DATA_LEN > 0) {
+ current_dat = 0;
+ QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_TFFH;
+
+ for (j = (current_size % MAX_WR_DATA_LEN); j > 0; j--) {
+ current_dat <<= 8;
+ current_dat |= *(buf + j - 1);
+ }
+
+ QSPI->WR_FIFO = current_dat;
+ QSPI->BYTE_NUM = ((current_size % MAX_WR_DATA_LEN)) << 16;
+
+ if (QSPI_WriteEnable(sCommand.BusMode) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT);
+ while (QSPI_IsBusy(sCommand.BusMode));
+
+ buf += (current_size % MAX_WR_DATA_LEN);
+ sCommand.Address = (current_addr + current_size % MAX_WR_DATA_LEN);
+ }
+
+ loop_addr += current_size;
+ current_addr = loop_addr;
+ current_size = ((loop_addr + X25Q_PAGE_SIZE) > end_addr) ? (end_addr - loop_addr) : X25Q_PAGE_SIZE;
+ } while (loop_addr < end_addr);
+
+ return QSPI_STATUS_OK;
+}
+
+
+#define MAX_RD_DMA_DATA_LEN 0x100
+#define MAX_WR_DMA_DATA_LEN 0x100
+
+static QSPI_StatusTypeDef QSPI_DMA_Configuration(DMA_TypeDef *DMA_Channelx, DMA_InitTypeDef *DMA_InitStruct)
+{
+ DMA_InitStruct->DMA_DIR = DMA_DIR_Memory_To_Peripheral;
+ DMA_InitStruct->DMA_Peripheral = (uint32_t)(QSPI);
+ DMA_InitStruct->DMA_PeripheralBaseAddr = (uint32_t) & (QSPI->WR_FIFO);
+ DMA_InitStruct->DMA_PeripheralInc = DMA_Inc_Nochange;
+ DMA_InitStruct->DMA_PeripheralDataSize = DMA_DataSize_Word;
+ DMA_InitStruct->DMA_PeripheralBurstSize = DMA_BurstSize_4;
+
+ DMA_InitStruct->DMA_MemoryInc = DMA_Inc_Increment;
+ DMA_InitStruct->DMA_MemoryDataSize = DMA_DataSize_Word;
+ DMA_InitStruct->DMA_MemoryBurstSize = DMA_BurstSize_4;
+ DMA_InitStruct->DMA_BlockSize = MAX_WR_DMA_DATA_LEN >> 2;
+ DMA_InitStruct->DMA_PeripheralHandShake = DMA_PeripheralHandShake_Hardware;
+
+ if (DMA_Channelx == DMA_Channel_0) {
+ SYSCTRL->DMA_CHAN = (SYSCTRL->DMA_CHAN & ~0x1F) | 0x1A;
+ } else if (DMA_Channelx == DMA_Channel_1) {
+ SYSCTRL->DMA_CHAN = (SYSCTRL->DMA_CHAN & ~(0x1F << 8)) | (0x1A << 8);
+ } else if (DMA_Channelx == DMA_Channel_2) {
+ SYSCTRL->DMA_CHAN = (SYSCTRL->DMA_CHAN & ~(0x1F << 16)) | (0x1A << 16);
+ } else if (DMA_Channelx == DMA_Channel_3) {
+ SYSCTRL->DMA_CHAN = (SYSCTRL->DMA_CHAN & ~(0x1F << 24)) | (0x1A << 24);
+ } else if (DMA_Channelx == DMA_Channel_5) {
+ SYSCTRL->DMA_CHAN1 = (SYSCTRL->DMA_CHAN1 & ~(0x1F << 8)) | (0x1A << 8);
+ } else if (DMA_Channelx == DMA_Channel_6) {
+ SYSCTRL->DMA_CHAN1 = (SYSCTRL->DMA_CHAN1 & ~(0x1F << 16)) | (0x1A << 16);
+ } else if (DMA_Channelx == DMA_Channel_7) {
+ SYSCTRL->DMA_CHAN1 = (SYSCTRL->DMA_CHAN1 & ~(0x1F << 24)) | (0x1A << 24);
+ } else {
+ return QSPI_STATUS_NOT_SUPPORTED;
+ }
+
+ return QSPI_STATUS_OK;
+}
+
+#if(ENABLE_CACHE_AES)
+
+#define DEBUG_AES 0
+static uint8_t buf_aes_enc(uint8_t *cp_buf, uint32_t sz, uint8_t *sup_buf)
+{
+ AES128_CBC_ctx aesCtx;
+ uint32_t i, k;
+ int32_t j;
+ uint8_t key128[16] = {0};
+ uint8_t iv[16] = {0};
+ uint8_t cipher[32];
+ uint8_t plain[32];
+
+ SYSCTRL_AHBPeriphClockCmd(SYSCTRL_AHBPeriph_OTP, ENABLE);
+ memcpy(key128, (uint32_t *)(0x40009128), 16);
+ memcpy(iv, (uint32_t *)(0x40009138), 16);
+
+ memset(cipher, 0, sizeof(cipher));
+ memset(plain, 0, sizeof(plain));
+
+ for (i = 0; i < sz / 32; i ++) {
+ //memcpy(plain, cp_buf + i * 32, 32);
+ k = 0;
+ for (j = 15; j >= 0; j --) {
+ plain[k] = cp_buf[ i * 32 + j];
+ plain[k + 16] = cp_buf[i * 32 + 16 + j];
+ k += 1;
+ }
+ AES128_CBC_init(&aesCtx, key128, iv);
+ AES128_CBC_encrypt(&aesCtx, 2, cipher, plain);
+
+ k = 0;
+ for (j = 15; j >= 0; j --) {
+ sup_buf[i * 32 + j] = cipher[k];
+ sup_buf[i * 32 + 16 + j] = cipher[k + 16];
+ k += 1;
+ }
+ }
+ return 0;
+}
+#endif
+
+uint8_t QSPI_SoftWareReset(QSPI_BusModeTypeDef BusMode)
+{
+ MH_CommandTypeDef sCommand = {0};;
+
+ sCommand.Instruction = RESET_ENABLE_CMD;
+ sCommand.BusMode = BusMode;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8;
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ sCommand.Instruction = RESET_MEMORY_CMD;
+ sCommand.BusMode = BusMode;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8;
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ delay_40ms();
+
+ return QSPI_STATUS_OK;
+}
+
+uint8_t QSPI_SingleCommand(QSPI_CommandTypeDef *cmdParam)
+{
+ MH_CommandTypeDef sCommand = {0};
+
+ sCommand.Instruction = cmdParam->Instruction;
+ sCommand.BusMode = cmdParam->BusMode;
+ sCommand.CmdFormat = cmdParam->CmdFormat;
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ return QSPI_STATUS_OK;
+}
+
+uint8_t QSPI_DeepPowerDown(QSPI_CommandTypeDef *cmdParam)
+{
+ MH_CommandTypeDef sCommand = {0};
+
+ while (CACHE->CACHE_AES_CS & CACHE_IS_BUSY);
+
+ if (NULL == cmdParam) {
+ sCommand.Instruction = DEEP_POWER_DOWN;
+ sCommand.BusMode = QSPI_BUSMODE_111;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8;
+ } else {
+ sCommand.Instruction = cmdParam->Instruction;
+ sCommand.BusMode = cmdParam->BusMode;
+ sCommand.CmdFormat = cmdParam->CmdFormat;
+ }
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+ return QSPI_STATUS_OK;
+}
+
+uint8_t QSPI_ReleaseDeepPowerDown(QSPI_CommandTypeDef *cmdParam)
+{
+ MH_CommandTypeDef sCommand = {0};
+ uint32_t clock_delay;
+
+ while (CACHE->CACHE_AES_CS & CACHE_IS_BUSY);
+
+ if (NULL == cmdParam) {
+ sCommand.Instruction = RELEASE_FROM_DEEP_POWER_DOWN;
+ sCommand.BusMode = QSPI_BUSMODE_111;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8;
+ } else {
+ sCommand.Instruction = cmdParam->Instruction;
+ sCommand.BusMode = cmdParam->BusMode;
+ sCommand.CmdFormat = cmdParam->CmdFormat;
+ }
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ //防止唤醒期间CACHE访问FLASH导致死机
+ //延时30us
+ for (clock_delay = 0; clock_delay < (SYSCTRL->HCLK_1MS_VAL * 3 / 1000); clock_delay += 4);
+
+ return QSPI_STATUS_OK;
+}
+
+uint32_t QSPI_ReadID(QSPI_CommandTypeDef *cmdParam)
+{
+ MH_CommandTypeDef sCommand = {0};
+
+ while (CACHE->CACHE_AES_CS & CACHE_IS_BUSY);
+ if (cmdParam == NULL) {
+ sCommand.Instruction = READ_JEDEC_ID_CMD;
+ sCommand.BusMode = QSPI_BUSMODE_111;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_RREG24;
+ } else {
+ sCommand.Instruction = cmdParam->Instruction;
+ sCommand.BusMode = cmdParam->BusMode;
+ sCommand.CmdFormat = cmdParam->CmdFormat;
+ }
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ return (sCommand.RdData & 0x00FFFFFF);
+}
+
+uint16_t QSPI_StatusReg(QSPI_CommandTypeDef *cmdParam)
+{
+ MH_CommandTypeDef sCommand = {0};
+
+ assert_param(IS_PARAM_NOTNULL(cmdParam));
+
+ while (CACHE->CACHE_AES_CS & CACHE_IS_BUSY);
+ sCommand.Instruction = cmdParam->Instruction;
+ sCommand.BusMode = cmdParam->BusMode;
+ sCommand.CmdFormat = cmdParam->CmdFormat;
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ return (sCommand.RdData & 0x0000FFFF);
+}
+
+uint8_t QSPI_WriteParam(QSPI_CommandTypeDef *cmdParam, uint16_t wrData)
+{
+ MH_CommandTypeDef sCommand = {0};
+
+ assert_param(IS_PARAM_NOTNULL(cmdParam));
+
+ while (CACHE->CACHE_AES_CS & CACHE_IS_BUSY);
+ sCommand.Instruction = cmdParam->Instruction;
+ sCommand.BusMode = cmdParam->BusMode;
+ sCommand.CmdFormat = cmdParam->CmdFormat;
+ sCommand.WrData = wrData;
+
+ if (QSPI_WriteEnable(sCommand.BusMode) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+ while (QSPI_IsBusy(sCommand.BusMode));
+
+ return QSPI_STATUS_OK;
+}
+
+uint8_t QSPI_EraseSector(QSPI_CommandTypeDef *cmdParam, uint32_t SectorAddress)
+{
+ MH_CommandTypeDef sCommand = {0};
+ SectorAddress &= (uint32_t)(0x00FFFFFF);
+
+ assert_param(IS_QSPI_ADDR(SectorAddress));
+ while (CACHE->CACHE_AES_CS & CACHE_IS_BUSY);
+
+ if (cmdParam == NULL) {
+ sCommand.Instruction = SECTOR_ERASE_CMD;
+ sCommand.BusMode = QSPI_BUSMODE_111;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24;
+ } else {
+ sCommand.Instruction = cmdParam->Instruction;
+ sCommand.BusMode = cmdParam->BusMode;
+ sCommand.CmdFormat = cmdParam->CmdFormat;
+ }
+
+ sCommand.Address = SectorAddress;
+
+ if (QSPI_WriteEnable(sCommand.BusMode) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ while (QSPI_IsBusy(sCommand.BusMode));
+
+ return QSPI_STATUS_OK;
+}
+
+uint8_t QSPI_EraseChip(QSPI_CommandTypeDef *cmdParam)
+{
+ MH_CommandTypeDef sCommand = {0};
+ while (CACHE->CACHE_AES_CS & CACHE_IS_BUSY);
+
+ if (cmdParam == NULL) {
+ sCommand.Instruction = CHIP_ERASE_CMD;
+ sCommand.BusMode = QSPI_BUSMODE_111;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8;
+ } else {
+ sCommand.Instruction = cmdParam->Instruction;
+ sCommand.BusMode = cmdParam->BusMode;
+ sCommand.CmdFormat = cmdParam->CmdFormat;
+ }
+
+ while (QSPI_IsBusy(sCommand.BusMode));
+
+ if (QSPI_WriteEnable(sCommand.BusMode) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ if ((MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT)) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ while (QSPI_IsBusy(sCommand.BusMode));
+
+ return QSPI_STATUS_OK;
+}
+
+uint8_t QSPI_ProgramPage(QSPI_CommandTypeDef *cmdParam, DMA_TypeDef *DMA_Channelx, uint32_t adr, uint32_t sz, uint8_t *buf)
+{
+ uint32_t i;
+ uint32_t end_addr, current_size, current_addr = 0, loop_addr;
+ DMA_InitTypeDef DMA_InitStruct;
+ MH_CommandTypeDef sCommand = {0};
+
+ while (CACHE->CACHE_AES_CS & CACHE_IS_BUSY);
+
+ if (DMA_Channelx == NULL) {
+ return QSPI_ProgramPage_Ex(cmdParam, adr, sz, buf);
+ }
+
+ adr &= (uint32_t)(0x00FFFFFF);
+ assert_param(IS_QSPI_ADDR(adr));
+ assert_param(IS_QSPI_ADDR_ADD_SZ(adr, sz));
+
+ while (current_addr <= adr) {
+ current_addr += X25Q_PAGE_SIZE;
+ }
+ current_size = current_addr - adr;
+
+ /* Check if the size of the data is less than the remaining place in the page */
+ if (current_size > sz) {
+ current_size = sz;
+ }
+
+ /* Initialize the adress variables */
+ current_addr = adr;
+ loop_addr = adr;
+ end_addr = adr + sz;
+
+ if (cmdParam == NULL) {
+ sCommand.Instruction = QUAD_INPUT_PAGE_PROG_CMD;
+ sCommand.BusMode = QSPI_BUSMODE_114;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24_PDAT;
+ } else {
+ sCommand.Instruction = cmdParam->Instruction;
+ sCommand.BusMode = cmdParam->BusMode;
+ sCommand.CmdFormat = cmdParam->CmdFormat;
+ }
+
+ if (QSPI_DMA_Configuration(DMA_Channelx, &DMA_InitStruct) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ do {
+ for (i = 0; i < (current_size / MAX_WR_DMA_DATA_LEN); i++) {
+ sCommand.Address = current_addr;
+ QSPI->BYTE_NUM = MAX_WR_DMA_DATA_LEN << 16;
+ QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_TFFH;
+
+ DMA_InitStruct.DMA_BlockSize = (MAX_WR_DMA_DATA_LEN / 4);
+ DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)buf;
+ DMA_Init(DMA_Channelx, &DMA_InitStruct);
+
+ //Enable DMA
+ DMA_ChannelCmd(DMA_Channelx, ENABLE);
+ QSPI->DMA_CNTL |= QUADSPI_DMA_CNTL_TX_EN;
+
+ if (QSPI_WriteEnable(sCommand.BusMode) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ while (QSPI_IsBusy(sCommand.BusMode));
+
+ QSPI->DMA_CNTL &= ~QUADSPI_DMA_CNTL_TX_EN;
+ DMA_ChannelCmd(DMA_Channelx, DISABLE);
+
+ buf += MAX_WR_DMA_DATA_LEN;
+ current_addr += MAX_WR_DMA_DATA_LEN;
+ sCommand.Address = current_addr;
+
+ }
+ if (current_size % MAX_WR_DMA_DATA_LEN > 0) {
+ QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_TFFH;
+ sCommand.Address = current_addr;
+ QSPI->BYTE_NUM = (current_size % MAX_WR_DMA_DATA_LEN) << 16;
+
+ DMA_InitStruct.DMA_BlockSize = (current_size % MAX_WR_DMA_DATA_LEN) >> 2;
+ DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)buf;
+ DMA_Init(DMA_Channelx, &DMA_InitStruct);
+
+ DMA_ChannelCmd(DMA_Channelx, ENABLE);
+ QSPI->DMA_CNTL |= QUADSPI_DMA_CNTL_TX_EN;
+
+ if (QSPI_WriteEnable(sCommand.BusMode) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ while (QSPI_IsBusy(sCommand.BusMode));
+
+ QSPI->DMA_CNTL &= ~QUADSPI_DMA_CNTL_TX_EN;
+ buf += current_size % MAX_WR_DMA_DATA_LEN;
+ }
+
+ loop_addr += current_size;
+ current_addr = loop_addr;
+
+ current_size = ((loop_addr + X25Q_PAGE_SIZE) > end_addr) ? (end_addr - loop_addr) : X25Q_PAGE_SIZE;
+ } while (loop_addr < end_addr);
+
+ //disable DMA
+ DMA_ChannelCmd(DMA_Channelx, DISABLE);
+ return QSPI_STATUS_OK;
+}
+
+#if(ENABLE_CACHE_AES)
+uint8_t QSPI_ProgramPage_ByAES(QSPI_CommandTypeDef *cmdParam, DMA_TypeDef *DMA_Channelx, uint32_t adr, uint32_t sz, uint8_t *buf)
+{
+
+ uint32_t i;
+ uint32_t end_addr, current_size, current_addr = 0, loop_addr;
+ DMA_InitTypeDef DMA_InitStruct;
+ uint8_t mplain[32];
+ MH_CommandTypeDef sCommand;
+
+ while (CACHE->CACHE_AES_CS & CACHE_IS_BUSY);
+
+ adr &= (uint32_t)(0x00FFFFFF);
+
+ assert_param(IS_QSPI_ADDR(adr));
+ assert_param(IS_QSPI_ADDR_ADD_SZ(adr, sz));
+
+ if (DMA_Channelx == NULL) {
+ DMA_Channelx = DMA_Channel_0;
+ }
+
+ while (current_addr <= adr) {
+ current_addr += X25Q_PAGE_SIZE;
+ }
+ current_size = current_addr - adr;
+
+ /* Check if the size of the data is less than the remaining place in the page */
+ if (current_size > sz) {
+ current_size = sz;
+ }
+
+ /* Initialize the adress variables */
+ current_addr = adr;
+ loop_addr = adr;
+ end_addr = adr + sz;
+
+ buf_aes_enc((uint8_t*)(buf), sz, (uint8_t *)mplain);
+ if (QSPI_DMA_Configuration(DMA_Channelx, &DMA_InitStruct) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ if (cmdParam == NULL) {
+ sCommand.Instruction = QUAD_INPUT_PAGE_PROG_CMD;
+ sCommand.BusMode = QSPI_BUSMODE_114;
+ sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24_PDAT;
+ } else {
+ sCommand.Instruction = cmdParam->Instruction;
+ sCommand.BusMode = cmdParam->BusMode;
+ sCommand.CmdFormat = cmdParam->CmdFormat;
+ }
+
+ do {
+ for (i = 0; i < (current_size / MAX_WR_DMA_DATA_LEN); i++) {
+ sCommand.Address = current_addr;
+ QSPI->BYTE_NUM = MAX_WR_DMA_DATA_LEN << 16;
+ QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_TFFH;
+
+ DMA_InitStruct.DMA_BlockSize = (MAX_WR_DMA_DATA_LEN / 4);
+ DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)buf;
+ DMA_Init(DMA_Channelx, &DMA_InitStruct);
+
+ //Enable DMA
+ DMA_ChannelCmd(DMA_Channelx, ENABLE);
+ QSPI->DMA_CNTL |= QUADSPI_DMA_CNTL_TX_EN;
+
+ if (QSPI_WriteEnable(sCommand.BusMode) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ while (QSPI_IsBusy(sCommand.BusMode));
+
+ QSPI->DMA_CNTL &= ~QUADSPI_DMA_CNTL_TX_EN;
+ DMA_ChannelCmd(DMA_Channelx, DISABLE);
+
+ buf += MAX_WR_DMA_DATA_LEN;
+ current_addr += MAX_WR_DMA_DATA_LEN;
+ sCommand.Address = current_addr;
+ }
+
+ if (current_size % MAX_WR_DMA_DATA_LEN > 0) {
+ uint8_t cnt_aes_div, cnt_aes_rem;
+ cnt_aes_rem = current_size % 32;
+ cnt_aes_div = current_size / 32;
+
+ if (cnt_aes_div) {
+ QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_TFFH;
+ sCommand.Address = current_addr;
+ QSPI->BYTE_NUM = ((cnt_aes_div * 32)) << 16;
+
+ DMA_InitStruct.DMA_BlockSize = (cnt_aes_div * 32);
+ DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)buf;
+ DMA_Init(DMA_Channelx, &DMA_InitStruct);
+
+ DMA_ChannelCmd(DMA_Channelx, ENABLE);
+ QSPI->DMA_CNTL |= QUADSPI_DMA_CNTL_TX_EN;
+
+ if (QSPI_WriteEnable(sCommand.BusMode) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+ while (QSPI_IsBusy(sCommand.BusMode));
+
+ QSPI->DMA_CNTL &= ~QUADSPI_DMA_CNTL_TX_EN;
+
+ buf += cnt_aes_div * 32;
+ current_addr += (cnt_aes_div * 32);
+ QSPI->ADDRES = current_addr << 8;
+ }
+ if (cnt_aes_rem) {
+ QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_TFFH;
+ sCommand.Address = current_addr;
+ QSPI->BYTE_NUM = 32 << 16;
+
+ DMA_InitStruct.DMA_BlockSize = 32;
+ DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)mplain;
+ DMA_Init(DMA_Channelx, &DMA_InitStruct);
+
+ DMA_ChannelCmd(DMA_Channelx, ENABLE);
+
+ QSPI->DMA_CNTL |= QUADSPI_DMA_CNTL_TX_EN;
+ if (QSPI_WriteEnable(sCommand.BusMode) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ if (MH_QSPI_Command(&sCommand, MH_QSPI_TIMEOUT_DEFAULT_CNT) != MH_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+ while (QSPI_IsBusy(sCommand.BusMode));
+
+ QSPI->DMA_CNTL &= ~QUADSPI_DMA_CNTL_TX_EN;
+ }
+ }
+
+ loop_addr += current_size;
+ current_addr = loop_addr;
+
+ current_size = ((loop_addr + X25Q_PAGE_SIZE) > end_addr) ? (end_addr - loop_addr) : X25Q_PAGE_SIZE;
+ } while (loop_addr < end_addr);
+
+ //disable DMA
+ DMA_ChannelCmd(DMA_Channelx, DISABLE);
+ return QSPI_STATUS_OK;
+}
+#endif
+
+void QSPI_Init(QSPI_InitTypeDef *mhqspi)
+{
+ if (mhqspi == NULL) {
+ QSPI->DEVICE_PARA = (QSPI->DEVICE_PARA & ~0xFF) | 0x6B;
+ } else {
+ QSPI->CACHE_INTF_CMD = (uint32_t)((mhqspi->Cache_Cmd_ReleaseDeepInstruction << 24)
+ | (mhqspi->Cache_Cmd_DeepInstruction << 16)
+ | ((mhqspi->Cache_Cmd_ReadBusMode & 0x03) << 12)
+ | ((mhqspi->Cache_Cmd_ReadFormat & 0x0F) << 8) | (mhqspi->Cache_Cmd_ReadInstruction));
+
+ QSPI->DEVICE_PARA = (uint32_t)((QSPI->DEVICE_PARA & ~0xFFFF)
+ | (((mhqspi->SampleDly & 0x01) << 15)
+ | ((mhqspi->SamplePha & 0x01) << 14)
+ | ((mhqspi->ProToCol & 0x03) << 8)
+ | ((mhqspi->DummyCycles & 0x0F) << 4)
+ | ((mhqspi->FreqSel & 0x03)) | QSPI_DEVICE_PARA_FLASH_READY_Mask));
+ }
+}
+
+/**
+ * @brief Sets the QSPI latency value.
+ * @param u32UsClk: specifies the QSPI Latency value.
+ * @retval None
+ */
+void QSPI_SetLatency(uint32_t u32UsClk)
+{
+ SYSCTRL_ClocksTypeDef clocks;
+
+ if (0 == u32UsClk) {
+ SYSCTRL_GetClocksFreq(&clocks);
+ QSPI->DEVICE_PARA = (QSPI->DEVICE_PARA & 0xFFFF) | ((clocks.CPU_Frequency * 2 / 1000000) << 16);
+ } else {
+ QSPI->DEVICE_PARA = (QSPI->DEVICE_PARA & 0xFFFF) | (u32UsClk << 16);
+ }
+}
+
+/**
+ * @brief Flash Erase Sector.
+ * @param sectorAddress: The sector address to be erased
+ * @retval FLASH Status: The returned value can be: QSPI_STATUS_ERROR, QSPI_STATUS_OK
+ */
+uint8_t FLASH_EraseSector(uint32_t sectorAddress)
+{
+ uint8_t ret;
+
+ // __disable_irq();
+ // __disable_fault_irq();
+
+ ret = ROM_QSPI_EraseSector(NULL, sectorAddress);
+
+ // __enable_fault_irq();
+ // __enable_irq();
+
+ return ret;
+}
+
+/**
+ * @brief Flash Program Interface.
+ * @param cmdParam: pointer to a QSPI_CommandTypeDef structure that contains the configuration information.
+ * @param DMA_Channelx: DMA_Channel_0
+ * @param addr: specifies the address to be programmed.
+ * @param size: specifies the size to be programmed.
+ * @param buffer: pointer to the data to be programmed, need word aligned
+ * @retval FLASH Status: The returned value can be: QSPI_STATUS_ERROR, QSPI_STATUS_OK
+ */
+uint8_t FLASH_ProgramPage(QSPI_CommandTypeDef *cmdParam, DMA_TypeDef *DMA_Channelx, uint32_t addr, uint32_t size, uint8_t *buffer)
+{
+ uint8_t ret;
+
+ __disable_irq();
+ __disable_fault_irq();
+
+ ret = ROM_QSPI_ProgramPage(cmdParam, DMA_Channelx, addr, size, buffer);
+
+ __enable_fault_irq();
+ __enable_irq();
+
+ return ret;
+}
+
+/**
+ * @brief Enable or Disable QSPI's Interrupt.
+ * @param QSPI_IT: specify the Interrupt
+ * This parameter can be one of the following values:
+ * @arg QSPI_IT_TX_FIFO_DATA
+ * @arg QSPI_IT_RX_FIFO_DATA
+ * @arg QSPI_IT_TX_FIFO_OF
+ * @arg QSPI_IT_TX_FIFO_UF
+ * @arg QSPI_IT_RX_FIFO_OF
+ * @arg QSPI_IT_RX_FIFO_UF
+ * @arg QSPI_IT_DONE_INT
+ * @param NewState: new state of Interrupt
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void QSPI_ITConfig(uint32_t QSPI_IT, FunctionalState NewState)
+{
+ if (NewState != DISABLE) {
+ QSPI->INT_UMASK |= QSPI_IT;
+ } else {
+ QSPI->INT_MASK |= QSPI_IT;
+ }
+}
+
+/**
+ * @brief Clear the QSPI's interrupt bits
+ * @param QSPI_IT: specify the Interrupt
+ * This parameter can be one of the following values:
+ * @arg QSPI_IT_TX_FIFO_DATA
+ * @arg QSPI_IT_RX_FIFO_DATA
+ * @arg QSPI_IT_TX_FIFO_OF
+ * @arg QSPI_IT_TX_FIFO_UF
+ * @arg QSPI_IT_RX_FIFO_OF
+ * @arg QSPI_IT_RX_FIFO_UF
+ * @arg QSPI_IT_DONE_INT
+ * @retval None
+ */
+void QSPI_ClearITPendingBit(uint32_t QSPI_IT)
+{
+ QSPI->INT_CLEAR |= QSPI_IT;
+}
+
+ITStatus QSPI_GetITStatus(uint32_t QSPI_IT)
+{
+ if ((QSPI->INT_STATUS & QSPI_IT) != RESET) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+ITStatus QSPI_GetITRawStatus(uint32_t QSPI_IT)
+{
+ if ((QSPI->INT_RAWSTATUS & QSPI_IT) != RESET) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+
+void QSPI_TxFIFOFlush(void)
+{
+ QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_TFFH;
+}
+
+FlagStatus QSPI_TxFIFOEmpty(void)
+{
+ if (QSPI->FIFO_CNTL & QUADSPI_FIFO_CNTL_TFE) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+FlagStatus QSPI_TxFIFOFull(void)
+{
+ if (QSPI->FIFO_CNTL & QUADSPI_FIFO_CNTL_TFFL) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+uint8_t QSPI_TxFIFOLevel(void)
+{
+ return ((QSPI->FIFO_CNTL >> 16) & 0xF);
+}
+
+void QSPI_RxFIFOFlush(void)
+{
+ QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_RFFH;
+}
+
+
+FlagStatus QSPI_RxFIFOEmpty(void)
+{
+ if (QSPI->FIFO_CNTL & QUADSPI_FIFO_CNTL_RFE) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+FlagStatus QSPI_RxFIFOFull(void)
+{
+ if (QSPI->FIFO_CNTL & QUADSPI_FIFO_CNTL_RFFL) {
+ return SET;
+ } else {
+ return RESET;
+ }
+}
+
+uint8_t QSPI_RxFIFOLevel(void)
+{
+ return ((QSPI->FIFO_CNTL) & 0xF);
+}
+
+uint32_t QSPI_ReadRxFIFO(void)
+{
+ return QSPI->RD_FIFO;
+}
+
+void QSPI_WriteTxFIFO(uint32_t data)
+{
+ QSPI->WR_FIFO = data;
+}
+
+uint8_t g_plainBuff[4096];
+uint8_t AES_Program(QSPI_CommandTypeDef *cmdParam, DMA_TypeDef *DMA_Channelx, uint32_t addr, uint32_t size, uint8_t *buffer)
+{
+ ASSERT((addr % 4096) == 0);
+ if (EncryptedFlash()) {
+ buf_aes_enc(buffer, 4096, (uint8_t *)g_plainBuff);
+#ifdef __GNUC__
+ return QSPI_ProgramPage(cmdParam, DMA_Channelx, addr, size, (uint8_t *)g_plainBuff);
+#else
+ return FLASH_ProgramPage(cmdParam, DMA_Channelx, addr, size, (uint8_t *)g_plainBuff);
+#endif
+ } else {
+#ifdef __GNUC__
+ return QSPI_ProgramPage(cmdParam, DMA_Channelx, addr, size, (uint8_t *)buffer);
+#else
+ return FLASH_ProgramPage(cmdParam, DMA_Channelx, addr, size, (uint8_t *)buffer);
+#endif
+ }
+}
+
+static bool EncryptedFlash(void)
+{
+ static bool first = true;
+ static bool encrypt = false;
+ uint8_t key128[16], iv[16];
+
+ if (first) {
+ OTP_PowerOn();
+ first = false;
+ memcpy(key128, (uint32_t *)(0x40009128), 16);
+ memcpy(iv, (uint32_t *)(0x40009138), 16);
+ //PrintArray("key128", key128, 16);
+ //PrintArray("iv", iv, 16);
+ if (CheckAllFF(key128, 16) && CheckAllFF(iv, 16)) {
+ encrypt = false;
+ printf("non-encrypted device\n");
+ } else {
+ encrypt = true;
+ printf("encrypted device\n");
+ }
+ }
+
+ return encrypt;
+}
+
+/*********************** (C) COPYRIGHT Megahunt *****END OF FILE****/
+#endif
\ No newline at end of file
diff --git a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c
index 41134ff..7322f11 100644
--- a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c
+++ b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c
@@ -16,6 +16,7 @@
#include "user_msg.h"
#include "drv_usb.h"
#include "user_delay.h"
+#include "data_parser_task.h"
/** @defgroup usbd_cdc
* @brief usbd core module
@@ -57,6 +58,8 @@ static uint8_t usbd_cdc_EP0_RxReady(void* pdev);
static uint8_t usbd_cdc_DataIn(void* pdev, uint8_t epnum);
static uint8_t usbd_cdc_DataOut(void* pdev, uint8_t epnum);
static uint8_t usbd_cdc_SOF(void* pdev);
+static uint8_t usbd_cdc_StallControl(void* pdev);
+static uint8_t* usbd_cdc_FindDescriptor(uint8_t descType, uint16_t *len);
static uint8_t* USBD_cdc_GetCfgDesc(uint8_t speed, uint16_t* length);
@@ -88,11 +91,12 @@ extern USB_OTG_CORE_HANDLE g_usbDev;
#define CDC_TX_MAX_LENGTH 1024
#define CDC_PACKET_SIZE 64
+#define CDC_LINE_CODING_LEN 7U
static uint8_t g_cdcSendBuffer[CDC_TX_MAX_LENGTH];
static uint32_t g_cdcSendIndex = 0;
-static uint32_t cdcCmd = 0xFF;
+static uint32_t cdcCmd = NO_CMD;
static uint32_t cdcLen = 0;
CDC_Data_TypeDef CDCData = {
@@ -290,28 +294,34 @@ static uint8_t usbd_cdc_Setup(void* pdev, USB_SETUP_REQ* req)
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
/* CDC Class Requests -------------------------------*/
case USB_REQ_TYPE_CLASS:
- /* Check if the request is a data setup packet */
- if (req->wLength) {
- /* Check if the request is Device-to-Host */
- if (req->bmRequest & 0x80) {
- /* Get the data to be sent to Host from interface layer */
- APP_FOPS.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength);
-
- /* Send the data to the host */
- USBD_CtlSendData(pdev, CmdBuff, req->wLength);
- } else { /* Host-to-Device requeset */
- /* Set the value of the current command to be processed */
- cdcCmd = req->bRequest;
- cdcLen = req->wLength;
-
- /* Prepare the reception of the buffer over EP0
- Next step: the received data will be managed in usbd_cdc_EP0_TxSent()
- function. */
- USBD_CtlPrepareRx(pdev, CmdBuff, req->wLength);
+ switch (req->bRequest) {
+ case GET_LINE_CODING:
+ if (((req->bmRequest & 0x80U) == 0U) || (req->wLength != CDC_LINE_CODING_LEN)) {
+ return usbd_cdc_StallControl(pdev);
+ }
+ APP_FOPS.pIf_Ctrl(GET_LINE_CODING, CmdBuff, CDC_LINE_CODING_LEN);
+ USBD_CtlSendData(pdev, CmdBuff, CDC_LINE_CODING_LEN);
+ break;
+
+ case SET_LINE_CODING:
+ if (((req->bmRequest & 0x80U) != 0U) || (req->wLength != CDC_LINE_CODING_LEN)) {
+ return usbd_cdc_StallControl(pdev);
+ }
+ cdcCmd = SET_LINE_CODING;
+ cdcLen = CDC_LINE_CODING_LEN;
+ USBD_CtlPrepareRx(pdev, CmdBuff, CDC_LINE_CODING_LEN);
+ break;
+
+ case SET_CONTROL_LINE_STATE:
+ case SEND_BREAK:
+ if (((req->bmRequest & 0x80U) != 0U) || (req->wLength != 0U)) {
+ return usbd_cdc_StallControl(pdev);
}
- } else { /* No Data request */
- /* Transfer the command to the interface layer */
APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0);
+ break;
+
+ default:
+ return usbd_cdc_StallControl(pdev);
}
return USBD_OK;
@@ -320,8 +330,13 @@ static uint8_t usbd_cdc_Setup(void* pdev, USB_SETUP_REQ* req)
switch (req->bRequest) {
case USB_REQ_GET_DESCRIPTOR:
if ((req->wValue >> 8) == CDC_DESCRIPTOR_TYPE) {
- pbuf = usbd_cdc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
- len = MIN(USB_CDC_DESC_SIZ, req->wLength);
+ pbuf = usbd_cdc_FindDescriptor(CDC_DESCRIPTOR_TYPE, &len);
+ if (pbuf == NULL || len == 0U) {
+ return usbd_cdc_StallControl(pdev);
+ }
+ len = MIN(len, req->wLength);
+ } else {
+ return usbd_cdc_StallControl(pdev);
}
USBD_CtlSendData(pdev, pbuf, len);
@@ -337,9 +352,16 @@ static uint8_t usbd_cdc_Setup(void* pdev, USB_SETUP_REQ* req)
} else {
/* Call the error management function (command will be nacked */
USBD_CtlError(pdev, req);
+ return USBD_FAIL;
}
break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ return USBD_FAIL;
}
+ return USBD_OK;
+
default:
USBD_CtlError(pdev, req);
return USBD_FAIL;
@@ -355,21 +377,37 @@ static uint8_t usbd_cdc_Setup(void* pdev, USB_SETUP_REQ* req)
static uint8_t usbd_cdc_EP0_RxReady(void* pdev)
{
USB_OTG_EP* ep = &((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[0];
- if (ep->xfer_buff != CmdBuff)
+ if (cdcCmd == NO_CMD)
return USBD_OK;
- // Will fired when CDC Set Cmd request callback
- if (cdcCmd != NO_CMD) {
- /* Process the data */
- APP_FOPS.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen);
-
- /* Reset the command variable to default value */
+ if ((((USB_OTG_CORE_HANDLE*)pdev)->dev.device_state != USB_OTG_EP0_DATA_OUT) ||
+ (cdcCmd != SET_LINE_CODING) ||
+ (cdcLen != CDC_LINE_CODING_LEN) ||
+ (ep->xfer_buff != CmdBuff) ||
+ (ep->xfer_len != cdcLen) ||
+ (ep->xfer_count != cdcLen)) {
cdcCmd = NO_CMD;
+ cdcLen = 0;
+ return usbd_cdc_StallControl(pdev);
}
+ APP_FOPS.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen);
+ cdcCmd = NO_CMD;
+ cdcLen = 0;
+
return USBD_OK;
}
+static uint8_t usbd_cdc_StallControl(void* pdev)
+{
+ cdcCmd = NO_CMD;
+ cdcLen = 0;
+ DCD_EP_Stall(pdev, 0x80);
+ DCD_EP_Stall(pdev, 0x00);
+ USB_OTG_EP0_OutStart(pdev);
+ return USBD_FAIL;
+}
+
/**
* @brief usbd_audio_DataIn
* Data sent on non-control IN endpoint
@@ -393,16 +431,70 @@ static uint8_t usbd_cdc_DataIn(void* pdev, uint8_t epnum)
*/
static uint8_t usbd_cdc_DataOut(void* pdev, uint8_t epnum)
{
-void PushDataToField(uint8_t *data, uint16_t len);
- USB_OTG_EP* ep = &((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum];
+ uint8_t ep_idx = epnum & 0x7F;
+ if (ep_idx >= USB_OTG_MAX_EP_COUNT) {
+ return USBD_FAIL;
+ }
+ USB_OTG_EP* ep = &((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[ep_idx];
uint16_t rxCount = ep->xfer_count;
PrintArray("WEBUSB rx", USB_Rx_Buffer, rxCount);
- PushDataToField(USB_Rx_Buffer, rxCount);
- PubValueMsg(SPRING_MSG_GET, rxCount);
+ if (rxCount != 0U) {
+ if (!CanPushDataToField(rxCount)) {
+ printf("WEBUSB RX drop: parser buffer full len=%u\n", rxCount);
+ DCD_EP_PrepareRx(pdev, CDC_OUT_EP, (uint8_t*)(USB_Rx_Buffer), CDC_DATA_OUT_PACKET_SIZE);
+ return USBD_OK;
+ }
+
+ if (PushDataToField(USB_Rx_Buffer, rxCount) != rxCount) {
+ printf("WEBUSB RX drop: push mismatch len=%u\n", rxCount);
+ ResetDataField();
+ DCD_EP_PrepareRx(pdev, CDC_OUT_EP, (uint8_t*)(USB_Rx_Buffer), CDC_DATA_OUT_PACKET_SIZE);
+ return USBD_OK;
+ }
+
+ if (PubValueMsg(SPRING_MSG_GET, rxCount) != MSG_SUCCESS) {
+ printf("WEBUSB RX drop: queue full len=%u\n", rxCount);
+ ResetDataField();
+ }
+ }
DCD_EP_PrepareRx(pdev, CDC_OUT_EP, (uint8_t*)(USB_Rx_Buffer), CDC_DATA_OUT_PACKET_SIZE);
return USBD_OK;
}
+static uint8_t* usbd_cdc_FindDescriptor(uint8_t descType, uint16_t *len)
+{
+ uint8_t *desc = NULL;
+ uint16_t totalLen = 0;
+ uint16_t idx = 0;
+
+ if (len == NULL) {
+ return NULL;
+ }
+ *len = 0;
+
+#ifdef USBD_ENABLE_MSC
+ desc = usbd_cdc_CfgDesc;
+ totalLen = sizeof(usbd_cdc_CfgDesc);
+#else
+ desc = USBD_CDC_CfgHSDesc;
+ totalLen = sizeof(USBD_CDC_CfgHSDesc);
+#endif
+
+ while ((idx + 1U) < totalLen) {
+ uint8_t blen = desc[idx];
+ if ((blen < 2U) || ((uint16_t)(idx + blen) > totalLen)) {
+ break;
+ }
+ if (desc[idx + 1U] == descType) {
+ *len = blen;
+ return &desc[idx];
+ }
+ idx = (uint16_t)(idx + blen);
+ }
+
+ return NULL;
+}
+
static uint8_t usbd_cdc_SOF(void* pdev)
{
return USBD_OK;
@@ -478,4 +570,3 @@ static void USBD_cdc_SendCallback(void)
{
printf("USBD_cdc_SendCallback usb send over\n");
}
-
diff --git a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c
index e598f53..7d52816 100644
--- a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c
+++ b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c
@@ -12,9 +12,6 @@
#include "usbd_msc_mem.h"
#include "usbd_msc_data.h"
#include "stdio.h"
-#include "background_task.h"
-#include "user_fatfs.h"
-#include "fingerprint_task.h"
/** @defgroup MSC_SCSI
* @brief Mass storage SCSI layer module
@@ -98,8 +95,6 @@ static int8_t SCSI_ProcessWrite(uint8_t lun);
* @{
*/
-#define AUTO_REBOOT_AFTER_COPY_FILE
-
/**
* @brief SCSI_ProcessCmd
* Process SCSI commands
@@ -113,28 +108,6 @@ int8_t SCSI_ProcessCmd(USB_OTG_CORE_HANDLE *pdev,
uint8_t *params)
{
cdev = pdev;
-#ifdef AUTO_REBOOT_AFTER_COPY_FILE
- static uint8_t lastParam[2] = {0};
- //printf("%X\r\n", params[0]);
- if (params[0] == SCSI_TEST_UNIT_READY && lastParam[0] == SCSI_TEST_UNIT_READY && lastParam[1] == SCSI_WRITE10) {
- printf("file copy over\r\n");
- MountUsbFatfs();
- FIL fp;
- uint32_t fileSize;
- FRESULT res = f_open(&fp, "1:pillar.bin", FA_OPEN_EXISTING | FA_READ);
- if (res) {
- printf("open error\r\n");
- } else {
- fileSize = f_size(&fp);
- printf("file size=%d\r\n", fileSize);
- if (fileSize > 0) {
- SystemReboot();
- }
- }
- }
- lastParam[1] = lastParam[0];
- lastParam[0] = params[0];
-#endif
switch (params[0]) {
case SCSI_TEST_UNIT_READY:
return SCSI_TestUnitReady(lun, params);
@@ -447,13 +420,13 @@ static int8_t SCSI_Read10(uint8_t lun, uint8_t *params)
return -1;
}
- SCSI_blk_addr = (params[2] << 24) | \
- (params[3] << 16) | \
- (params[4] << 8) | \
- params[5];
+ SCSI_blk_addr = ((uint32_t)params[2] << 24) | \
+ ((uint32_t)params[3] << 16) | \
+ ((uint32_t)params[4] << 8) | \
+ (uint32_t)params[5];
- SCSI_blk_len = (params[7] << 8) | \
- params[8];
+ SCSI_blk_len = ((uint32_t)params[7] << 8) | \
+ (uint32_t)params[8];
@@ -516,12 +489,12 @@ static int8_t SCSI_Write10(uint8_t lun, uint8_t *params)
}
- SCSI_blk_addr = (params[2] << 24) | \
- (params[3] << 16) | \
- (params[4] << 8) | \
- params[5];
- SCSI_blk_len = (params[7] << 8) | \
- params[8];
+ SCSI_blk_addr = ((uint32_t)params[2] << 24) | \
+ ((uint32_t)params[3] << 16) | \
+ ((uint32_t)params[4] << 8) | \
+ (uint32_t)params[5];
+ SCSI_blk_len = ((uint32_t)params[7] << 8) | \
+ (uint32_t)params[8];
/* check if LBA address is in the right range */
if (SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0) {
@@ -567,12 +540,12 @@ static int8_t SCSI_Verify10(uint8_t lun, uint8_t *params)
return -1; /* Error, Verify Mode Not supported*/
}
- SCSI_blk_addr = (params[2] << 24) | \
- (params[3] << 16) | \
- (params[4] << 8) | \
- params[5];
- SCSI_blk_len = (params[7] << 8) | \
- params[8];
+ SCSI_blk_addr = ((uint32_t)params[2] << 24) | \
+ ((uint32_t)params[3] << 16) | \
+ ((uint32_t)params[4] << 8) | \
+ (uint32_t)params[5];
+ SCSI_blk_len = ((uint32_t)params[7] << 8) | \
+ (uint32_t)params[8];
if (SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0) {
return -1; /* error */
@@ -591,8 +564,7 @@ static int8_t SCSI_Verify10(uint8_t lun, uint8_t *params)
*/
static int8_t SCSI_CheckAddressRange(uint8_t lun, uint32_t blk_offset, uint16_t blk_nbr)
{
-
- if ((blk_offset + blk_nbr) > SCSI_blk_nbr) {
+ if ((blk_offset >= SCSI_blk_nbr) || (blk_nbr > (SCSI_blk_nbr - blk_offset))) {
SCSI_SenseCode(lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
return -1;
}
diff --git a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/inc/usbd_req.h b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/inc/usbd_req.h
index a07b1c6..d26c7c1 100644
--- a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/inc/usbd_req.h
+++ b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/inc/usbd_req.h
@@ -35,7 +35,7 @@ void USBD_ParseSetupRequest(USB_OTG_CORE_HANDLE *pdev,
void USBD_CtlError(USB_OTG_CORE_HANDLE *pdev,
USB_SETUP_REQ *req);
-void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len);
+void USBD_GetString(uint8_t *desc, uint16_t descLen, uint8_t *unicode, uint16_t *len);
/**
* @}
*/
diff --git a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/src/usbd_core.c b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/src/usbd_core.c
index f2af7d9..e68f627 100644
--- a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/src/usbd_core.c
+++ b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/src/usbd_core.c
@@ -116,9 +116,8 @@ void USBD_Init(USB_OTG_CORE_HANDLE* pdev, USB_OTG_CORE_ID_TypeDef coreID, USBD_D
nvicSet = true;
/* Enable USB Interrupt */
NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_SetPriorityGrouping(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = USB_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
@@ -199,8 +198,12 @@ static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE* pdev)
*/
static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE* pdev, uint8_t epnum)
{
+ uint8_t ep_idx = epnum & 0x7F;
USB_OTG_EP* ep;
- ep = &pdev->dev.out_ep[epnum & 0x7F];
+ if (ep_idx >= USB_OTG_MAX_EP_COUNT) {
+ return USBD_FAIL;
+ }
+ ep = &pdev->dev.out_ep[ep_idx];
if (epnum == 0) {
if (pdev->dev.device_state == USB_OTG_EP0_DATA_OUT) {
if ((pdev->dev.class_cb->EP0_RxReady != NULL) && (pdev->dev.device_status == USB_OTG_CONFIGURED)) {
@@ -216,7 +219,7 @@ static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE* pdev, uint8_t epnum)
USB_OTG_EPStartXfer(pdev, ep);
} else {
if ((pdev->dev.class_cb->DataOut != NULL) && (pdev->dev.device_status == USB_OTG_CONFIGURED)) {
- pdev->dev.class_cb->DataOut(pdev, epnum);
+ pdev->dev.class_cb->DataOut(pdev, ep_idx);
}
}
}
@@ -232,8 +235,12 @@ static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE* pdev, uint8_t epnum)
*/
static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE* pdev, uint8_t epnum)
{
+ uint8_t ep_idx = epnum & 0x7F;
USB_OTG_EP* ep;
- ep = &pdev->dev.in_ep[epnum];
+ if (ep_idx >= USB_OTG_MAX_EP_COUNT) {
+ return USBD_FAIL;
+ }
+ ep = &pdev->dev.in_ep[ep_idx];
if (epnum == 0) {
if (ep->xfer_count > 1) {
USB_OTG_EP0StartXfer(pdev, ep);
@@ -255,7 +262,7 @@ static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE* pdev, uint8_t epnum)
} else if (ep->xfer_count == 1 || ep->total_data_len == 0) {
ep->xfer_count = 0;
if ((pdev->dev.class_cb->DataIn != NULL) && (pdev->dev.device_status == USB_OTG_CONFIGURED)) {
- pdev->dev.class_cb->DataIn(pdev, epnum);
+ pdev->dev.class_cb->DataIn(pdev, ep_idx);
}
}
}
diff --git a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/src/usbd_ioreq.c b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/src/usbd_ioreq.c
index 8a2f696..30b54be 100644
--- a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/src/usbd_ioreq.c
+++ b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/src/usbd_ioreq.c
@@ -146,6 +146,9 @@ USBD_Status USBD_CtlReceiveStatus(USB_OTG_CORE_HANDLE *pdev)
*/
uint16_t USBD_GetRxCount(USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
{
+ if (epnum >= USB_OTG_MAX_EP_COUNT) {
+ return 0;
+ }
return pdev->dev.out_ep[epnum].xfer_count;
}
diff --git a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/src/usbd_req.c b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/src/usbd_req.c
index 1564009..7d63c28 100644
--- a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/src/usbd_req.c
+++ b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_Device_Library/Core/src/usbd_req.c
@@ -44,11 +44,24 @@ static void USBD_SetFeature(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req);
static void USBD_ClrFeature(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req);
-static uint8_t USBD_GetLen(uint8_t* buf);
+static uint8_t USBD_IsValidEPAddress(uint8_t ep_addr);
+
/**
* @}
*/
+static uint8_t USBD_IsValidEPAddress(uint8_t ep_addr)
+{
+ uint8_t ep_num = ep_addr & 0x7F;
+ if ((ep_addr & 0x70) != 0U) {
+ return 0U;
+ }
+ if (ep_num >= USB_OTG_MAX_EP_COUNT) {
+ return 0U;
+ }
+ return 1U;
+}
+
/**
* @brief USBD_StdDevReq
* Handle standard usb device requests
@@ -116,7 +129,7 @@ USBD_Status USBD_StdItfReq(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req)
USBD_Status ret = USBD_OK;
switch (pdev->dev.device_status) {
case USB_OTG_CONFIGURED:
- if (LOBYTE(req->wIndex) > USBD_ITF_MAX_NUM || pdev->dev.class_cb->Setup(pdev, req) != USBD_OK) {
+ if (LOBYTE(req->wIndex) >= USBD_ITF_MAX_NUM || pdev->dev.class_cb->Setup(pdev, req) != USBD_OK) {
USBD_CtlError(pdev, req);
}
break;
@@ -147,6 +160,10 @@ USBD_Status USBD_StdEPReq(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req)
switch (pdev->dev.device_status) {
case USB_OTG_ADDRESSED:
if ((ep_addr != 0x00) && (ep_addr != 0x80)) {
+ if (!USBD_IsValidEPAddress(ep_addr)) {
+ USBD_CtlError(pdev, req);
+ break;
+ }
DCD_EP_Stall(pdev, ep_addr);
}
break;
@@ -154,6 +171,10 @@ USBD_Status USBD_StdEPReq(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req)
case USB_OTG_CONFIGURED:
if (req->wValue == USB_FEATURE_EP_HALT) {
if ((ep_addr != 0x00) && (ep_addr != 0x80)) {
+ if (!USBD_IsValidEPAddress(ep_addr)) {
+ USBD_CtlError(pdev, req);
+ break;
+ }
DCD_EP_Stall(pdev, ep_addr);
}
}
@@ -172,6 +193,10 @@ USBD_Status USBD_StdEPReq(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req)
switch (pdev->dev.device_status) {
case USB_OTG_ADDRESSED:
if ((ep_addr != 0x00) && (ep_addr != 0x80)) {
+ if (!USBD_IsValidEPAddress(ep_addr)) {
+ USBD_CtlError(pdev, req);
+ break;
+ }
DCD_EP_Stall(pdev, ep_addr);
}
break;
@@ -179,6 +204,10 @@ USBD_Status USBD_StdEPReq(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req)
case USB_OTG_CONFIGURED:
if (req->wValue == USB_FEATURE_EP_HALT) {
if ((ep_addr != 0x00) && (ep_addr != 0x80)) {
+ if (!USBD_IsValidEPAddress(ep_addr)) {
+ USBD_CtlError(pdev, req);
+ break;
+ }
DCD_EP_ClrStall(pdev, ep_addr);
pdev->dev.class_cb->Setup(pdev, req);
}
@@ -196,24 +225,40 @@ USBD_Status USBD_StdEPReq(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req)
switch (pdev->dev.device_status) {
case USB_OTG_ADDRESSED:
if ((ep_addr != 0x00) && (ep_addr != 0x80)) {
+ if (!USBD_IsValidEPAddress(ep_addr)) {
+ USBD_CtlError(pdev, req);
+ break;
+ }
DCD_EP_Stall(pdev, ep_addr);
}
break;
case USB_OTG_CONFIGURED:
+ if ((ep_addr & 0x70) != 0) {
+ USBD_CtlError(pdev, req);
+ break;
+ }
if ((ep_addr & 0x80) == 0x80) {
- if (pdev->dev.in_ep[ep_addr & 0x7F].is_stall) {
+ uint8_t ep_num = ep_addr & 0x7F;
+ if (ep_num >= USB_OTG_MAX_EP_COUNT) {
+ USBD_CtlError(pdev, req);
+ break;
+ }
+ if (pdev->dev.in_ep[ep_num].is_stall) {
USBD_ep_status = 0x0001;
} else {
USBD_ep_status = 0x0000;
}
} else if ((ep_addr & 0x80) == 0x00) {
- if (pdev->dev.out_ep[ep_addr].is_stall) {
- USBD_ep_status = 0x0001;
+ uint8_t ep_num = ep_addr & 0x7F;
+ if (ep_num >= USB_OTG_MAX_EP_COUNT) {
+ USBD_CtlError(pdev, req);
+ break;
}
-
- else {
+ if (pdev->dev.out_ep[ep_num].is_stall) {
+ USBD_ep_status = 0x0001;
+ } else {
USBD_ep_status = 0x0000;
}
}
@@ -236,8 +281,8 @@ USBD_Status USBD_StdEPReq(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req)
static void USBD_WinUSBGetDescriptor(USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req)
{
- uint16_t len;
- uint8_t *pbuf;
+ uint16_t len = 0;
+ uint8_t *pbuf = NULL;
switch (req->wIndex) {
case 0x04: // compat ID
@@ -252,9 +297,11 @@ static void USBD_WinUSBGetDescriptor(USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *r
return;
}
- if ((len != 0) && (req->wLength != 0)) {
+ if ((pbuf != NULL) && (len != 0) && (req->wLength != 0)) {
len = MIN(len, req->wLength);
USBD_CtlSendData(pdev, pbuf, len);
+ } else {
+ USBD_CtlError(pdev, req);
}
}
@@ -268,7 +315,7 @@ static void USBD_WinUSBGetDescriptor(USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *r
*/
static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req)
{
- uint16_t len;
+ uint16_t len = 0;
uint8_t* pbuf = NULL;
// USB_OTG_CSR0L_IN_PERIPHERAL_TypeDef csr0l;
// csr0l.d8 = USB_OTG_READ_REG8(&pdev->regs.INDEXREGS->CSRL.CSR0L);
@@ -282,6 +329,10 @@ static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req)
case USB_DESC_TYPE_CONFIGURATION:
pbuf = (uint8_t*)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len);
+ if (pbuf == NULL || len < 2U) {
+ USBD_CtlError(pdev, req);
+ return;
+ }
pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
pdev->dev.pConfig_descriptor = pbuf;
@@ -343,11 +394,13 @@ static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req)
return;
}
- if ((len != 0) && (req->wLength != 0)) {
+ if ((pbuf != NULL) && (len != 0) && (req->wLength != 0)) {
len = MIN(len, req->wLength);
USBD_CtlSendData(pdev, pbuf, len);
+ } else if ((req->wLength != 0) && (pbuf == NULL)) {
+ USBD_CtlError(pdev, req);
}
}
@@ -622,38 +675,39 @@ void USBD_CtlError(USB_OTG_CORE_HANDLE* pdev, USB_SETUP_REQ* req)
* @param len : descriptor length
* @retval None
*/
-void USBD_GetString(uint8_t* desc, uint8_t* unicode, uint16_t* len)
+void USBD_GetString(uint8_t* desc, uint16_t descLen, uint8_t* unicode, uint16_t* len)
{
- uint8_t idx = 0;
+ uint16_t idx = 0;
+ uint16_t asciiLen = 0;
+ uint16_t maxAsciiLen = 0;
- if (desc != NULL) {
- *len = USBD_GetLen(desc) * 2 + 2;
- unicode[idx++] = *len;
- unicode[idx++] = USB_DESC_TYPE_STRING;
+ if (len == NULL) {
+ return;
+ }
+ *len = 0;
- while (*desc != '\0') {
- unicode[idx++] = *desc++;
- unicode[idx++] = 0x00;
- }
+ if (desc == NULL || unicode == NULL || descLen == 0U) {
+ return;
}
-}
-/**
- * @brief USBD_GetLen
- * return the string length
- * @param buf : pointer to the ascii string buffer
- * @retval string length
- */
-static uint8_t USBD_GetLen(uint8_t* buf)
-{
- uint8_t len = 0;
+ /* Reserve 2 bytes for descriptor header [len, type]. */
+ maxAsciiLen = (USB_MAX_STR_DESC_SIZ - 2U) / 2U;
+ if (descLen < maxAsciiLen) {
+ maxAsciiLen = descLen;
+ }
- while (*buf != '\0') {
- len++;
- buf++;
+ while (asciiLen < maxAsciiLen && desc[asciiLen] != '\0') {
+ asciiLen++;
}
- return len;
+ *len = (uint16_t)(asciiLen * 2U + 2U);
+ unicode[idx++] = (uint8_t)(*len);
+ unicode[idx++] = USB_DESC_TYPE_STRING;
+
+ for (uint16_t i = 0; i < asciiLen; i++) {
+ unicode[idx++] = desc[i];
+ unicode[idx++] = 0x00;
+ }
}
/************************ (C) COPYRIGHT 2014 Megahuntmicro ****END OF FILE****/
diff --git a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_OTG_Driver/src/usb_core.c b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_OTG_Driver/src/usb_core.c
index 845a291..50aeab8 100644
--- a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_OTG_Driver/src/usb_core.c
+++ b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_OTG_Driver/src/usb_core.c
@@ -1299,6 +1299,8 @@ USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE* pdev, USB_OTG_EP* ep)
USB_OTG_TXCSRL_IN_PERIPHERAL_TypeDef tx_csrl;
USB_OTG_RXCSRL_IN_PERIPHERAL_TypeDef rx_csrl;
USB_OTG_RXCOUNT_TypeDef rx_count;
+ uint32_t rx_len = 0;
+ uint32_t rx_remain = 0;
/* IN endpoint */
if (ep->is_in) {
@@ -1323,14 +1325,28 @@ USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE* pdev, USB_OTG_EP* ep)
USB_OTG_WRITE_REG8(&pdev->regs.CSRREGS[ep->num]->RXCSRL, rx_csrl.d8);
} else {
rx_count.d16 = USB_OTG_READ_REG16(&pdev->regs.CSRREGS[ep->num]->RXCOUNT);
- USB_OTG_ReadPacket(pdev, ep->xfer_buff + ep->xfer_count, ep->num, rx_count.d16);
- ep->xfer_count += rx_count.d16;
- if (ep->xfer_len >= ep->xfer_count) {
- ep->rem_data_len = ep->xfer_len - ep->xfer_count;
- } else {
- ep->rem_data_len = 0;
- ep->xfer_count = ep->xfer_len;
+ rx_len = rx_count.d16;
+
+ if ((ep->xfer_buff == NULL) || (ep->xfer_count > ep->xfer_len)) {
+ ep->is_stall = 1;
+ USB_OTG_EPSetStall(pdev, ep);
+ rx_csrl.b.rx_pkt_rdy = 0;
+ USB_OTG_WRITE_REG8(&pdev->regs.CSRREGS[ep->num]->RXCSRL, rx_csrl.d8);
+ return USB_OTG_FAIL;
+ }
+
+ rx_remain = ep->xfer_len - ep->xfer_count;
+ if ((rx_len > ep->maxpacket) || (rx_len > rx_remain)) {
+ ep->is_stall = 1;
+ USB_OTG_EPSetStall(pdev, ep);
+ rx_csrl.b.rx_pkt_rdy = 0;
+ USB_OTG_WRITE_REG8(&pdev->regs.CSRREGS[ep->num]->RXCSRL, rx_csrl.d8);
+ return USB_OTG_FAIL;
}
+
+ USB_OTG_ReadPacket(pdev, ep->xfer_buff + ep->xfer_count, ep->num, (uint16_t)rx_len);
+ ep->xfer_count += rx_len;
+ ep->rem_data_len = ep->xfer_len - ep->xfer_count;
rx_csrl.b.rx_pkt_rdy = 0;
USB_OTG_WRITE_REG8(&pdev->regs.CSRREGS[ep->num]->RXCSRL, rx_csrl.d8);
}
diff --git a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_OTG_Driver/src/usb_dcd.c b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_OTG_Driver/src/usb_dcd.c
index 006a868..2f2ed70 100644
--- a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_OTG_Driver/src/usb_dcd.c
+++ b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_OTG_Driver/src/usb_dcd.c
@@ -10,6 +10,18 @@
#include "usb_dcd.h"
#include "usb_bsp.h"
+static uint8_t DCD_IsValidEpAddr(uint8_t ep_addr)
+{
+ uint8_t ep_num = ep_addr & 0x7F;
+ if ((ep_addr & 0x70U) != 0U) {
+ return 0U;
+ }
+ if (ep_num >= USB_OTG_MAX_EP_COUNT) {
+ return 0U;
+ }
+ return 1U;
+}
+
void DCD_Init(USB_OTG_CORE_HANDLE* pdev, USB_OTG_CORE_ID_TypeDef coreID)
{
/* Set Register Address */
@@ -45,6 +57,9 @@ uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev,
uint8_t ep_type)
{
USB_OTG_EP *ep;
+ if (!DCD_IsValidEpAddr(ep_addr)) {
+ return 1U;
+ }
if ((ep_addr & 0x80) == 0x80) {
ep = &pdev->dev.in_ep[ep_addr & 0x7F];
@@ -80,6 +95,9 @@ uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev,
uint32_t DCD_EP_Close(USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr)
{
USB_OTG_EP *ep;
+ if (!DCD_IsValidEpAddr(ep_addr)) {
+ return 1U;
+ }
if ((ep_addr & 0x80) == 0x80) {
ep = &pdev->dev.in_ep[ep_addr & 0x7F];
@@ -106,6 +124,9 @@ uint32_t DCD_EP_PrepareRx(USB_OTG_CORE_HANDLE *pdev,
uint16_t buf_len)
{
USB_OTG_EP *ep;
+ if (!DCD_IsValidEpAddr(ep_addr)) {
+ return 1U;
+ }
ep = &pdev->dev.out_ep[ep_addr & 0x7F];
@@ -138,6 +159,9 @@ uint32_t DCD_EP_Tx(USB_OTG_CORE_HANDLE *pdev,
uint32_t buf_len)
{
USB_OTG_EP *ep;
+ if (!DCD_IsValidEpAddr(ep_addr)) {
+ return 1U;
+ }
ep = &pdev->dev.in_ep[ep_addr & 0x7F];
@@ -170,15 +194,19 @@ uint32_t DCD_EP_Tx(USB_OTG_CORE_HANDLE *pdev,
uint32_t DCD_EP_Stall(USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
{
+ uint8_t ep_idx = epnum & 0x7F;
USB_OTG_EP *ep;
+ if (ep_idx >= USB_OTG_MAX_EP_COUNT) {
+ return 1;
+ }
if ((0x80 & epnum) == 0x80) {
- ep = &pdev->dev.in_ep[epnum & 0x7F];
+ ep = &pdev->dev.in_ep[ep_idx];
} else {
- ep = &pdev->dev.out_ep[epnum];
+ ep = &pdev->dev.out_ep[ep_idx];
}
ep->is_stall = 1;
- ep->num = epnum & 0x7F;
+ ep->num = ep_idx;
ep->is_in = ((epnum & 0x80) == 0x80);
USB_OTG_EPSetStall(pdev, ep);
@@ -193,15 +221,19 @@ uint32_t DCD_EP_Stall(USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
*/
uint32_t DCD_EP_ClrStall(USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
{
+ uint8_t ep_idx = epnum & 0x7F;
USB_OTG_EP *ep;
+ if (ep_idx >= USB_OTG_MAX_EP_COUNT) {
+ return 1;
+ }
if ((0x80 & epnum) == 0x80) {
- ep = &pdev->dev.in_ep[epnum & 0x7F];
+ ep = &pdev->dev.in_ep[ep_idx];
} else {
- ep = &pdev->dev.out_ep[epnum];
+ ep = &pdev->dev.out_ep[ep_idx];
}
ep->is_stall = 0;
- ep->num = epnum & 0x7F;
+ ep->num = ep_idx;
ep->is_in = ((epnum & 0x80) == 0x80);
USB_OTG_EPClearStall(pdev, ep);
@@ -216,10 +248,13 @@ uint32_t DCD_EP_ClrStall(USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
*/
uint32_t DCD_EP_Flush(USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
{
+ if (!DCD_IsValidEpAddr(epnum)) {
+ return 1U;
+ }
if ((epnum & 0x80) == 0x80) {
USB_OTG_FlushTxFifo(pdev, epnum & 0x7F);
} else {
- USB_OTG_FlushRxFifo(pdev, epnum);
+ USB_OTG_FlushRxFifo(pdev, epnum & 0x7F);
}
return (0);
@@ -290,11 +325,14 @@ uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
{
USB_OTG_EP *ep;
uint32_t Status = 0;
+ if (!DCD_IsValidEpAddr(epnum)) {
+ return 0U;
+ }
if ((0x80 & epnum) == 0x80) {
ep = &pdev->dev.in_ep[epnum & 0x7F];
} else {
- ep = &pdev->dev.out_ep[epnum];
+ ep = &pdev->dev.out_ep[epnum & 0x7F];
}
Status = USB_OTG_GetEPStatus(pdev, ep);
@@ -313,11 +351,14 @@ uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
void DCD_SetEPStatus(USB_OTG_CORE_HANDLE *pdev, uint8_t epnum, uint32_t Status)
{
USB_OTG_EP *ep;
+ if (!DCD_IsValidEpAddr(epnum)) {
+ return;
+ }
if ((0x80 & epnum) == 0x80) {
ep = &pdev->dev.in_ep[epnum & 0x7F];
} else {
- ep = &pdev->dev.out_ep[epnum];
+ ep = &pdev->dev.out_ep[epnum & 0x7F];
}
USB_OTG_SetEPStatus(pdev, ep, Status);
diff --git a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_OTG_Driver/src/usb_dcd_int.c b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_OTG_Driver/src/usb_dcd_int.c
index b835e8f..f32daea 100644
--- a/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_OTG_Driver/src/usb_dcd_int.c
+++ b/external/mh1903_lib/SCPU_USB_Lib/SCPU_USB_OTG_Driver/src/usb_dcd_int.c
@@ -59,6 +59,7 @@ uint32_t USBD_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev)
uint32_t retval = 0;
USB_OTG_EP* ep;
uint32_t rxLength = 0;
+ uint32_t rxRemain = 0;
if (USB_OTG_IsDeviceMode(pdev)) { /* ensure that we are in device mode */
gintr_status.d8 = USB_OTG_ReadCoreItr(pdev);
@@ -104,6 +105,31 @@ uint32_t USBD_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev)
ep = &pdev->dev.out_ep[0];
/* Read Packet */
rxLength = USB_OTG_READ_REG8(&pdev->regs.INDEXREGS->COUNT.COUNT0);
+ if ((ep->xfer_buff == NULL) || (ep->xfer_count > ep->xfer_len)) {
+ DCD_EP_Stall(pdev, 0x80);
+ DCD_EP_Stall(pdev, 0x00);
+ csr0l.b.data_end = 1;
+ csr0l.b.serviced_rxpktrdy = 1;
+ USB_OTG_WRITE_REG8(&pdev->regs.INDEXREGS->CSRL.CSR0L, csr0l.d8);
+ ep->xfer_buff = pdev->dev.setup_packet;
+ ep->xfer_count = 0;
+ ep->xfer_len = 8;
+ USB_OTG_EP0_OutStart(pdev);
+ return retval;
+ }
+ rxRemain = ep->xfer_len - ep->xfer_count;
+ if (rxLength > rxRemain) {
+ DCD_EP_Stall(pdev, 0x80);
+ DCD_EP_Stall(pdev, 0x00);
+ csr0l.b.data_end = 1;
+ csr0l.b.serviced_rxpktrdy = 1;
+ USB_OTG_WRITE_REG8(&pdev->regs.INDEXREGS->CSRL.CSR0L, csr0l.d8);
+ ep->xfer_buff = pdev->dev.setup_packet;
+ ep->xfer_count = 0;
+ ep->xfer_len = 8;
+ USB_OTG_EP0_OutStart(pdev);
+ return retval;
+ }
/* Copy the setup packet received in FIFO into the setup buffer in RAM */
USB_OTG_ReadPacket(pdev, ep->xfer_buff + ep->xfer_count, 0, rxLength);
ep->xfer_count += rxLength;
@@ -218,6 +244,9 @@ static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev, uint16_t ep_intr)
USB_OTG_TXCSRL_IN_PERIPHERAL_TypeDef txcsrl;
uint16_t epnum = 0;
while (ep_intr) {
+ if (epnum >= USB_OTG_MAX_EP_COUNT) {
+ break;
+ }
if (ep_intr & 0x01) { /* In ITR */
txcsrl.d8 = USB_OTG_READ_REG8(&pdev->regs.CSRREGS[epnum]->TXCSRL);
if (!txcsrl.b.tx_pkt_rdy) {
@@ -253,24 +282,46 @@ static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev, uint16_t ep_intr)
{
USB_OTG_RXCSRL_IN_PERIPHERAL_TypeDef rxcsrl;
USB_OTG_RXCOUNT_TypeDef rx_count;
+ USB_OTG_EP *ep;
uint32_t epnum = 1;
- uint32_t rx_fifo_len = 0;
+ uint32_t rx_len = 0;
+ uint32_t rx_remain = 0;
ep_intr >>= 1;
while (ep_intr) {
+ if (epnum >= USB_OTG_MAX_EP_COUNT) {
+ break;
+ }
if (ep_intr & 0x1) {
+ ep = &pdev->dev.out_ep[epnum];
rxcsrl.d8 = USB_OTG_READ_REG8(&pdev->regs.CSRREGS[epnum]->RXCSRL);
/* Transfer complete */
if (rxcsrl.b.rx_pkt_rdy) {
/* Inform upper layer: data ready */
- rx_count.d16 = USB_OTG_READ_REG8(&pdev->regs.CSRREGS[epnum]->RXCOUNT);
- rx_fifo_len = MIN(rx_count.d16, pdev->dev.out_ep[epnum].maxpacket);
- USB_OTG_ReadPacket(pdev,
- pdev->dev.out_ep[epnum].xfer_buff + pdev->dev.out_ep[epnum].xfer_count,
- epnum,
- rx_count.d16);
- pdev->dev.out_ep[epnum].xfer_count += rx_fifo_len;
- /* RX COMPLETE */
+ rx_count.d16 = USB_OTG_READ_REG16(&pdev->regs.CSRREGS[epnum]->RXCOUNT);
+ rx_len = rx_count.d16;
+
+ if ((ep->xfer_buff == NULL) || (ep->xfer_count > ep->xfer_len)) {
+ DCD_EP_Stall(pdev, (uint8_t)epnum);
+ rxcsrl.b.rx_pkt_rdy = 0;
+ USB_OTG_WRITE_REG8(&pdev->regs.CSRREGS[epnum]->RXCSRL, rxcsrl.d8);
+ ep_intr >>= 1;
+ epnum++;
+ continue;
+ }
+
+ rx_remain = ep->xfer_len - ep->xfer_count;
+ if ((rx_len > ep->maxpacket) || (rx_len > rx_remain)) {
+ DCD_EP_Stall(pdev, (uint8_t)epnum);
+ rxcsrl.b.rx_pkt_rdy = 0;
+ USB_OTG_WRITE_REG8(&pdev->regs.CSRREGS[epnum]->RXCSRL, rxcsrl.d8);
+ ep_intr >>= 1;
+ epnum++;
+ continue;
+ }
+
+ USB_OTG_ReadPacket(pdev, ep->xfer_buff + ep->xfer_count, epnum, (uint16_t)rx_len);
+ ep->xfer_count += rx_len;
USBD_DCD_INT_fops->DataOutStage(pdev, epnum);
}
/* Endpoint disable */
diff --git a/src/boot_update.c b/src/boot_update.c
new file mode 100644
index 0000000..c5f7c81
--- /dev/null
+++ b/src/boot_update.c
@@ -0,0 +1,124 @@
+#ifdef BUILD_PRODUCTION
+#include "define.h"
+#include "mhscpu.h"
+#include "user_fatfs.h"
+#include "user_memory.h"
+#include "draw_on_lcd.h"
+#include "sha256.h"
+#include "gui_model.h"
+#include "cmsis_os2.h"
+#include "drv_qspi_flash.h"
+
+LV_FONT_DECLARE(openSans_24);
+
+#define BOOT_ADDR (0x01001000)
+#define SECTOR_SIZE 4096
+#define BOOT_HEAD_SIZE 0x104
+#define APP_ADDR (0x1001000 + 0x80000) //108 1000
+#define APP_CHECK_START_ADDR (APP_ADDR)
+#define APP_END_ADDR (0x2000000)
+static const uint8_t MAGIC_NUMBER[] = {'m', 'h', '1', '9', '0', '3', 'b', 'o', 'o', 't', 'u', 'p', 'd', 'a', 't', 'e'};
+
+static uint8_t g_fileUnit[4096] = {0};
+
+static uint32_t BinarySearchBootHead(void)
+{
+ size_t MAGIC_NUMBER_SIZE = sizeof(MAGIC_NUMBER);
+ uint8_t *buffer = SRAM_MALLOC(SECTOR_SIZE);
+ uint32_t startIndex = (APP_CHECK_START_ADDR - APP_ADDR) / SECTOR_SIZE;
+ uint32_t endIndex = (APP_END_ADDR - APP_ADDR) / SECTOR_SIZE;
+
+ for (int i = startIndex + 1; i < endIndex; i++) {
+ memcpy_s(buffer, SECTOR_SIZE, (uint32_t *)(APP_ADDR + i * SECTOR_SIZE), SECTOR_SIZE);
+ if (memcmp(buffer, MAGIC_NUMBER, MAGIC_NUMBER_SIZE) == 0) {
+ printf("find magic number\n");
+ return i;
+ }
+ }
+ SRAM_FREE(buffer);
+ return -1;
+}
+
+static void Delay(uint32_t ms)
+{
+ uint32_t i, tick, countPerMs;
+ countPerMs = SYSCTRL->HCLK_1MS_VAL / 4;
+ for (tick = 0; tick < ms; tick++) {
+ for (i = 0; i < countPerMs; i++) {
+ if (i > 10000000) {
+ printf("!!\r\n");
+ }
+ }
+ }
+}
+
+int32_t UpdateBootFromFlash(void)
+{
+ osKernelLock();
+ int num = BinarySearchBootHead();
+ printf("num = %d\n", num);
+ if (num <= 0) {
+ osKernelUnlock();
+ return false;
+ }
+ uint32_t len, offset, crcCalc, readCrc, writeAddr = 0x1001000;
+ uint32_t baseAddr = APP_ADDR + num * SECTOR_SIZE;
+ int startNum = num + 1;
+ uint8_t hash[32] = {0};
+ uint8_t calHash[32] = {0};
+ size_t MAGIC_NUMBER_SIZE = sizeof(MAGIC_NUMBER);
+
+ struct sha256_ctx ctx;
+ sha256_init(&ctx);
+ QspiFlashInit();
+
+ memset(g_fileUnit, 0xFF, sizeof(g_fileUnit));
+
+ memcpy(g_fileUnit, (uint32_t *)baseAddr, 4 + 32 + MAGIC_NUMBER_SIZE);
+ uint32_t bootLen = (g_fileUnit[MAGIC_NUMBER_SIZE + 0] << 24) + (g_fileUnit[MAGIC_NUMBER_SIZE + 1] << 16) + (g_fileUnit[MAGIC_NUMBER_SIZE + 2] << 8) + g_fileUnit[MAGIC_NUMBER_SIZE + 3];
+ printf("bootLen = %d\n", bootLen);
+ memcpy(hash, &g_fileUnit[MAGIC_NUMBER_SIZE + 4], 32);
+
+ memset(g_fileUnit, 0xFF, sizeof(g_fileUnit));
+ memcpy(g_fileUnit, (uint32_t *)(baseAddr + 4 + 32 + 0x30 + MAGIC_NUMBER_SIZE), BOOT_HEAD_SIZE);
+ QspiFlashEraseAndWrite(0x01000000, g_fileUnit, 4096);
+
+ sha256_update(&ctx, (uint32_t *)(baseAddr + 4 + 32 + MAGIC_NUMBER_SIZE), 0x134);
+ crcCalc = crc32_ieee(0, (uint32_t *)(baseAddr + 4 + 32 + MAGIC_NUMBER_SIZE), 0x134);
+
+ for (int i = startNum; i <= startNum + (bootLen - 0x134) / SECTOR_SIZE; i++, writeAddr += SECTOR_SIZE) {
+ Delay(100);
+ memset(g_fileUnit, 0xFF, sizeof(g_fileUnit));
+ if (i == startNum + (bootLen - 0x134) / SECTOR_SIZE) {
+ len = (bootLen - 0x134) % SECTOR_SIZE - 4;
+ sha256_update(&ctx, (uint32_t *)(APP_ADDR + i * SECTOR_SIZE), len + 4);
+ memcpy(&readCrc, (uint32_t *)(APP_ADDR + i * SECTOR_SIZE + len), 4);
+ } else {
+ len = SECTOR_SIZE;
+ sha256_update(&ctx, (uint32_t *)(APP_ADDR + i * SECTOR_SIZE), len);
+ }
+ memcpy(g_fileUnit, (uint32_t *)(APP_ADDR + i * SECTOR_SIZE), len);
+ crcCalc = crc32_ieee(crcCalc, (uint32_t *)(APP_ADDR + i * SECTOR_SIZE), len);
+ printf("writeAddr = %#x\n", writeAddr);
+ QspiFlashEraseAndWrite(writeAddr, g_fileUnit, SECTOR_SIZE);
+ }
+
+ sha256_done(&ctx, (struct sha256 *)calHash);
+
+ osKernelUnlock();
+ PrintArray("hash", hash, 32);
+ PrintArray("calHash", calHash, 32);
+ printf("crcCalc = %#x\n", crcCalc);
+ printf("readCrc = %#x\n", readCrc);
+ if (memcmp(hash, calHash, 32) == 0) {
+ printf("update success\n");
+ memset(g_fileUnit, 0xFF, sizeof(g_fileUnit));
+ QspiFlashEraseAndWrite((uint32_t *)(APP_END_ADDR - 4096), g_fileUnit, 4096);
+ memset(g_fileUnit, 0, sizeof(g_fileUnit));
+ return 0;
+ } else {
+ printf("update failed\n");
+ return -1;
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/boot_update.h b/src/boot_update.h
new file mode 100644
index 0000000..ec77e73
--- /dev/null
+++ b/src/boot_update.h
@@ -0,0 +1,7 @@
+#ifndef _BOOT_UPDATE_H
+#define _BOOT_UPDATE_H
+
+int32_t UpdateBootFromFlash(void);
+
+#endif /* _BOOT_UPDATE_H */
+
diff --git a/src/config/mhscpu_conf.h b/src/config/mhscpu_conf.h
index 9ea1a3c..8afdc1e 100644
--- a/src/config/mhscpu_conf.h
+++ b/src/config/mhscpu_conf.h
@@ -26,6 +26,7 @@
#include "mhscpu_ssc.h"
#include "mhscpu_adc.h"
#include "mhscpu_otp.h"
+#include "mhscpu_qspi.h"
#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
#include "string.h"
diff --git a/src/config/version.c b/src/config/version.c
index 22954d1..d9e0b90 100644
--- a/src/config/version.c
+++ b/src/config/version.c
@@ -84,6 +84,22 @@ void GetBootVersionNumber(char *version)
snprintf(version, SOFTWARE_VERSION_MAX_LEN, "%d.%d.%d", major, minor, build);
}
+#ifdef BUILD_PRODUCTION
+bool NeedUpdateBoot(void)
+{
+#ifndef BUILD_PRODUCTION
+ return false;
+#endif
+ uint32_t major, minor, build;
+ if (GetBootSoftwareVersion(&major, &minor, &build) == false) {
+ return true;
+ }
+ if (major == 0 && minor == 3 && build == 0) {
+ return false;
+ }
+ return true;
+}
+
bool GetBootSoftwareVersion(uint32_t *major, uint32_t *minor, uint32_t *build)
{
#ifdef COMPILE_SIMULATOR
@@ -137,3 +153,9 @@ static bool GetBootSoftwareVersionFormData(uint32_t *major, uint32_t *minor, uin
}
return succ;
}
+#else
+bool NeedUpdateBoot(void)
+{
+ return false;
+}
+#endif
\ No newline at end of file
diff --git a/src/config/version.h b/src/config/version.h
index b6044a8..2fcc745 100644
--- a/src/config/version.h
+++ b/src/config/version.h
@@ -6,8 +6,8 @@
#define SOFTWARE_VERSION_MAX_LEN (32)
#define SOFTWARE_VERSION_MAJOR 12
#define SOFTWARE_VERSION_MAJOR_OFFSET 10
-#define SOFTWARE_VERSION_MINOR 3
-#define SOFTWARE_VERSION_BUILD 10
+#define SOFTWARE_VERSION_MINOR 4
+#define SOFTWARE_VERSION_BUILD 0
#define SOFTWARE_VERSION_BETA 1
#define SOFTWARE_VERSION (SOFTWARE_VERSION_MAJOR * 10000 + SOFTWARE_VERSION_MINOR * 100 + SOFTWARE_VERSION_BUILD)
#ifdef WEB3_VERSION
@@ -26,6 +26,7 @@
#error "Invalid software version"
#endif
+#ifdef BUILD_PRODUCTION
void GetSoftWareVersion(char *version);
void GetSoftWareVersionNumber(char *version);
const char *GetSoftwareVersionString(void);
@@ -33,6 +34,8 @@ void GetUpdateVersionNumber(char *version);
bool GetBootSoftwareVersion(uint32_t *major, uint32_t *minor, uint32_t *build);
bool IsBootVersionMatch(void);
void GetBootVersionNumber(char *version);
+#endif
+bool NeedUpdateBoot(void);
#endif
diff --git a/src/crypto/checksum/md5.c b/src/crypto/checksum/md5.c
deleted file mode 100644
index a2ae1be..0000000
--- a/src/crypto/checksum/md5.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
- * MD5 Message-Digest Algorithm (RFC 1321).
- *
- * Homepage:
- * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
- *
- * Author:
- * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
- *
- * This software was written by Alexander Peslyak in 2001. No copyright is
- * claimed, and the software is hereby placed in the public domain.
- * In case this attempt to disclaim copyright and place the software in the
- * public domain is deemed null and void, then the software is
- * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
- * general public under the following terms:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted.
- *
- * There's ABSOLUTELY NO WARRANTY, express or implied.
- *
- * (This is a heavily cut-down "BSD license".)
- *
- * This differs from Colin Plumb's older public domain implementation in that
- * no exactly 32-bit integer data type is required (any 32-bit or wider
- * unsigned integer data type will do), there's no compile-time endianness
- * configuration, and the function prototypes match OpenSSL's. No code from
- * Colin Plumb's implementation has been reused; this comment merely compares
- * the properties of the two independent implementations.
- *
- * The primary goals of this implementation are portability and ease of use.
- * It is meant to be fast, but not as fast as possible. Some known
- * optimizations are not included to reduce source code size and avoid
- * compile-time configuration.
- */
-
-#ifndef HAVE_OPENSSL
-
-#include <string.h>
-
-#include "md5.h"
-
-/*
- * The basic MD5 functions.
- *
- * F and G are optimized compared to their RFC 1321 definitions for
- * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
- * implementation.
- */
-#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
-#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
-#define H(x, y, z) (((x) ^ (y)) ^ (z))
-#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-
-/*
- * The MD5 transformation for all four rounds.
- */
-#define STEP(f, a, b, c, d, x, t, s) \
- (a) += f((b), (c), (d)) + (x) + (t); \
- (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
- (a) += (b);
-
-/*
- * SET reads 4 input bytes in little-endian byte order and stores them in a
- * properly aligned word in host byte order.
- *
- * The check for little-endian architectures that tolerate unaligned memory
- * accesses is just an optimization. Nothing will break if it fails to detect
- * a suitable architecture.
- *
- * Unfortunately, this optimization may be a C strict aliasing rules violation
- * if the caller's data buffer has effective type that cannot be aliased by
- * MD5_u32plus. In practice, this problem may occur if these MD5 routines are
- * inlined into a calling function, or with future and dangerously advanced
- * link-time optimizations. For the time being, keeping these MD5 routines in
- * their own translation unit avoids the problem.
- */
-#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
-#define SET(n) \
- (*(MD5_u32plus *)&ptr[(n) * 4])
-#define GET(n) \
- SET(n)
-#else
-#define SET(n) \
- (ctx->block[(n)] = \
- (MD5_u32plus)ptr[(n) * 4] | \
- ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
- ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
- ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
-#define GET(n) \
- (ctx->block[(n)])
-#endif
-
-/*
- * This processes one or more 64-byte data blocks, but does NOT update the bit
- * counters. There are no alignment requirements.
- */
-static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
-{
- const unsigned char *ptr;
- MD5_u32plus a, b, c, d;
- MD5_u32plus saved_a, saved_b, saved_c, saved_d;
-
- ptr = (const unsigned char *)data;
-
- a = ctx->a;
- b = ctx->b;
- c = ctx->c;
- d = ctx->d;
-
- do {
- saved_a = a;
- saved_b = b;
- saved_c = c;
- saved_d = d;
-
- /* Round 1 */
- STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
- STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
- STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
- STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
- STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
- STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
- STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
- STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
- STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
- STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
- STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
- STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
- STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
- STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
- STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
- STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
-
- /* Round 2 */
- STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
- STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
- STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
- STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
- STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
- STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
- STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
- STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
- STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
- STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
- STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
- STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
- STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
- STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
- STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
- STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
-
- /* Round 3 */
- STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
- STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
- STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
- STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
- STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
- STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
- STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
- STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
- STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
- STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
- STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
- STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
- STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
- STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
- STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
- STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
-
- /* Round 4 */
- STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
- STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
- STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
- STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
- STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
- STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
- STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
- STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
- STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
- STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
- STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
- STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
- STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
- STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
- STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
- STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
-
- a += saved_a;
- b += saved_b;
- c += saved_c;
- d += saved_d;
-
- ptr += 64;
- } while (size -= 64);
-
- ctx->a = a;
- ctx->b = b;
- ctx->c = c;
- ctx->d = d;
-
- return ptr;
-}
-
-void MD5_Init(MD5_CTX *ctx)
-{
- ctx->a = 0x67452301;
- ctx->b = 0xefcdab89;
- ctx->c = 0x98badcfe;
- ctx->d = 0x10325476;
-
- ctx->lo = 0;
- ctx->hi = 0;
-}
-
-void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
-{
- MD5_u32plus saved_lo;
- unsigned long used, available;
-
- saved_lo = ctx->lo;
- if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
- ctx->hi++;
- ctx->hi += size >> 29;
-
- used = saved_lo & 0x3f;
-
- if (used) {
- available = 64 - used;
-
- if (size < available) {
- memcpy(&ctx->buffer[used], data, size);
- return;
- }
-
- memcpy(&ctx->buffer[used], data, available);
- data = (const unsigned char *)data + available;
- size -= available;
- body(ctx, ctx->buffer, 64);
- }
-
- if (size >= 64) {
- data = body(ctx, data, size & ~(unsigned long)0x3f);
- size &= 0x3f;
- }
-
- memcpy(ctx->buffer, data, size);
-}
-
-#define OUT(dst, src) \
- (dst)[0] = (unsigned char)(src); \
- (dst)[1] = (unsigned char)((src) >> 8); \
- (dst)[2] = (unsigned char)((src) >> 16); \
- (dst)[3] = (unsigned char)((src) >> 24);
-
-void MD5_Final(unsigned char *result, MD5_CTX *ctx)
-{
- unsigned long used, available;
-
- used = ctx->lo & 0x3f;
-
- ctx->buffer[used++] = 0x80;
-
- available = 64 - used;
-
- if (available < 8) {
- memset(&ctx->buffer[used], 0, available);
- body(ctx, ctx->buffer, 64);
- used = 0;
- available = 64;
- }
-
- memset(&ctx->buffer[used], 0, available - 8);
-
- ctx->lo <<= 3;
- OUT(&ctx->buffer[56], ctx->lo)
- OUT(&ctx->buffer[60], ctx->hi)
-
- body(ctx, ctx->buffer, 64);
-
- OUT(&result[0], ctx->a)
- OUT(&result[4], ctx->b)
- OUT(&result[8], ctx->c)
- OUT(&result[12], ctx->d)
-
- memset(ctx, 0, sizeof(*ctx));
-}
-
-#endif
diff --git a/src/crypto/checksum/md5.h b/src/crypto/checksum/md5.h
deleted file mode 100644
index 6c1d3fd..0000000
--- a/src/crypto/checksum/md5.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
- * MD5 Message-Digest Algorithm (RFC 1321).
- *
- * Homepage:
- * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
- *
- * Author:
- * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
- *
- * This software was written by Alexander Peslyak in 2001. No copyright is
- * claimed, and the software is hereby placed in the public domain.
- * In case this attempt to disclaim copyright and place the software in the
- * public domain is deemed null and void, then the software is
- * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
- * general public under the following terms:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted.
- *
- * There's ABSOLUTELY NO WARRANTY, express or implied.
- *
- * See md5.c for more information.
- */
-
-#ifdef HAVE_OPENSSL
-#include <openssl/md5.h>
-#elif !defined(_MD5_H)
-#define _MD5_H
-
-/* Any 32-bit or wider unsigned integer data type will do */
-typedef unsigned int MD5_u32plus;
-
-typedef struct {
- MD5_u32plus lo, hi;
- MD5_u32plus a, b, c, d;
- unsigned char buffer[64];
- MD5_u32plus block[16];
-} MD5_CTX;
-
-extern void MD5_Init(MD5_CTX *ctx);
-extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
-extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
-
-#endif
diff --git a/src/driver/drv_atecc608b.c b/src/driver/drv_atecc608b.c
index 90e4227..0d22d58 100644
--- a/src/driver/drv_atecc608b.c
+++ b/src/driver/drv_atecc608b.c
@@ -158,6 +158,7 @@ int32_t Atecc608bKdf(uint8_t slot, const uint8_t *authKey, const uint8_t *inData
uint8_t nonce[32];
uint8_t ioProtectKey[32];
uint8_t authSlot;
+ uint32_t retry;
do {
authSlot = GetAuthSlot(slot);
@@ -165,24 +166,29 @@ int32_t Atecc608bKdf(uint8_t slot, const uint8_t *authKey, const uint8_t *inData
ret = ERR_ATECC608B_SLOT_NUM_ERR;
break;
}
- ret = Atecc608bAuthorize(authSlot, authKey);
- CHECK_ATECC608B_RET("auth", ret);
- ret = atcab_kdf(KDF_MODE_SOURCE_SLOT | KDF_MODE_TARGET_OUTPUT_ENC | KDF_MODE_ALG_HKDF,
- slot, KDF_DETAILS_HKDF_MSG_LOC_INPUT | (inLen << 24), inData, outData, nonce);
+ for (retry = 0; retry < 3; retry++) {
+ ret = Atecc608bAuthorize(authSlot, authKey);
+ if (ret != ATCA_SUCCESS) {
+ continue;
+ }
+ ret = atcab_kdf(KDF_MODE_SOURCE_SLOT | KDF_MODE_TARGET_OUTPUT_ENC | KDF_MODE_ALG_HKDF,
+ slot, KDF_DETAILS_HKDF_MSG_LOC_INPUT | (inLen << 24), inData, outData, nonce);
+ if (ret != ATCA_SUCCESS) {
+ continue;
+ }
+ GetIoProtectKey(ioProtectKey);
+ atca_io_decrypt_in_out_t io_dec_params = {
+ .io_key = ioProtectKey,
+ .out_nonce = nonce,
+ .data = outData,
+ .data_size = 32,
+ };
+ ret = atcah_io_decrypt(&io_dec_params);
+ if (ret == ATCA_SUCCESS) {
+ break;
+ }
+ }
CHECK_ATECC608B_RET("kdf", ret);
- //PrintArray("outData", outData, 32);
- //PrintArray("nonce", nonce, 32);
- GetIoProtectKey(ioProtectKey);
- atca_io_decrypt_in_out_t io_dec_params = {
- .io_key = ioProtectKey,
- .out_nonce = nonce,
- .data = outData,
- .data_size = 32,
- };
- ret = atcah_io_decrypt(&io_dec_params);
- CHECK_ATECC608B_RET("atcah_io_decrypt", ret);
- //PrintArray("outData", outData, 32);
- //PrintArray("nonce", nonce, 32);
} while (0);
CLEAR_ARRAY(nonce);
CLEAR_ARRAY(ioProtectKey);
diff --git a/src/driver/drv_mpu.c b/src/driver/drv_mpu.c
index cfc5e32..de1fab8 100644
--- a/src/driver/drv_mpu.c
+++ b/src/driver/drv_mpu.c
@@ -5,6 +5,33 @@ static bool g_otpProtect = false;
extern uint32_t _sbss;
extern uint32_t _ebss;
+static uint8_t MpuRegionSizeField(uint32_t regionSize)
+{
+ if (regionSize <= MPU_REGION_SIZE_4G) {
+ return (uint8_t)regionSize;
+ }
+
+ uint32_t sizeBytes = 32U;
+ uint8_t sizeField = MPU_REGION_SIZE_32B;
+ while ((sizeBytes < regionSize) && (sizeField < MPU_REGION_SIZE_4G)) {
+ sizeBytes <<= 1U;
+ sizeField++;
+ }
+ return sizeField;
+}
+
+static void ConfigureMPUForSramNoExec(void)
+{
+ MpuSetProtection(MHSCPU_SRAM_BASE,
+ MHSCPU_SRAM_SIZE,
+ MPU_REGION_NUMBER7,
+ MPU_INSTRUCTION_ACCESS_DISABLE,
+ MPU_REGION_FULL_ACCESS,
+ MPU_ACCESS_NOT_SHAREABLE,
+ MPU_ACCESS_CACHEABLE,
+ MPU_ACCESS_BUFFERABLE);
+}
+
void MpuDisable(void)
{
__DMB();
@@ -51,7 +78,7 @@ void MpuSetProtection(uint32_t baseAddress, uint32_t regionSize, uint32_t region
mpu.Enable = MPU_REGION_ENABLE;
mpu.Number = regionNum;
mpu.BaseAddress = baseAddress;
- mpu.Size = regionSize;
+ mpu.Size = MpuRegionSizeField(regionSize);
mpu.SubRegionDisable = 0x00;
mpu.TypeExtField = MPU_TEX_LEVEL0;
mpu.AccessPermission = accessPermission;
@@ -90,7 +117,7 @@ void ConfigureMPUForBSS(void)
void MpuInit(void)
{
- ConfigureMPUForBSS();
+ ConfigureMPUForSramNoExec();
MpuSetOtpProtection(true);
}
@@ -111,4 +138,3 @@ void MpuSetOtpProtection(bool noAccess)
MPU_ACCESS_CACHEABLE,
MPU_ACCESS_BUFFERABLE);
}
-
diff --git a/src/driver/drv_qspi_flash.c b/src/driver/drv_qspi_flash.c
new file mode 100644
index 0000000..d573142
--- /dev/null
+++ b/src/driver/drv_qspi_flash.c
@@ -0,0 +1,181 @@
+#ifdef BUILD_PRODUCTION
+#include "drv_qspi_flash.h"
+#include "stdio.h"
+#include "mhscpu.h"
+#include "assert.h"
+#include "mh_rand.h"
+#include "mhscpu_qspi.h"
+
+static uint32_t CheckFlashType(void);
+
+QSPI_CommandTypeDef g_cmdType;
+
+/// @brief QSPI flash init, get model.
+/// @param
+void QspiFlashInit(void)
+{
+ uint32_t chipType;
+
+ SYSCTRL_AHBPeriphClockCmd(SYSCTRL_AHBPeriph_DMA | SYSCTRL_AHBPeriph_CRYPT, ENABLE);
+ SYSCTRL_AHBPeriphResetCmd(SYSCTRL_AHBPeriph_DMA | SYSCTRL_AHBPeriph_CRYPT, ENABLE);
+ SYSCTRL_APBPeriphClockCmd(SYSCTRL_APBPeriph_TRNG, ENABLE);
+ SYSCTRL_APBPeriphResetCmd(SYSCTRL_APBPeriph_TRNG, ENABLE);
+ mh_rand_init();
+ QSPI_Init(NULL);
+ QSPI_SetLatency(0);
+ chipType = CheckFlashType();
+ if (chipType == QSPI_SUPPORT_CHIP_JEDEC_ID_MICR) {
+ g_cmdType.Instruction = PAGE_PROG_CMD;
+ g_cmdType.BusMode = QSPI_BUSMODE_111;
+ g_cmdType.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24_PDAT;
+ } else {
+ g_cmdType.Instruction = QUAD_INPUT_PAGE_PROG_CMD;
+ g_cmdType.BusMode = QSPI_BUSMODE_114;
+ g_cmdType.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24_PDAT;
+ }
+}
+
+
+/// @brief Erase flash sector.
+/// @param addr Erase address.
+void QspiFlashErase(uint32_t addr)
+{
+ FLASH_EraseSector(addr);
+}
+
+
+/// @brief
+/// @param addr Write flash addr.
+/// @param data
+/// @param len
+void QspiFlashWrite(uint32_t addr, const uint8_t *data, uint32_t len)
+{
+#ifdef __ARMCC_VERSION
+ //FLASH_ProgramPage(&g_cmdType, NULL, addr, len, (uint8_t *)data);
+ AES_Program(&g_cmdType, NULL, addr, len, (uint8_t *)data);
+#else
+ QSPI_ProgramPage(&g_cmdType, NULL, addr, len, (uint8_t *)data);
+#endif
+}
+
+#include "log_print.h"
+/// @brief
+/// @param addr Write flash addr.
+/// @param data
+/// @param len
+void QspiFlashEraseAndWrite(uint32_t addr, const uint8_t *data, uint32_t len)
+{
+ ASSERT(len == 4096);
+
+ do {
+ __disable_irq();
+ FLASH_EraseSector(addr);
+ CACHE_CleanAll(CACHE);
+ AES_Program(&g_cmdType, NULL, addr, len, (uint8_t *)data);
+ if (memcmp(data, (uint8_t *)addr, len) == 0) {
+ printf("read back check ok %#x\n", addr);
+ break;
+ } else {
+ printf("encrypt check error....... %#x\n", addr);
+ PrintArray("write", data, len);
+ PrintArray("read", (uint8_t *)addr, len);
+ }
+ } while (0);
+ __enable_irq();
+}
+
+
+/// @brief Get flash type.
+/// @param
+/// @return
+static uint32_t CheckFlashType(void)
+{
+ uint32_t chip_type;
+ QSPI_CommandTypeDef test_cmd;
+
+ ROM_QSPI_ReleaseDeepPowerDown(NULL);
+
+ chip_type = ROM_QSPI_ReadID(NULL);
+ printf("FLASH ID = %#x \n", chip_type);
+ if (chip_type == 0xffffff) {
+ test_cmd.Instruction = 0x9F;
+ test_cmd.BusMode = QSPI_BUSMODE_444;
+ test_cmd.CmdFormat = QSPI_CMDFORMAT_CMD8_RREG24;
+ chip_type = ROM_QSPI_ReadID(&test_cmd);
+ printf("ReRead_FLASH ID = %#x \n", chip_type);
+ }
+
+ chip_type = chip_type >> 16;
+ switch (chip_type) {
+ case QSPI_SUPPORT_CHIP_JEDEC_ID_MICR: //MICRON
+ printf("QSPI Flash chip is MICRON\n");
+
+ //burst
+ test_cmd.Instruction = 0x81;
+ test_cmd.BusMode = QSPI_BUSMODE_111;
+ test_cmd.CmdFormat = QSPI_CMDFORMAT_CMD8_WREG8;
+ ROM_QSPI_WriteParam(&test_cmd, 0xF1);
+
+ CACHE->CACHE_CONFIG = (CACHE->CACHE_CONFIG & 0xFF00FFFF) | (0xA5 << 16);
+
+ test_cmd.Instruction = 0x61;
+ test_cmd.BusMode = QSPI_BUSMODE_111;
+ test_cmd.CmdFormat = QSPI_CMDFORMAT_CMD8_WREG16;
+ ROM_QSPI_WriteParam(&test_cmd, 0x4F);
+ break;
+
+ case QSPI_SUPPORT_CHIP_JEDEC_ID_MXIC: //MXIC
+ printf("QSPI Flash chip is MXIC\n");
+
+ test_cmd.Instruction = 0xC0;
+ test_cmd.BusMode = QSPI_BUSMODE_111;
+ test_cmd.CmdFormat = QSPI_CMDFORMAT_CMD8_WREG8;
+ ROM_QSPI_WriteParam(&test_cmd, 0x02); ///< 32Bytes
+
+ CACHE->CACHE_CONFIG = (CACHE->CACHE_CONFIG & 0xFF00FFFF) | (0xA5 << 16);
+
+ test_cmd.Instruction = 0x01;
+ test_cmd.BusMode = QSPI_BUSMODE_111;
+ test_cmd.CmdFormat = QSPI_CMDFORMAT_CMD8_WREG16;
+ ROM_QSPI_WriteParam(&test_cmd, 0x0042); ///< QE WEL
+ break;
+
+ case QSPI_SUPPORT_CHIP_JEDEC_ID_WD: //Winbond
+ printf("QSPI Flash chip is Winbond\n");
+
+ test_cmd.Instruction = WRITE_STATUS_REG1_CMD;
+ test_cmd.BusMode = QSPI_BUSMODE_111;
+ test_cmd.CmdFormat = QSPI_CMDFORMAT_CMD8_WREG16;
+ ROM_QSPI_WriteParam(&test_cmd, 0x0202);
+
+ test_cmd.Instruction = SET_BURST_WITH_WRAP;
+ test_cmd.BusMode = QSPI_BUSMODE_144;
+ test_cmd.CmdFormat = QSPI_CMDFORMAT_CMD8_DMY24_WREG8;
+ ROM_QSPI_WriteParam(&test_cmd, 0x40);
+
+ CACHE->CACHE_CONFIG = (CACHE->CACHE_CONFIG & 0xFF00FFFF) | (0xA5 << 16);
+ break;
+
+ case QSPI_SUPPORT_CHIP_JEDEC_ID_GD: ///< GD
+ printf("QSPI Flash chip is GD\n");
+
+ test_cmd.Instruction = WRITE_STATUS_REG1_CMD; ///< Write Status Register
+ test_cmd.BusMode = QSPI_BUSMODE_111;
+ test_cmd.CmdFormat = QSPI_CMDFORMAT_CMD8_WREG16;
+ ROM_QSPI_WriteParam(&test_cmd, 0x0200); ///< QE(low byte first, MSB first)
+
+ test_cmd.Instruction = SET_BURST_WITH_WRAP; ///< Set Burst with Wrap
+ test_cmd.BusMode = QSPI_BUSMODE_144;
+ test_cmd.CmdFormat = QSPI_CMDFORMAT_CMD8_DMY24_WREG8;
+ ROM_QSPI_WriteParam(&test_cmd, 0x40); ///< Wrap Length:32Bytes
+
+ CACHE->CACHE_CONFIG = (CACHE->CACHE_CONFIG & 0xFF00FFFF) | (0xA5 << 16);
+ break;
+
+ default:
+ printf("QSPI Flash chip Not Support\n");
+ break;
+ }
+ return chip_type;
+}
+#endif
\ No newline at end of file
diff --git a/src/driver/drv_qspi_flash.h b/src/driver/drv_qspi_flash.h
new file mode 100644
index 0000000..56a281c
--- /dev/null
+++ b/src/driver/drv_qspi_flash.h
@@ -0,0 +1,28 @@
+#ifndef _DRV_QSPI_FLASH_H
+#define _DRV_QSPI_FLASH_H
+
+#include "stdint.h"
+#include "stdbool.h"
+#include "err_code.h"
+#include "mhscpu_qspi.h"
+
+/// @brief QSPI flash init, get model.
+/// @param
+void QspiFlashInit(void);
+
+
+/// @brief Get battery voltage.
+/// @param addr Erase address.
+void QspiFlashErase(uint32_t addr);
+
+
+/// @brief
+/// @param addr Write flash addr.
+/// @param data
+/// @param len
+void QspiFlashWrite(uint32_t addr, const uint8_t *data, uint32_t len);
+
+void QspiFlashEraseAndWrite(uint32_t addr, const uint8_t *data, uint32_t len);
+
+
+#endif
diff --git a/src/driver/low_power.c b/src/driver/low_power.c
index 98f6f46..00073f8 100644
--- a/src/driver/low_power.c
+++ b/src/driver/low_power.c
@@ -152,11 +152,11 @@ void RecoverFromLowPower(void)
DS28S60_Open();
LcdInit();
LcdClear(0x0000);
+ LcdBacklightOn();
PubValueMsg(BACKGROUND_MSG_BATTERY_INTERVAL, 1);
SetLvglHandlerAndSnapShot(true);
g_lowPowerState = LOW_POWER_STATE_WORKING;
PubValueMsg(BACKGROUND_MSG_SD_CARD_CHANGE, 0);
- LcdBacklightOn();
#if (USB_POP_WINDOW_ENABLE == 0)
if (GetUSBSwitch() && GetUsbDetectState()) {
OpenUsb();
diff --git a/src/driver/usb/drv_usb.c b/src/driver/usb/drv_usb.c
index 5ec4189..62a5dc4 100644
--- a/src/driver/usb/drv_usb.c
+++ b/src/driver/usb/drv_usb.c
@@ -8,6 +8,10 @@ __ALIGN_BEGIN USB_OTG_CORE_HANDLE g_usbDev __ALIGN_END;
static volatile bool g_usbInit = false;
+#ifndef USB_IRQ_RTOS_SAFE_PRIO
+#define USB_IRQ_RTOS_SAFE_PRIO 1
+#endif
+
void UsbInit(void)
{
USBPHY_CR1_TypeDef usbphy_cr1;
@@ -27,6 +31,7 @@ void UsbInit(void)
memset_s(&g_usbDev, sizeof(g_usbDev), 0x00, sizeof(g_usbDev));
USBD_Init(&g_usbDev, USB_OTG_FS_CORE_ID, &USR_desc, DeviceCallback, &USRD_cb);
+ NVIC_SetPriority(USB_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), USB_IRQ_RTOS_SAFE_PRIO, 0));
g_usbInit = true;
}
}
@@ -64,4 +69,3 @@ bool UsbInitState(void)
return g_usbInit;
}
-
diff --git a/src/driver/usb/usbd_cdc_vcp.c b/src/driver/usb/usbd_cdc_vcp.c
index 75aaa51..b656e84 100644
--- a/src/driver/usb/usbd_cdc_vcp.c
+++ b/src/driver/usb/usbd_cdc_vcp.c
@@ -98,7 +98,10 @@ static uint16_t VCP_Ctrl(uint32_t Cmd, uint8_t* Buf, uint32_t Len)
break;
case SET_LINE_CODING:
- linecoding.bitrate = (uint32_t)(Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24));
+ if (Buf == NULL || Len < 7U) {
+ return USBD_FAIL;
+ }
+ linecoding.bitrate = (uint32_t)((uint32_t)Buf[0] | ((uint32_t)Buf[1] << 8) | ((uint32_t)Buf[2] << 16) | ((uint32_t)Buf[3] << 24));
linecoding.format = Buf[4];
linecoding.paritytype = Buf[5];
linecoding.datatype = Buf[6];
@@ -109,6 +112,9 @@ static uint16_t VCP_Ctrl(uint32_t Cmd, uint8_t* Buf, uint32_t Len)
break;
case GET_LINE_CODING:
+ if (Buf == NULL || Len < 7U) {
+ return USBD_FAIL;
+ }
Buf[0] = (uint8_t)(linecoding.bitrate);
Buf[1] = (uint8_t)(linecoding.bitrate >> 8);
Buf[2] = (uint8_t)(linecoding.bitrate >> 16);
@@ -179,7 +185,7 @@ uint32_t VCP_GetTxBuflen(void)
*/
uint8_t* VCP_GetTxBufrsaddr(void)
{
- return CDCData.SendBuffer->Buffer + CDCData.ReadBuffer->PushOffset;
+ return CDCData.SendBuffer->Buffer + CDCData.SendBuffer->PopOffset;
}
/**
diff --git a/src/driver/usb/usbd_composite.c b/src/driver/usb/usbd_composite.c
index ae73a29..50d5107 100644
--- a/src/driver/usb/usbd_composite.c
+++ b/src/driver/usb/usbd_composite.c
@@ -1,9 +1,11 @@
#include "usbd_composite.h"
#include "stdio.h"
+#include "string.h"
#include "usb_core.h"
#include "usbd_msc_core.h"
#include "usbd_cdc_core.h"
#include "usbd_desc.h"
+#include "usbd_req.h"
#include "log_print.h"
#include "usb_task.h"
@@ -20,6 +22,8 @@ static uint8_t CompositeSOF(void *pdev);
static uint8_t *GetCompositeConfigDescriptor(uint8_t speed, uint16_t *length);
static uint8_t *USBD_Composite_GetDeviceQualifierDescriptor(uint16_t *length);
static uint8_t *USBD_Composite_WinUSBOSStrDescriptor(uint16_t *length);
+static uint8_t AppendClassDescriptor(uint8_t *outDesc, uint16_t *length, uint8_t *descriptor, uint16_t descriptorSize, uint8_t interfaceIndex);
+static uint8_t CompositeSelectClass(USB_SETUP_REQ *req, uint8_t *isMsc);
__ALIGN_BEGIN static uint8_t CompositeConfigDescriptor[USB_COMPOSITE_CONFIG_DESC_MAX_SIZE] __ALIGN_END = {
0x09, /* bLength: Configuration Descriptor size */
@@ -44,6 +48,8 @@ __ALIGN_BEGIN static uint8_t CompositeConfigDescriptor[USB_COMPOSITE_CONFIG_DESC
};
static uint8_t g_interfaceCount = 0;
+static uint8_t g_mscInterfaceNo = 0xFF;
+static uint8_t g_cdcInterfaceNo = 0xFF;
USBD_Class_cb_TypeDef USBCompositeCb = {
CompositeInit,
@@ -84,13 +90,18 @@ static uint8_t CompositeDeInit(void *pdev, uint8_t cfgidx)
static uint8_t CompositeSetup(void *pdev, USB_SETUP_REQ *req)
{
- uint8_t index = LOBYTE(req->wIndex);
+ uint8_t isMsc = 0;
+ if (CompositeSelectClass(req, &isMsc) != USBD_OK) {
+ USBD_CtlError(pdev, req);
+ return USBD_FAIL;
+ }
- if (index == 0) {
+#ifdef USBD_ENABLE_MSC
+ if (isMsc != 0U) {
return USBD_MSC_cb.Setup(pdev, req);
- } else {
- return USBD_CDC_cb.Setup(pdev, req);
}
+#endif
+ return USBD_CDC_cb.Setup(pdev, req);
}
static uint8_t CompositeEP0_TxSent(void *pdev)
@@ -128,41 +139,111 @@ static uint8_t CompositeSOF(void* pdev)
return USBD_CDC_cb.SOF(pdev);
}
+static uint8_t AppendClassDescriptor(uint8_t *outDesc, uint16_t *length, uint8_t *descriptor, uint16_t descriptorSize, uint8_t interfaceIndex)
+{
+ if (outDesc == NULL || length == NULL || descriptor == NULL || descriptorSize < 9U) {
+ return 0U;
+ }
+
+ descriptorSize -= 9U;
+ if ((uint32_t)(*length) + descriptorSize > USB_COMPOSITE_CONFIG_DESC_MAX_SIZE) {
+ return 0U;
+ }
+
+ descriptor[9 + 2] = interfaceIndex;
+ memcpy(outDesc + *length, descriptor + 9U, descriptorSize);
+ *length += descriptorSize;
+ return 1U;
+}
+
static uint8_t *GetCompositeConfigDescriptor(uint8_t speed, uint16_t *length)
{
uint16_t descriptorSize = 0;
uint8_t *descriptor;
uint8_t interfaceIndex = 0;
+ uint8_t appendOk = 0;
g_interfaceCount = 0;
+ g_mscInterfaceNo = 0xFF;
+ g_cdcInterfaceNo = 0xFF;
*length = 9;
#ifdef USBD_ENABLE_MSC
//MSC
descriptor = USBD_MSC_cb.GetConfigDescriptor(speed, &descriptorSize);
- descriptorSize -= 9;
- descriptor[9 + 2] = interfaceIndex;
+ appendOk = AppendClassDescriptor(CompositeConfigDescriptor, length, descriptor, descriptorSize, interfaceIndex);
+ if (!appendOk) {
+ *length = 9;
+ return CompositeConfigDescriptor;
+ }
+ g_mscInterfaceNo = interfaceIndex;
interfaceIndex++;
- memcpy(CompositeConfigDescriptor + *length, descriptor + 9, descriptorSize);
- *length += descriptorSize;
g_interfaceCount++;
#endif
//CDC
descriptor = USBD_CDC_cb.GetConfigDescriptor(speed, &descriptorSize);
- descriptorSize -= 9;
- descriptor[9 + 2] = interfaceIndex;
- memcpy(CompositeConfigDescriptor + *length, descriptor + 9, descriptorSize);
- *length += descriptorSize;
+ appendOk = AppendClassDescriptor(CompositeConfigDescriptor, length, descriptor, descriptorSize, interfaceIndex);
+ if (!appendOk) {
+ *length = 9;
+ return CompositeConfigDescriptor;
+ }
+ g_cdcInterfaceNo = interfaceIndex;
g_interfaceCount++;
- CompositeConfigDescriptor[2] = *length;
+ CompositeConfigDescriptor[2] = (uint8_t)(*length & 0xFFU);
+ CompositeConfigDescriptor[3] = (uint8_t)((*length >> 8) & 0xFFU);
CompositeConfigDescriptor[4] = g_interfaceCount;
//printf("length=%d\r\n", *length);
//PrintArray("Descriptor", CompositeConfigDescriptor, *length);
return CompositeConfigDescriptor;
}
+static uint8_t CompositeSelectClass(USB_SETUP_REQ *req, uint8_t *isMsc)
+{
+ uint8_t recipient;
+ uint8_t index;
+ uint8_t epNum;
+
+ if (req == NULL || isMsc == NULL) {
+ return USBD_FAIL;
+ }
+
+ *isMsc = 0U;
+ recipient = req->bmRequest & USB_REQ_RECIPIENT_MASK;
+ index = LOBYTE(req->wIndex);
+
+ switch (recipient) {
+ case USB_REQ_RECIPIENT_INTERFACE:
+#ifdef USBD_ENABLE_MSC
+ if (index == g_mscInterfaceNo) {
+ *isMsc = 1U;
+ return USBD_OK;
+ }
+#endif
+ if (index == g_cdcInterfaceNo) {
+ return USBD_OK;
+ }
+ return USBD_FAIL;
+
+ case USB_REQ_RECIPIENT_ENDPOINT:
+ epNum = index & 0x7FU;
+#ifdef USBD_ENABLE_MSC
+ if ((epNum == (MSC_IN_EP & 0x7FU)) || (epNum == (MSC_OUT_EP & 0x7FU))) {
+ *isMsc = 1U;
+ return USBD_OK;
+ }
+#endif
+ if ((epNum == (CDC_IN_EP & 0x7FU)) || (epNum == (CDC_OUT_EP & 0x7FU))) {
+ return USBD_OK;
+ }
+ return USBD_FAIL;
+
+ default:
+ return USBD_FAIL;
+ }
+}
+
__ALIGN_BEGIN static uint8_t USBD_Composite_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = {
USB_LEN_DEV_QUALIFIER_DESC,
USB_DESC_TYPE_DEVICE_QUALIFIER,
diff --git a/src/driver/usb/usbd_desc.c b/src/driver/usb/usbd_desc.c
index ae902ae..beebcd6 100644
--- a/src/driver/usb/usbd_desc.c
+++ b/src/driver/usb/usbd_desc.c
@@ -146,7 +146,7 @@ uint8_t* USBD_USR_LangIDStrDescriptor(uint8_t speed, uint16_t* length)
*/
uint8_t* USBD_USR_ProductStrDescriptor(uint8_t speed, uint16_t* length)
{
- USBD_GetString((uint8_t*)USBD_PRODUCT_STRING, USBD_StrDesc, length);
+ USBD_GetString((uint8_t*)USBD_PRODUCT_STRING, sizeof(USBD_PRODUCT_STRING) - 1U, USBD_StrDesc, length);
return USBD_StrDesc;
}
@@ -159,7 +159,7 @@ uint8_t* USBD_USR_ProductStrDescriptor(uint8_t speed, uint16_t* length)
*/
uint8_t* USBD_USR_ManufacturerStrDescriptor(uint8_t speed, uint16_t* length)
{
- USBD_GetString((uint8_t*)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
+ USBD_GetString((uint8_t*)USBD_MANUFACTURER_STRING, sizeof(USBD_MANUFACTURER_STRING) - 1U, USBD_StrDesc, length);
return USBD_StrDesc;
}
@@ -201,7 +201,7 @@ uint8_t* USBD_USR_SerialStrDescriptor(uint8_t speed, uint16_t* length)
usbSN[i] += usbSN[i] < 0x0A ? '0' : '7';
}
- USBD_GetString(usbSN, USBD_StrDesc, length);
+ USBD_GetString(usbSN, *length, USBD_StrDesc, length);
return USBD_StrDesc;
}
@@ -214,7 +214,7 @@ uint8_t* USBD_USR_SerialStrDescriptor(uint8_t speed, uint16_t* length)
*/
uint8_t* USBD_USR_ConfigStrDescriptor(uint8_t speed, uint16_t* length)
{
- USBD_GetString((uint8_t*)USBD_CONFIGURATION_STRING, USBD_StrDesc, length);
+ USBD_GetString((uint8_t*)USBD_CONFIGURATION_STRING, sizeof(USBD_CONFIGURATION_STRING) - 1U, USBD_StrDesc, length);
return USBD_StrDesc;
}
@@ -227,7 +227,7 @@ uint8_t* USBD_USR_ConfigStrDescriptor(uint8_t speed, uint16_t* length)
*/
uint8_t* USBD_USR_InterfaceStrDescriptor(uint8_t speed, uint16_t* length)
{
- USBD_GetString((uint8_t*)USBD_INTERFACE_STRING, USBD_StrDesc, length);
+ USBD_GetString((uint8_t*)USBD_INTERFACE_STRING, sizeof(USBD_INTERFACE_STRING) - 1U, USBD_StrDesc, length);
return USBD_StrDesc;
}
@@ -340,7 +340,7 @@ __ALIGN_BEGIN uint8_t USBD_WINUSB_OSPropertyDesc[USB_LEN_OS_PROPERTY_DESC] __ALI
uint8_t *USBD_WinUSBOSStrDescriptor(uint16_t *length)
{
//printf("USBD_WinUSBOSStrDescriptor!\r\n");
- USBD_GetString((uint8_t *)USBD_OS_STRING, USBD_StrDesc, length);
+ USBD_GetString((uint8_t *)USBD_OS_STRING, sizeof(USBD_OS_STRING), USBD_StrDesc, length);
return USBD_StrDesc;
}
diff --git a/src/driver/usb/usbd_storage_msd.c b/src/driver/usb/usbd_storage_msd.c
index c27bc98..e71dfdd 100644
--- a/src/driver/usb/usbd_storage_msd.c
+++ b/src/driver/usb/usbd_storage_msd.c
@@ -96,7 +96,21 @@ int8_t STORAGE_IsWriteProtected(uint8_t lun)
int8_t STORAGE_Read(uint8_t lun, uint8_t* buffer, uint32_t block_number, uint16_t count)
{
- Gd25FlashReadBuffer(block_number * MSC_MEDIA_PACKET, buffer, MSC_MEDIA_PACKET * count);
+ uint64_t startAddr = (uint64_t)block_number * MSC_MEDIA_PACKET;
+ uint64_t totalSize = (uint64_t)count * MSC_MEDIA_PACKET;
+ uint64_t mediaSize = ((uint64_t)GD25QXX_SECTOR_NUM / 2U) * MSC_MEDIA_PACKET;
+
+ if (buffer == NULL) {
+ return -1;
+ }
+ if (totalSize == 0U) {
+ return 0;
+ }
+ if (startAddr >= mediaSize || totalSize > (mediaSize - startAddr)) {
+ return -1;
+ }
+
+ Gd25FlashReadBuffer((uint32_t)startAddr, buffer, (uint32_t)totalSize);
return 0;
}
@@ -110,8 +124,32 @@ int8_t STORAGE_Read(uint8_t lun, uint8_t* buffer, uint32_t block_number, uint16_
*/
int8_t STORAGE_Write(uint8_t lun, uint8_t* buffer, uint32_t block_number, uint16_t count)
{
- Gd25FlashSectorErase(block_number * MSC_MEDIA_PACKET);
- Gd25FlashWriteBuffer(block_number * MSC_MEDIA_PACKET, buffer, count * MSC_MEDIA_PACKET);
+ uint64_t startAddr = (uint64_t)block_number * MSC_MEDIA_PACKET;
+ uint64_t totalSize = (uint64_t)count * MSC_MEDIA_PACKET;
+ uint64_t mediaSize = ((uint64_t)GD25QXX_SECTOR_NUM / 2U) * MSC_MEDIA_PACKET;
+ uint32_t start_addr;
+ uint32_t total_size;
+
+ if (buffer == NULL) {
+ return -1;
+ }
+ if (totalSize == 0U) {
+ return 0;
+ }
+ if (startAddr >= mediaSize || totalSize > (mediaSize - startAddr)) {
+ return -1;
+ }
+
+ start_addr = (uint32_t)startAddr;
+ total_size = (uint32_t)totalSize;
+
+ uint32_t first_sector = start_addr / GD25QXX_SECTOR_SIZE;
+ uint32_t last_sector = (start_addr + total_size - 1U) / GD25QXX_SECTOR_SIZE;
+ for (uint32_t sector = first_sector; sector <= last_sector; sector++) {
+ Gd25FlashSectorErase(sector * GD25QXX_SECTOR_SIZE);
+ }
+
+ Gd25FlashWriteBuffer(start_addr, buffer, total_size);
return 0;
}
diff --git a/src/main.c b/src/main.c
index 08edc8f..f0e540b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -50,12 +50,14 @@
#include "version.h"
#include "hardware_version.h"
#include "librust_c.h"
+#include "drv_mpu.h"
int main(void)
{
__enable_irq();
SetAllGpioLow();
SystemClockInit();
+ MpuInit();
SensorInit();
Uart0Init(CmdIsrRcvByte);
FingerprintInit();
@@ -77,7 +79,6 @@ int main(void)
Atecc608bInit();
AccountsDataCheck();
MountUsbFatfs();
- UsbInit();
RtcInit();
MotorInit();
BatteryInit();
diff --git a/src/presetting.c b/src/presetting.c
index bb82833..cd1f664 100644
--- a/src/presetting.c
+++ b/src/presetting.c
@@ -57,12 +57,13 @@ int32_t GetWebAuthRsaKey(uint8_t *key)
data = SRAM_MALLOC(WEB_AUTH_RSA_KEY_LEN);
memcpy(data, (uint8_t *)OTP_ADDR_WEB_AUTH_RSA_KEY, WEB_AUTH_RSA_KEY_LEN);
if (CheckEntropy(data, WEB_AUTH_RSA_KEY_LEN) == false) {
+ MpuSetOtpProtection(true);
SRAM_FREE(data);
return ERR_WEB_AUTH_KEY_NOT_EXIST;
}
- SRAM_FREE(data);
- memcpy(key, data, WEB_AUTH_RSA_KEY_LEN);
MpuSetOtpProtection(true);
+ memcpy(key, data, WEB_AUTH_RSA_KEY_LEN);
+ SRAM_FREE(data);
return SUCCESS_CODE;
}
diff --git a/src/tasks/background_task.c b/src/tasks/background_task.c
index 37b36bf..521807a 100644
--- a/src/tasks/background_task.c
+++ b/src/tasks/background_task.c
@@ -92,10 +92,10 @@ static void BackgroundTask(void *argument)
GuiApiEmitSignalWithValue(SIG_INIT_USB_CONNECTION, 0);
GuiApiEmitSignalWithValue(SIG_INIT_PULLOUT_USB, 0);
} else if (GetUSBSwitch()) {
-#if (USB_POP_WINDOW_ENABLE == 1)
- GuiApiEmitSignalWithValue(SIG_INIT_USB_CONNECTION, 1);
-#else
+#if (USB_POP_WINDOW_ENABLE == 0)
OpenUsb();
+#else
+ GuiApiEmitSignalWithValue(SIG_INIT_USB_CONNECTION, 1);
#endif
}
GuiApiEmitSignal(SIG_INIT_BATTERY, &battState, sizeof(battState));
diff --git a/src/tasks/data_parser_task.c b/src/tasks/data_parser_task.c
index 0a0315a..94bb8d9 100644
--- a/src/tasks/data_parser_task.c
+++ b/src/tasks/data_parser_task.c
@@ -98,10 +98,38 @@ void CreateDataParserTask(void)
g_dataParserHandle = osThreadNew(DataParserTask, NULL, &dataParserTask_attributes);
}
-void PushDataToField(uint8_t *data, uint16_t len)
+bool CanPushDataToField(uint16_t len)
{
- for (int i = 0; i < len; i++) {
- circular_buf_put(g_cBufHandle, data[i]);
+ if (g_cBufHandle == NULL) {
+ return false;
+ }
+
+ size_t capacity = circular_buf_capacity(g_cBufHandle);
+ size_t used = circular_buf_size(g_cBufHandle);
+ return (capacity >= used) && ((capacity - used) >= len);
+}
+
+uint16_t PushDataToField(const uint8_t *data, uint16_t len)
+{
+ if (data == NULL || len == 0 || !CanPushDataToField(len)) {
+ return 0;
+ }
+
+ uint16_t pushed = 0;
+ for (uint16_t i = 0; i < len; i++) {
+ if (circular_buf_try_put(g_cBufHandle, data[i]) != 0) {
+ break;
+ }
+ pushed++;
+ }
+
+ return pushed;
+}
+
+void ResetDataField(void)
+{
+ if (g_cBufHandle != NULL) {
+ circular_buf_reset(g_cBufHandle);
}
}
@@ -133,12 +161,23 @@ static void DataParserTask(void *argument)
continue;
}
switch (rcvMsg.id) {
- case SPRING_MSG_GET:
- for (int i = 0; i < rcvMsg.value; i++) {
- circular_buf_get(g_cBufHandle, &USB_Rx_Buffer[i]);
+ case SPRING_MSG_GET: {
+ uint32_t targetLen = rcvMsg.value;
+ if (targetLen > sizeof(USB_Rx_Buffer) - 1U) {
+ targetLen = sizeof(USB_Rx_Buffer) - 1U;
+ }
+ uint32_t actualLen = 0;
+ for (uint32_t i = 0; i < targetLen; i++) {
+ if (circular_buf_get(g_cBufHandle, &USB_Rx_Buffer[i]) != 0) {
+ break;
+ }
+ actualLen++;
+ }
+ if (actualLen > 0U) {
+ ProtocolReceivedData(USB_Rx_Buffer, actualLen, USBD_cdc_SendBuffer_Cb);
}
- ProtocolReceivedData(USB_Rx_Buffer, rcvMsg.value, USBD_cdc_SendBuffer_Cb);
break;
+ }
default:
break;
}
@@ -176,4 +215,4 @@ void MemManage_Handler(void)
// system reset test
*(uint32_t *)0 = 123;
NVIC_SystemReset();
-}
\ No newline at end of file
+}
diff --git a/src/tasks/data_parser_task.h b/src/tasks/data_parser_task.h
index 1dd6d4f..340990c 100644
--- a/src/tasks/data_parser_task.h
+++ b/src/tasks/data_parser_task.h
@@ -10,5 +10,8 @@ uint8_t *GetDeviceParserPubKey(uint8_t *webPub, uint16_t len);
void DataEncrypt(uint8_t *data, uint16_t len);
void DataDecrypt(uint8_t *data, uint8_t *plain, uint16_t len);
void SetDeviceParserIv(uint8_t *iv);
+bool CanPushDataToField(uint16_t len);
+uint16_t PushDataToField(const uint8_t *data, uint16_t len);
+void ResetDataField(void);
#endif
diff --git a/src/tasks/ui_display_task.c b/src/tasks/ui_display_task.c
index 54f3770..9ee3a01 100644
--- a/src/tasks/ui_display_task.c
+++ b/src/tasks/ui_display_task.c
@@ -12,13 +12,11 @@
#include "user_memory.h"
#include "gui_chain.h"
#include "drv_lcd_bright.h"
-#include "drv_mpu.h"
#include "device_setting.h"
#include "anti_tamper.h"
#include "screenshot.h"
#include "lv_i18n_api.h"
#include "gui_api.h"
-#include "drv_mpu.h"
#include "drv_gd25qxx.h"
#define LVGL_FAST_TICK_MS 5
@@ -102,8 +100,6 @@ static void UiDisplayTask(void *argument)
}
GuiFrameOpenView(&g_initView);
SetLcdBright(GetBright());
- MpuInit();
-
while (1) {
RefreshLvglTickMode();
ret = osMessageQueueGet(g_uiQueue, &rcvMsg, NULL, g_dynamicTick);
@@ -419,4 +415,4 @@ void NftLockDecodeTouchQuit(void)
}
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/tasks/usb_task.c b/src/tasks/usb_task.c
index e70deac..54b5721 100644
--- a/src/tasks/usb_task.c
+++ b/src/tasks/usb_task.c
@@ -62,20 +62,11 @@ static void UsbTask(void *argument)
Message_t rcvMsg;
osStatus_t ret;
- osDelay(1000);
-#if (USB_POP_WINDOW_ENABLE == 1)
- CloseUsb();
-#else
- if (GetUSBSwitch() && GetUsbDetectState()) {
- OpenUsb();
- }
-#endif
while (1) {
ret = osMessageQueueGet(g_usbQueue, &rcvMsg, NULL, 10000);
if (ret == osOK) {
switch (rcvMsg.id) {
case USB_MSG_ISR_HANDLER: {
- ClearLockScreenTime();
USBD_OTG_ISR_Handler((USB_OTG_CORE_HANDLE *)rcvMsg.value);
NVIC_ClearPendingIRQ(USB_IRQn);
NVIC_EnableIRQ(USB_IRQn);
@@ -87,6 +78,7 @@ static void UsbTask(void *argument)
break;
case USB_MSG_INIT: {
g_usbState = true;
+ ClearLockScreenTime();
UsbInit();
SetUsbState(true);
}
@@ -120,4 +112,3 @@ void UsbTest(int argc, char *argv[])
CloseUsb();
}
}
-
diff --git a/src/ui/gui_analyze/gui_analyze.c b/src/ui/gui_analyze/gui_analyze.c
index eb9e48d..aada31a 100644
--- a/src/ui/gui_analyze/gui_analyze.c
+++ b/src/ui/gui_analyze/gui_analyze.c
@@ -519,7 +519,6 @@ static void DisplayJsonRecursive(lv_obj_t *parent, cJSON *item, int indent, uint
if (cJSON_IsObject(item)) {
DisplayJsonRecursive(parent, item->child, indent + 1, yOffset);
} else if (cJSON_IsArray(item)) {
- int size = cJSON_GetArraySize(item);
for (int i = 0; i < 1; i++) {
cJSON* subitem = cJSON_GetArrayItem(item, i);
DisplayJsonRecursive(parent, subitem, indent, yOffset);
diff --git a/src/ui/gui_frame/gui_obj.h b/src/ui/gui_frame/gui_obj.h
index 797b889..a40da0d 100644
--- a/src/ui/gui_frame/gui_obj.h
+++ b/src/ui/gui_frame/gui_obj.h
@@ -65,6 +65,7 @@ typedef int32_t(*GuiEventProcessFunc)(void *self, uint16_t usEvent, void *param,
add(SCREEN_CONNECT_USB) \
add(SCREEN_CHECK_DELETE_WALLET) \
add(SCREEN_ETH_BATCH_TX) \
+ add(SCREEN_BOOT_UPDATE) \
typedef enum {
SCREEN_INVALID = -1,
diff --git a/src/ui/gui_model/gui_model.c b/src/ui/gui_model/gui_model.c
index 43e1678..127e15b 100644
--- a/src/ui/gui_model/gui_model.c
+++ b/src/ui/gui_model/gui_model.c
@@ -50,6 +50,8 @@
#define APP_ADDR (0x1001000 + 0x80000) //108 1000
#define APP_CHECK_START_ADDR (0x1400000)
#define APP_END_ADDR (0x2000000)
+#define SD_CARD_OTA_FILE_PATH "0:/keystone3.bin"
+#define INTERNAL_STORAGE_OTA_FILE_PATH "1:/keystone3.bin"
#define MODEL_WRITE_SE_HEAD do { \
ret = CHECK_BATTERY_LOW_POWER(); \
@@ -108,6 +110,7 @@ static int32_t ModelParseTransaction(const void *indata, uint32_t inDataLen, Bac
static int32_t ModelFormatMicroSd(const void *indata, uint32_t inDataLen);
static int32_t ModelParseTransactionRawData(const void *inData, uint32_t inDataLen);
static int32_t ModelTransactionParseRawDataDelay(const void *inData, uint32_t inDataLen);
+static int32_t ModelUpdateBoot(const void *inData, uint32_t inDataLen);
static PasswordVerifyResult_t g_passwordVerifyResult;
static bool g_stopCalChecksum = false;
@@ -284,6 +287,11 @@ void GuiModelCopySdCardOta(void)
AsyncExecute(ModelCopySdCardOta, NULL, 0);
}
+void GuiModelUpdateBoot(void)
+{
+ AsyncExecute(ModelUpdateBoot, NULL, 0);
+}
+
void GuiModelURGenerateQRCode(GenerateUR func)
{
AsyncExecuteRunnable(ModelURGenerateQRCode, NULL, 0, (BackgroundAsyncRunnable_t)func);
@@ -1348,7 +1356,7 @@ static int32_t ModelCopySdCardOta(const void *inData, uint32_t inDataLen)
#ifndef COMPILE_SIMULATOR
static uint8_t walletAmount;
SetPageLockScreen(false);
- int32_t ret = FatfsFileCopy("0:/keystone3.bin", "1:/pillar.bin");
+ int32_t ret = FatfsFileCopy(SD_CARD_OTA_FILE_PATH, INTERNAL_STORAGE_OTA_FILE_PATH);
if (ret == SUCCESS_CODE) {
GetExistAccountNum(&walletAmount);
if (walletAmount == 0) {
@@ -1373,6 +1381,26 @@ static bool CheckNeedDelay(ViewType viewType)
}
#endif
+static int32_t ModelUpdateBoot(const void *inData, uint32_t inDataLen)
+{
+#ifdef BUILD_PRODUCTION
+ osDelay(1000);
+ static uint8_t walletAmount;
+ SetPageLockScreen(false);
+ int32_t ret = UpdateBootFromFlash();
+ SetPageLockScreen(true);
+ if (ret == SUCCESS_CODE) {
+ NVIC_SystemReset();
+ GuiApiEmitSignal(SIG_BOOT_UPDATE_SUCCESS, NULL, 0);
+ } else {
+ GuiApiEmitSignal(SIG_BOOT_UPDATE_FAIL, NULL, 0);
+ }
+#else
+ GuiApiEmitSignal(SIG_BOOT_UPDATE_SUCCESS, NULL, 0);
+#endif
+ return SUCCESS_CODE;
+}
+
static PtrT_TransactionCheckResult g_checkResult = NULL;
static int32_t ModelCheckTransaction(const void *inData, uint32_t inDataLen)
{
@@ -1865,4 +1893,4 @@ int32_t RsaGenerateKeyPair(bool needEmitSignal)
ClearLockScreenTime();
return ret;
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/ui/gui_model/gui_model.h b/src/ui/gui_model/gui_model.h
index 2a31310..01cfc60 100644
--- a/src/ui/gui_model/gui_model.h
+++ b/src/ui/gui_model/gui_model.h
@@ -95,6 +95,7 @@ void GuiModelStopCalculateCheckSum(void);
void GuiModelSettingWritePassphrase(void);
void GuiModelCalculateBinSha256(void);
void GuiModelFormatMicroSd(void);
+void GuiModelUpdateBoot(void);
uint32_t BinarySearchLastNonFFSector(void);
void GuiModelParseTransactionRawData(void);
void GuiModelTransactionParseRawDataDelay(void);
diff --git a/src/ui/gui_views/gui_boot_update_view.c b/src/ui/gui_views/gui_boot_update_view.c
new file mode 100644
index 0000000..cd99a6e
--- /dev/null
+++ b/src/ui/gui_views/gui_boot_update_view.c
@@ -0,0 +1,33 @@
+#include "gui.h"
+#include "gui_obj.h"
+#include "gui_views.h"
+#include "gui_boot_update_widgets.h"
+
+int32_t GuiBootUpdateViewEventProcess(void *self, uint16_t usEvent, void *param, uint16_t usLen)
+{
+ switch (usEvent) {
+ case GUI_EVENT_OBJ_INIT:
+ GuiBootUpdateInit();
+ break;
+ case GUI_EVENT_OBJ_DEINIT:
+ GuiBootUpdateDeInit();
+ break;
+ case SIG_BOOT_UPDATE_SUCCESS:
+ GuiBootUpdateSuccess();
+ break;
+ case SIG_BOOT_UPDATE_FAIL:
+ // GuiBootUpdateFail();
+ break;
+ default:
+ return ERR_GUI_UNHANDLED;
+ }
+ return SUCCESS_CODE;
+}
+
+GUI_VIEW g_bootUpdateView = {
+ .id = SCREEN_BOOT_UPDATE,
+ .previous = NULL,
+ .isActive = false,
+ .optimization = false,
+ .pEvtHandler = GuiBootUpdateViewEventProcess,
+};
diff --git a/src/ui/gui_views/gui_init_view.c b/src/ui/gui_views/gui_init_view.c
index 637d002..82adf6c 100644
--- a/src/ui/gui_views/gui_init_view.c
+++ b/src/ui/gui_views/gui_init_view.c
@@ -47,10 +47,11 @@ static int32_t GuiInitViewInit(void *param)
return SUCCESS_CODE;
}
- if (IsBootVersionMatch() == false) {
- GuiBootVersionNotMatchWidget();
- return SUCCESS_CODE;
- }
+ // should not show boot version this version
+ // if (IsBootVersionMatch() == false) {
+ // GuiBootVersionNotMatchWidget();
+ // return SUCCESS_CODE;
+ // }
GuiModeGetAccount();
return SUCCESS_CODE;
}
@@ -76,6 +77,9 @@ int32_t GUI_InitViewEventProcess(void *self, uint16_t usEvent, void *param, uint
if (IsUpdateSuccess()) {
GuiFrameOpenView(&g_updateSuccessView);
}
+ if (NeedUpdateBoot()) {
+ GuiFrameOpenView(&g_bootUpdateView);
+ }
break;
} else {
return GuiFrameOpenViewWithParam(&g_lockView, &lockParam, sizeof(lockParam));
diff --git a/src/ui/gui_views/gui_views.h b/src/ui/gui_views/gui_views.h
index 4045c94..a1ea9a3 100644
--- a/src/ui/gui_views/gui_views.h
+++ b/src/ui/gui_views/gui_views.h
@@ -25,6 +25,9 @@ typedef enum {
SIG_INIT_SD_CARD_OTA_COPY,
SIG_INIT_SD_CARD_OTA_COPY_SUCCESS,
SIG_INIT_SD_CARD_OTA_COPY_FAIL,
+ SIG_INIT_UPDATE_BOOT,
+ SIG_BOOT_UPDATE_SUCCESS,
+ SIG_BOOT_UPDATE_FAIL,
SIG_STATUS_BAR_REFRESH,
SIG_INIT_TRANSFER_NFT_SCREEN,
SIG_INIT_CONNECT_USB,
@@ -236,6 +239,7 @@ extern GUI_VIEW g_transactionSignatureView;
extern GUI_VIEW g_diceRollsView;
extern GUI_VIEW g_exportPubkeyView;
extern GUI_VIEW g_updateSuccessView;
+extern GUI_VIEW g_bootUpdateView;
#ifdef BTC_ONLY
extern GUI_VIEW g_btcBtcWalletProfileView;
extern GUI_VIEW g_multisigTransactionSignatureView;
diff --git a/src/ui/gui_widgets/gui_boot_update_widgets.c b/src/ui/gui_widgets/gui_boot_update_widgets.c
new file mode 100644
index 0000000..fc7cd58
--- /dev/null
+++ b/src/ui/gui_widgets/gui_boot_update_widgets.c
@@ -0,0 +1,105 @@
+#include "gui.h"
+#include "gui_views.h"
+#include "gui_boot_update_widgets.h"
+#include "gui_status_bar.h"
+#include "gui_hintbox.h"
+#include "presetting.h"
+#include "gui_model.h"
+#include "version.h"
+
+static lv_obj_t *g_bootUpdateCont = NULL;
+static lv_obj_t *g_noticeWindow = NULL;
+static lv_obj_t *g_startBtn = NULL;
+
+void GuiCreateBootUpdateHandler(lv_event_t * e)
+{
+ if (GetCurrentDisplayPercent() <= 40 ||
+ GetUsbDetectState() == false) {
+ g_noticeWindow = GuiCreateConfirmHintBox(&imgFailed, _("error_box_low_power"), _("boot_update_limit_desc"), NULL, _("OK"), WHITE_COLOR_OPA20);
+ lv_obj_add_event_cb(GuiGetHintBoxRightBtn(g_noticeWindow), CloseHintBoxHandler, LV_EVENT_CLICKED, &g_noticeWindow);
+ return;
+ }
+
+ lv_obj_set_style_bg_color(g_startBtn, DARK_GRAY_COLOR, LV_PART_MAIN);
+ lv_obj_clear_flag(g_startBtn, LV_OBJ_FLAG_CLICKABLE);
+
+ lv_obj_clean(g_bootUpdateCont);
+
+ lv_obj_t *label = GuiCreateLittleTitleLabel(g_bootUpdateCont, _("boot_update_process_title"));
+ lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 312);
+
+ label = GuiCreateNoticeLabel(g_bootUpdateCont, _("boot_update_process_desc"));
+ lv_obj_align(label, LV_ALIGN_DEFAULT, 36, 362);
+ lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN);
+
+ printf("GuiCreateBootUpdateHandler\n");
+ GuiModelUpdateBoot();
+}
+
+void GuiCreateBootUpdateSkipHandler(lv_event_t * e)
+{
+ printf("GuiCreateBootUpdateSkipHandler\n");
+ GuiCloseCurrentWorkingView();
+}
+
+void GuiBootUpdateDeInit(void)
+{
+ GUI_DEL_OBJ(g_bootUpdateCont)
+}
+
+void GuiBootUpdateSuccess(void)
+{
+ printf("GuiBootUpdateSuccess\n");
+}
+
+void GuiBootUpdateInit(void)
+{
+ lv_obj_t *tempObj, *dotImg;
+ uint32_t height = 336 - GUI_STATUS_BAR_HEIGHT;
+ printf("GuiBootUpdateInit\n");
+ if (g_bootUpdateCont == NULL) {
+ g_bootUpdateCont = GuiCreateContainer(480, 800 - GUI_STATUS_BAR_HEIGHT);
+ lv_obj_align(g_bootUpdateCont, LV_ALIGN_TOP_MID, 0, GUI_STATUS_BAR_HEIGHT);
+ tempObj = GuiCreateImg(g_bootUpdateCont, &imgFirmwareUp);
+ lv_obj_align(tempObj, LV_ALIGN_TOP_MID, 0, 64);
+ tempObj = GuiCreateLittleTitleLabel(g_bootUpdateCont, _("boot_update_title"));
+ lv_obj_align(tempObj, LV_ALIGN_TOP_MID, 0, 155);
+ tempObj = GuiCreateNoticeLabel(g_bootUpdateCont, _("boot_update_desc1"));
+ lv_obj_set_style_text_align(tempObj, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN);
+ lv_obj_align(tempObj, LV_ALIGN_DEFAULT, 36, 207);
+ dotImg = GuiCreateImg(g_bootUpdateCont, &imgCircular);
+ lv_obj_align(dotImg, LV_ALIGN_DEFAULT, 36, 307);
+ tempObj = GuiCreateIllustrateLabel(g_bootUpdateCont, _("boot_update_desc2"));
+ lv_obj_align_to(tempObj, dotImg, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
+ dotImg = GuiCreateImg(g_bootUpdateCont, &imgCircular);
+ lv_obj_align(dotImg, LV_ALIGN_DEFAULT, 36, 349);
+ tempObj = GuiCreateIllustrateLabel(g_bootUpdateCont, _("boot_update_desc3"));
+ lv_obj_align_to(tempObj, dotImg, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
+ dotImg = GuiCreateImg(g_bootUpdateCont, &imgCircular);
+ lv_obj_align(dotImg, LV_ALIGN_DEFAULT, 36, 391);
+ tempObj = GuiCreateIllustrateLabel(g_bootUpdateCont, _("boot_update_desc4"));
+ lv_obj_align_to(tempObj, dotImg, LV_ALIGN_DEFAULT, 30, -12);
+
+ tempObj = GuiCreateIllustrateLabel(g_bootUpdateCont, _("boot_update_desc5"));
+ lv_obj_align(tempObj, LV_ALIGN_TOP_MID, 0, 508);
+
+ tempObj = GuiCreateLabelWithFontAndTextColor(g_bootUpdateCont, "support@keyst.one", &openSansEnIllustrate, 0x1BE0C6);
+ lv_obj_align(tempObj, LV_ALIGN_TOP_MID, 0, 550);
+
+ char serialNumber[SERIAL_NUMBER_MAX_LEN];
+ char buff[BUFFER_SIZE_128];
+ GetSerialNumber(serialNumber);
+ snprintf_s(buff, sizeof(buff), "SN:%s ", serialNumber);
+ tempObj = GuiCreateNoticeLabel(g_bootUpdateCont, buff);
+ lv_obj_align(tempObj, LV_ALIGN_TOP_MID, 0, 600);
+
+ g_startBtn = GuiCreateTextBtn(g_bootUpdateCont, _("Start"));
+ lv_obj_align(g_startBtn, LV_ALIGN_BOTTOM_MID, 0, -36);
+ lv_obj_set_width(g_startBtn, 408);
+ lv_obj_add_event_cb(g_startBtn, GuiCreateBootUpdateHandler, LV_EVENT_CLICKED, NULL);
+
+ // tempObj = GuiCreateBtn(g_bootUpdateCont, "Skip");
+ // lv_obj_align(tempObj, LV_ALIGN_BOTTOM_RIGHT, 0, -100);
+ // lv_obj_add_event_cb(tempObj, GuiCreateBootUpdateSkipHandler, LV_EVENT_CLICKED, NULL);
+ }
+}
diff --git a/src/ui/gui_widgets/gui_boot_update_widgets.h b/src/ui/gui_widgets/gui_boot_update_widgets.h
new file mode 100644
index 0000000..7f39fa1
--- /dev/null
+++ b/src/ui/gui_widgets/gui_boot_update_widgets.h
@@ -0,0 +1,13 @@
+#ifndef _GUI_BOOT_UPDATE_WIDGETS_H
+#define _GUI_BOOT_UPDATE_WIDGETS_H
+
+#include "stdint.h"
+#include "stdbool.h"
+
+void GuiBootUpdateInit(void);
+void GuiBootUpdateSuccess(void);
+void GuiBootUpdateFail(void);
+void GuiBootUpdateDeInit(void);
+
+#endif
+
diff --git a/src/ui/gui_widgets/gui_lock_widgets.c b/src/ui/gui_widgets/gui_lock_widgets.c
index 419acbd..b07e931 100644
--- a/src/ui/gui_widgets/gui_lock_widgets.c
+++ b/src/ui/gui_widgets/gui_lock_widgets.c
@@ -246,7 +246,9 @@ void GuiLockScreenTurnOff(void)
if ((GetCurrentAccountIndex() != g_oldWalletIndex) ||
GuiIsForgetPass()) {
g_oldWalletIndex = GetCurrentAccountIndex();
- GuiCloseToTargetView(&g_homeView);
+ if (!NeedUpdateBoot()) {
+ GuiCloseToTargetView(&g_homeView);
+ }
} else {
GuiEmitSignal(GUI_EVENT_REFRESH, &single, sizeof(single));
GuiFirmwareUpdateWidgetRefresh();
@@ -289,6 +291,9 @@ void GuiLockScreenPassCode(bool en)
GuiEnterPassCodeStatus(g_verifyLock, true);
GuiFrameOpenView(&g_homeView);
GuiFrameOpenView(&g_updateSuccessView);
+ if (NeedUpdateBoot()) {
+ GuiFrameOpenView(&g_bootUpdateView);
+ }
#ifndef WEB3_VERSION
} else if (GetMnemonicType() == MNEMONIC_TYPE_TON) {
lv_obj_add_flag(g_pageWidget->page, LV_OBJ_FLAG_HIDDEN);
@@ -303,6 +308,9 @@ void GuiLockScreenPassCode(bool en)
GuiModeGetWalletDesc();
GuiEnterPassCodeStatus(g_verifyLock, true);
GuiFrameOpenView(&g_passphraseView);
+ if (NeedUpdateBoot()) {
+ GuiFrameOpenView(&g_bootUpdateView);
+ }
} else if (g_homeView.isActive) {
GuiLockScreenTurnOff();
} else if (g_forgetPassView.isActive) {
@@ -311,6 +319,9 @@ void GuiLockScreenPassCode(bool en)
lv_obj_add_flag(g_pageWidget->page, LV_OBJ_FLAG_HIDDEN);
SetNavBarMidBtn(g_pageWidget->navBarWidget, NVS_MID_BUTTON_BUTT, NULL, NULL);
GuiFrameOpenView(&g_homeView);
+ if (NeedUpdateBoot()) {
+ GuiFrameOpenView(&g_bootUpdateView);
+ }
HardwareInitAfterWake();
}
// Close the loading page after closing the lock screen page
@@ -550,4 +561,4 @@ static void GuiCloseGenerateXPubLoading(void)
static void HardwareInitAfterWake(void)
{
AsyncExecute(InitSdCardAfterWakeup, NULL, 0);
-}
\ No newline at end of file
+}
diff --git a/src/user_fatfs.c b/src/user_fatfs.c
index fb041f3..7b792ed 100644
--- a/src/user_fatfs.c
+++ b/src/user_fatfs.c
@@ -4,7 +4,6 @@
#include "drv_sys.h"
#include "log_print.h"
#include "user_memory.h"
-#include "md5.h"
#include "diskio.h"
#include "drv_gd25qxx.h"
#include "drv_sdcard.h"
diff --git a/src/webusb_protocol/general/eapdu_protocol_parser.c b/src/webusb_protocol/general/eapdu_protocol_parser.c
index 6283f93..186ad4e 100644
--- a/src/webusb_protocol/general/eapdu_protocol_parser.c
+++ b/src/webusb_protocol/general/eapdu_protocol_parser.c
@@ -1,6 +1,7 @@
#include "stdio.h"
#include "stdlib.h"
#include "assert.h"
+#include "cmsis_os.h"
#include "eapdu_protocol_parser.h"
#include "keystore.h"
#include "data_parser_task.h"
@@ -12,22 +13,24 @@
#include "eapdu_services/service_check_lock.h"
#include "eapdu_services/service_echo_test.h"
#include "eapdu_services/service_export_address.h"
-#include "eapdu_services/service_trans_usb_pubkey.h"
#include "eapdu_services/service_get_device_info.h"
static ProtocolSendCallbackFunc_t g_sendFunc = NULL;
-static struct ProtocolParser *global_parser = NULL;
+static uint32_t g_eapduRcvCount = 0;
#define EAPDU_RESPONSE_STATUS_LENGTH 2
#define MAX_PACKETS 200
-#define MAX_PACKETS_LENGTH 64
-#define MAX_EAPDU_DATA_SIZE (MAX_PACKETS_LENGTH - OFFSET_CDATA)
+#define MAX_PACKETS_LENGTH MAX_EAPDU_PACKET_SIZE
#define MAX_EAPDU_RESPONSE_DATA_SIZE (MAX_PACKETS_LENGTH - OFFSET_CDATA - EAPDU_RESPONSE_STATUS_LENGTH)
+#define EAPDU_REASSEMBLY_TIMEOUT_MS 5000
static uint8_t g_protocolRcvBuffer[MAX_PACKETS][MAX_PACKETS_LENGTH] __attribute__((section(".data_parser_section")));
static uint8_t g_packetLengths[MAX_PACKETS];
static uint8_t g_receivedPackets[MAX_PACKETS];
static uint8_t g_totalPackets = 0;
+static uint32_t g_lastPacketTick = 0;
+static uint32_t GetRcvCount(void);
+static void ResetRcvCount(void);
typedef enum {
FRAME_INVALID_LENGTH,
@@ -41,36 +44,63 @@ typedef enum {
void SendEApduResponse(EAPDUResponsePayload_t *payload)
{
assert(payload != NULL);
+ if (payload == NULL || g_sendFunc == NULL) {
+ return;
+ }
+ if (payload->data == NULL && payload->dataLen != 0U) {
+ return;
+ }
+
uint8_t packet[MAX_PACKETS_LENGTH];
uint16_t totalPackets = (payload->dataLen + MAX_EAPDU_RESPONSE_DATA_SIZE - 1) / MAX_EAPDU_RESPONSE_DATA_SIZE;
uint16_t packetIndex = 0;
uint32_t offset = 0;
+ uint32_t remaining = payload->dataLen;
+ if (totalPackets == 0U) {
+ totalPackets = 1U;
+ }
- while (payload->dataLen > 0) {
- uint16_t packetDataSize = payload->dataLen > MAX_EAPDU_RESPONSE_DATA_SIZE ? MAX_EAPDU_RESPONSE_DATA_SIZE : payload->dataLen;
+ do {
+ uint16_t packetDataSize = remaining > MAX_EAPDU_RESPONSE_DATA_SIZE ? MAX_EAPDU_RESPONSE_DATA_SIZE : (uint16_t)remaining;
packet[OFFSET_CLA] = payload->cla;
insert_16bit_value(packet, OFFSET_INS, payload->commandType);
insert_16bit_value(packet, OFFSET_P1, totalPackets);
insert_16bit_value(packet, OFFSET_P2, packetIndex);
insert_16bit_value(packet, OFFSET_LC, payload->requestID);
- memcpy_s(packet + OFFSET_CDATA, MAX_PACKETS_LENGTH - OFFSET_CDATA, payload->data + offset, packetDataSize);
+ if (packetDataSize > 0U) {
+ memcpy_s(packet + OFFSET_CDATA, MAX_PACKETS_LENGTH - OFFSET_CDATA, payload->data + offset, packetDataSize);
+ }
insert_16bit_value(packet, OFFSET_CDATA + packetDataSize, payload->status);
g_sendFunc(packet, OFFSET_CDATA + packetDataSize + EAPDU_RESPONSE_STATUS_LENGTH);
offset += packetDataSize;
- payload->dataLen -= packetDataSize;
+ remaining -= packetDataSize;
packetIndex++;
UserDelay(10);
- }
+ } while (remaining > 0U);
}
void SendEApduResponseError(uint8_t cla, CommandType ins, uint16_t requestID, StatusEnum status, char *error)
{
+ if (error == NULL) {
+ error = "unknown error";
+ }
EAPDUResponsePayload_t *result = (EAPDUResponsePayload_t *)SRAM_MALLOC(sizeof(EAPDUResponsePayload_t));
+ if (result == NULL) {
+ return;
+ }
cJSON *root = cJSON_CreateObject();
+ if (root == NULL) {
+ SRAM_FREE(result);
+ return;
+ }
cJSON_AddStringToObject(root, "payload", error);
char *json_str = cJSON_PrintBuffered(root, BUFFER_SIZE_1024, false);
cJSON_Delete(root);
+ if (json_str == NULL) {
+ SRAM_FREE(result);
+ return;
+ }
result->data = (uint8_t *)json_str;
result->dataLen = strlen((char *)result->data);
result->status = status;
@@ -85,10 +115,12 @@ void SendEApduResponseError(uint8_t cla, CommandType ins, uint16_t requestID, St
static void free_parser()
{
g_totalPackets = 0;
+ g_eapduRcvCount = 0;
+ g_lastPacketTick = 0;
memset_s(g_receivedPackets, sizeof(g_receivedPackets), 0, sizeof(g_receivedPackets));
memset_s(g_packetLengths, sizeof(g_packetLengths), 0, sizeof(g_packetLengths));
for (int i = 0; i < MAX_PACKETS; i++) {
- memset_s(g_protocolRcvBuffer, sizeof(g_protocolRcvBuffer[i]), 0, sizeof(g_protocolRcvBuffer[i]));
+ memset_s(g_protocolRcvBuffer[i], sizeof(g_protocolRcvBuffer[i]), 0, sizeof(g_protocolRcvBuffer[i]));
}
}
@@ -116,9 +148,6 @@ static void EApduRequestHandler(EAPDURequestPayload_t *request)
case CMD_GET_DEVICE_INFO:
GetDeviceInfoService(request);
break;
- case CMD_GET_DEVICE_USB_PUBKEY:
- GetDeviceUsbPubkeyService(request);
- break;
default:
printf("Invalid command: %u\n", request->commandType);
break;
@@ -152,6 +181,9 @@ static EAPDUFrame_t *FrameParser(const uint8_t *frame, uint32_t len)
return NULL;
}
EAPDUFrame_t *eapduFrame = (EAPDUFrame_t *)SRAM_MALLOC(sizeof(EAPDUFrame_t));
+ if (eapduFrame == NULL) {
+ return NULL;
+ }
eapduFrame->cla = frame[OFFSET_CLA];
eapduFrame->ins = extract_16bit_value(frame, OFFSET_INS);
eapduFrame->p1 = extract_16bit_value(frame, OFFSET_P1);
@@ -164,7 +196,14 @@ static EAPDUFrame_t *FrameParser(const uint8_t *frame, uint32_t len)
void EApduProtocolParse(const uint8_t *frame, uint32_t len)
{
- if (len < 4) { // Ensure frame has minimum length
+ uint32_t tick = osKernelGetTickCount();
+ if (g_totalPackets != 0 && g_lastPacketTick != 0 && (tick - g_lastPacketTick > EAPDU_REASSEMBLY_TIMEOUT_MS)) {
+ printf("EAPDU reassembly timeout\n");
+ free_parser();
+ }
+
+ g_eapduRcvCount++;
+ if (len < OFFSET_CDATA) {
printf("Invalid EAPDU data: too short\n");
free_parser();
return;
@@ -174,12 +213,24 @@ void EApduProtocolParse(const uint8_t *frame, uint32_t len)
SRAM_FREE(eapduFrame);
return;
}
- if (eapduFrame->p2 == 0 && g_totalPackets == 0) {
+ if (g_totalPackets == 0) {
g_totalPackets = eapduFrame->p1;
assert(g_totalPackets <= MAX_PACKETS);
memset_s(g_receivedPackets, sizeof(g_receivedPackets), 0, sizeof(g_receivedPackets));
+ } else if (g_totalPackets != eapduFrame->p1) {
+ SendEApduResponseError(EAPDU_PROTOCOL_HEADER, eapduFrame->ins, eapduFrame->lc, PRS_INVALID_TOTAL_PACKETS, "Mismatched total packets");
+ free_parser();
+ SRAM_FREE(eapduFrame);
+ return;
}
- assert(eapduFrame->dataLen <= MAX_PACKETS_LENGTH && eapduFrame->p2 < MAX_PACKETS);
+ g_lastPacketTick = tick;
+ if (eapduFrame->dataLen > MAX_EAPDU_DATA_SIZE || eapduFrame->p2 >= MAX_PACKETS) {
+ SendEApduResponseError(EAPDU_PROTOCOL_HEADER, eapduFrame->ins, eapduFrame->lc, PRS_INVALID_INDEX, "Invalid packet length/index");
+ free_parser();
+ SRAM_FREE(eapduFrame);
+ return;
+ }
+ assert(eapduFrame->dataLen <= MAX_EAPDU_DATA_SIZE && eapduFrame->p2 < MAX_PACKETS);
memcpy_s(g_protocolRcvBuffer[eapduFrame->p2], sizeof(g_protocolRcvBuffer[eapduFrame->p2]), eapduFrame->data, eapduFrame->dataLen);
g_packetLengths[eapduFrame->p2] = eapduFrame->dataLen;
g_receivedPackets[eapduFrame->p2] = 1;
@@ -196,14 +247,30 @@ void EApduProtocolParse(const uint8_t *frame, uint32_t len)
for (uint16_t i = 0; i < g_totalPackets; i++) {
fullDataLen += g_packetLengths[i];
}
+ if (fullDataLen > (MAX_PACKETS * MAX_EAPDU_DATA_SIZE)) {
+ free_parser();
+ SRAM_FREE(eapduFrame);
+ return;
+ }
fullData = (uint8_t *)SRAM_MALLOC(fullDataLen + 1);
+ if (fullData == NULL) {
+ free_parser();
+ SRAM_FREE(eapduFrame);
+ return;
+ }
for (uint32_t i = 0; i < g_totalPackets; i++) {
memcpy_s(fullData + offset, fullDataLen - offset, g_protocolRcvBuffer[i], g_packetLengths[i]);
offset += g_packetLengths[i];
}
fullData[fullDataLen] = '\0';
EAPDURequestPayload_t *request = (EAPDURequestPayload_t *)SRAM_MALLOC(sizeof(EAPDURequestPayload_t));
+ if (request == NULL) {
+ SRAM_FREE(fullData);
+ free_parser();
+ SRAM_FREE(eapduFrame);
+ return;
+ }
request->data = fullData;
request->dataLen = fullDataLen;
request->requestID = eapduFrame->lc;
@@ -223,16 +290,26 @@ static void RegisterSendFunc(ProtocolSendCallbackFunc_t sendFunc)
}
}
-struct ProtocolParser *NewEApduProtocolParser()
+static uint32_t GetRcvCount(void)
+{
+ return g_eapduRcvCount;
+}
+
+static void ResetRcvCount(void)
+{
+ free_parser();
+}
+
+const struct ProtocolParser *NewEApduProtocolParser()
{
- if (!global_parser) {
- global_parser = (struct ProtocolParser *)SRAM_MALLOC(sizeof(struct ProtocolParser));
- global_parser->name = EAPDU_PROTOCOL_PARSER_NAME;
- global_parser->parse = EApduProtocolParse;
- global_parser->registerSendFunc = RegisterSendFunc;
- global_parser->rcvCount = 0;
- }
- return global_parser;
+ static const struct ProtocolParser g_eapduParser = {
+ .name = EAPDU_PROTOCOL_PARSER_NAME,
+ .parse = EApduProtocolParse,
+ .registerSendFunc = RegisterSendFunc,
+ .getRcvCount = GetRcvCount,
+ .resetRcvCount = ResetRcvCount,
+ };
+ return &g_eapduParser;
}
void GotoResultPage(EAPDUResultPage_t *resultPageParams)
@@ -247,4 +324,4 @@ void GotoResultPage(EAPDUResultPage_t *resultPageParams)
PubBufferMsg(UI_MSG_USB_TRANSPORT_VIEW, resultPageParams, sizeof(EAPDUResultPage_t));
}
}
-}
\ No newline at end of file
+}
diff --git a/src/webusb_protocol/general/eapdu_protocol_parser.h b/src/webusb_protocol/general/eapdu_protocol_parser.h
index 7548f71..0cd14cd 100644
--- a/src/webusb_protocol/general/eapdu_protocol_parser.h
+++ b/src/webusb_protocol/general/eapdu_protocol_parser.h
@@ -11,6 +11,8 @@
#define EAPDU_PROTOCOL_PARSER_NAME "eapdu_protocol_parser"
enum { OFFSET_CLA = 0, OFFSET_INS = 1, OFFSET_P1 = 3, OFFSET_P2 = 5, OFFSET_LC = 7, OFFSET_CDATA = 9 };
+#define MAX_EAPDU_PACKET_SIZE 64
+#define MAX_EAPDU_DATA_SIZE (MAX_EAPDU_PACKET_SIZE - OFFSET_CDATA)
typedef enum {
CMD_ECHO_TEST = 0x00000001, // Command to test echo
@@ -18,7 +20,6 @@ typedef enum {
CMD_CHECK_LOCK_STATUS, // Command to check lock status
CMD_EXPORT_ADDRESS, // Command to export address
CMD_GET_DEVICE_INFO, // Command to get device info
- CMD_GET_DEVICE_USB_PUBKEY, // Command to get device public key
CMD_MAX_VALUE = 0xFFFFFFFF, // The maximum value for command
} CommandType;
@@ -79,9 +80,9 @@ typedef struct {
PtrString error_message;
} EAPDUResultPage_t;
-struct ProtocolParser* NewEApduProtocolParser();
+const struct ProtocolParser* NewEApduProtocolParser();
void SendEApduResponse(EAPDUResponsePayload_t *payload);
void GotoResultPage(EAPDUResultPage_t *resultPageParams);
void SendEApduResponseError(uint8_t cla, CommandType ins, uint16_t requestID, StatusEnum status, char *error);
-#endif
\ No newline at end of file
+#endif
diff --git a/src/webusb_protocol/general/eapdu_services/service_export_address.c b/src/webusb_protocol/general/eapdu_services/service_export_address.c
index 4d01592..bca87d5 100644
--- a/src/webusb_protocol/general/eapdu_services/service_export_address.c
+++ b/src/webusb_protocol/general/eapdu_services/service_export_address.c
@@ -5,6 +5,7 @@
#include "gui_lock_widgets.h"
#include "gui_home_widgets.h"
#include "gui_wallet.h"
+#include "cmsis_os.h"
/* DEFINES */
@@ -42,6 +43,23 @@ static void ExportEthAddress(uint16_t requestID, uint8_t n, ETHAccountType type)
/* STATIC VARIABLES */
static ExportAddressParams_t *g_exportAddressParams = NULL;
+static osMutexId_t g_exportAddressMutex = NULL;
+
+static void ExportAddressLock(void)
+{
+ if (g_exportAddressMutex == NULL) {
+ g_exportAddressMutex = osMutexNew(NULL);
+ ASSERT(g_exportAddressMutex != NULL);
+ }
+ osMutexAcquire(g_exportAddressMutex, osWaitForever);
+}
+
+static void ExportAddressUnlock(void)
+{
+ if (g_exportAddressMutex != NULL) {
+ osMutexRelease(g_exportAddressMutex);
+ }
+}
static struct EthParams *NewParams()
{
@@ -82,24 +100,53 @@ static struct EthParams *ParseParams(const char *data, size_t dataLength)
uint8_t GetExportWallet()
{
- if (g_exportAddressParams == NULL) {
- return DEFAULT;
+ uint8_t wallet = DEFAULT;
+ ExportAddressLock();
+ if (g_exportAddressParams != NULL) {
+ wallet = g_exportAddressParams->wallet;
}
- return g_exportAddressParams->wallet;
+ ExportAddressUnlock();
+ return wallet;
}
void ExportAddressApprove()
{
- ExportEthAddress(g_exportAddressParams->requestID, g_exportAddressParams->n, g_exportAddressParams->type);
- SRAM_FREE(g_exportAddressParams);
- g_exportAddressParams = NULL;
+ ExportAddressParams_t params = {0};
+ bool hasPending = false;
+
+ ExportAddressLock();
+ if (g_exportAddressParams != NULL) {
+ params = *g_exportAddressParams;
+ SRAM_FREE(g_exportAddressParams);
+ g_exportAddressParams = NULL;
+ hasPending = true;
+ }
+ ExportAddressUnlock();
+
+ if (!hasPending) {
+ return;
+ }
+ ExportEthAddress(params.requestID, params.n, params.type);
}
void ExportAddressReject()
{
- SendEApduResponseError(EAPDU_PROTOCOL_HEADER, CMD_EXPORT_ADDRESS, g_exportAddressParams->requestID, PRS_EXPORT_ADDRESS_REJECTED, "Export address is rejected");
- SRAM_FREE(g_exportAddressParams);
- g_exportAddressParams = NULL;
+ uint16_t requestID = 0;
+ bool hasPending = false;
+
+ ExportAddressLock();
+ if (g_exportAddressParams != NULL) {
+ requestID = g_exportAddressParams->requestID;
+ SRAM_FREE(g_exportAddressParams);
+ g_exportAddressParams = NULL;
+ hasPending = true;
+ }
+ ExportAddressUnlock();
+
+ if (!hasPending) {
+ return;
+ }
+ SendEApduResponseError(EAPDU_PROTOCOL_HEADER, CMD_EXPORT_ADDRESS, requestID, PRS_EXPORT_ADDRESS_REJECTED, "Export address is rejected");
}
static void ExportEthAddress(uint16_t requestID, uint8_t n, ETHAccountType type)
@@ -149,29 +196,51 @@ static bool CheckExportAcceptable(EAPDURequestPayload_t *payload)
void ExportAddressService(EAPDURequestPayload_t *payload)
{
+ bool isBusy = false;
+ bool paramsStored = false;
+
if (!CheckExportAcceptable(payload)) {
return;
}
+ ExportAddressLock();
if (g_exportAddressParams != NULL) {
+ isBusy = true;
+ }
+ ExportAddressUnlock();
+ if (isBusy) {
SendEApduResponseError(EAPDU_PROTOCOL_HEADER, CMD_EXPORT_ADDRESS, payload->requestID, PRS_EXPORT_ADDRESS_BUSY, "Export address is busy, please try again later");
- SRAM_FREE(g_exportAddressParams);
- g_exportAddressParams = NULL;
return;
}
struct EthParams *params = ParseParams((char *)payload->data, payload->dataLen);
if (!IsValidParams(params)) {
SendEApduResponseError(EAPDU_PROTOCOL_HEADER, CMD_EXPORT_ADDRESS, payload->requestID, PRS_EXPORT_ADDRESS_INVALID_PARAMS, "Invalid params");
+ SRAM_FREE(params);
return;
}
if (params->chain == ETH) {
- g_exportAddressParams = (ExportAddressParams_t *)SRAM_MALLOC(sizeof(ExportAddressParams_t));
- g_exportAddressParams->requestID = payload->requestID;
- g_exportAddressParams->n = params->n;
- g_exportAddressParams->type = params->type;
- g_exportAddressParams->wallet = params->wallet;
+ ExportAddressLock();
+ if (g_exportAddressParams != NULL) {
+ isBusy = true;
+ } else {
+ g_exportAddressParams = (ExportAddressParams_t *)SRAM_MALLOC(sizeof(ExportAddressParams_t));
+ if (g_exportAddressParams != NULL) {
+ g_exportAddressParams->requestID = payload->requestID;
+ g_exportAddressParams->n = params->n;
+ g_exportAddressParams->type = params->type;
+ g_exportAddressParams->wallet = params->wallet;
+ paramsStored = true;
+ }
+ }
+ ExportAddressUnlock();
+
+ if (isBusy || !paramsStored) {
+ SendEApduResponseError(EAPDU_PROTOCOL_HEADER, CMD_EXPORT_ADDRESS, payload->requestID, PRS_EXPORT_ADDRESS_BUSY, "Export address is busy, please try again later");
+ SRAM_FREE(params);
+ return;
+ }
EAPDUResultPage_t *resultPage = (EAPDUResultPage_t *)SRAM_MALLOC(sizeof(EAPDUResultPage_t));
resultPage->command = CMD_EXPORT_ADDRESS;
@@ -186,4 +255,4 @@ void ExportAddressService(EAPDURequestPayload_t *payload)
SRAM_FREE(params);
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/webusb_protocol/general/eapdu_services/service_get_device_info.c b/src/webusb_protocol/general/eapdu_services/service_get_device_info.c
index 1443e83..0ad85d3 100644
--- a/src/webusb_protocol/general/eapdu_services/service_get_device_info.c
+++ b/src/webusb_protocol/general/eapdu_services/service_get_device_info.c
@@ -4,23 +4,50 @@
#include "service_check_lock.h"
#include "user_memory.h"
#include "version.h"
+#include "gui.h"
+#include "gui_lock_widgets.h"
void GetDeviceInfoService(EAPDURequestPayload_t *payload)
{
char buffer[BUFFER_SIZE_32] = {0};
uint8_t mfp[4] = {0};
+
+ if (payload == NULL) {
+ return;
+ }
+
+ if (GuiLockScreenIsTop()) {
+ SendEApduResponseError(EAPDU_PROTOCOL_HEADER, CMD_GET_DEVICE_INFO, payload->requestID, PRS_PARSING_DISALLOWED,
+ "Get device info is not allowed when the device is locked");
+ return;
+ }
+
GetUpdateVersionNumber(buffer);
GetMasterFingerPrint(mfp);
EAPDUResponsePayload_t *result = (EAPDUResponsePayload_t *)SRAM_MALLOC(sizeof(EAPDUResponsePayload_t));
+ if (result == NULL) {
+ SendEApduResponseError(EAPDU_PROTOCOL_HEADER, CMD_GET_DEVICE_INFO, payload->requestID, RSP_FAILURE_CODE, "Internal memory error");
+ return;
+ }
cJSON *root = cJSON_CreateObject();
+ if (root == NULL) {
+ SRAM_FREE(result);
+ SendEApduResponseError(EAPDU_PROTOCOL_HEADER, CMD_GET_DEVICE_INFO, payload->requestID, RSP_FAILURE_CODE, "Internal memory error");
+ return;
+ }
cJSON_AddStringToObject(root, "firmwareVersion", buffer);
snprintf_s(buffer, sizeof(buffer), "%02x%02x%02x%02x", mfp[0], mfp[1], mfp[2], mfp[3]);
cJSON_AddStringToObject(root, "walletMFP", buffer);
char *json_str = cJSON_PrintBuffered(root, BUFFER_SIZE_1024, false);
- printf("json_str = %s\n", json_str);
cJSON_Delete(root);
+ if (json_str == NULL) {
+ SRAM_FREE(result);
+ SendEApduResponseError(EAPDU_PROTOCOL_HEADER, CMD_GET_DEVICE_INFO, payload->requestID, RSP_FAILURE_CODE, "Internal memory error");
+ return;
+ }
+
result->data = (uint8_t *)json_str;
result->dataLen = strlen((char *)result->data);
result->status = RSP_SUCCESS_CODE;
@@ -31,4 +58,4 @@ void GetDeviceInfoService(EAPDURequestPayload_t *payload)
SendEApduResponse(result);
EXT_FREE(json_str);
SRAM_FREE(result);
-}
\ No newline at end of file
+}
diff --git a/src/webusb_protocol/general/eapdu_services/service_trans_usb_pubkey.c b/src/webusb_protocol/general/eapdu_services/service_trans_usb_pubkey.c
deleted file mode 100644
index d0d9e1a..0000000
--- a/src/webusb_protocol/general/eapdu_services/service_trans_usb_pubkey.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "user_memory.h"
-#include "service_echo_test.h"
-
-void GetDeviceUsbPubkeyService(EAPDURequestPayload_t *payload)
-{
- EAPDUResponsePayload_t *result = (EAPDUResponsePayload_t *)SRAM_MALLOC(sizeof(EAPDUResponsePayload_t));
- result->data = payload->data;
- result->dataLen = payload->dataLen;
- result->status = RSP_SUCCESS_CODE;
- result->cla = EAPDU_PROTOCOL_HEADER;
- result->commandType = CMD_GET_DEVICE_USB_PUBKEY;
- result->requestID = payload->requestID;
-
- SendEApduResponse(result);
-
- SRAM_FREE(result);
-}
\ No newline at end of file
diff --git a/src/webusb_protocol/general/eapdu_services/service_trans_usb_pubkey.h b/src/webusb_protocol/general/eapdu_services/service_trans_usb_pubkey.h
deleted file mode 100644
index e100651..0000000
--- a/src/webusb_protocol/general/eapdu_services/service_trans_usb_pubkey.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _SERVICE_TRANS_USB_PUBKEY_H
-#define _SERVICE_TRANS_USB_PUBKEY_H
-
-#include "eapdu_protocol_parser.h"
-
-void GetDeviceUsbPubkeyService(EAPDURequestPayload_t *payload);
-
-#endif
\ No newline at end of file
diff --git a/src/webusb_protocol/internal_protocol_parser.c b/src/webusb_protocol/internal_protocol_parser.c
index 454cf46..ccbad8b 100644
--- a/src/webusb_protocol/internal_protocol_parser.c
+++ b/src/webusb_protocol/internal_protocol_parser.c
@@ -7,12 +7,15 @@
#include "user_memory.h"
#include "assert.h"
-static struct ProtocolParser *global_parser = NULL;
static ProtocolSendCallbackFunc_t g_sendFunc = NULL;
static uint8_t g_protocolRcvBuffer[PROTOCOL_MAX_LENGTH];
+static uint32_t g_internalRcvCount = 0;
+static uint32_t g_internalRcvLen = 0;
static uint8_t *ExecuteService(FrameHead_t *head, const uint8_t *tlvData, uint32_t *outLen);
static uint8_t *ProtocolParse(const uint8_t *inData, uint32_t inLen, uint32_t *outLen);
+static uint32_t GetRcvCount(void);
+static void ResetRcvCount(void);
typedef struct {
uint8_t serviceId;
@@ -36,36 +39,33 @@ void InternalProtocol_Parse(const uint8_t *data, uint32_t len)
}
assert(len <= PROTOCOL_MAX_LENGTH);
- static uint32_t rcvLen = 0;
uint32_t i, outLen;
uint8_t *sendBuf;
for (i = 0; i < len; i++) {
- if (global_parser->rcvCount >= PROTOCOL_MAX_LENGTH) {
- global_parser->rcvCount = 0;
- rcvLen = 0;
+ if (g_internalRcvCount >= PROTOCOL_MAX_LENGTH) {
+ ResetRcvCount();
continue;
}
- if (global_parser->rcvCount == 0) {
+ if (g_internalRcvCount == 0) {
if (data[i] == PROTOCOL_HEADER) {
- g_protocolRcvBuffer[global_parser->rcvCount++] = data[i];
+ g_protocolRcvBuffer[g_internalRcvCount++] = data[i];
}
- } else if (global_parser->rcvCount == 9) {
- g_protocolRcvBuffer[global_parser->rcvCount++] = data[i];
- rcvLen = ((uint32_t)g_protocolRcvBuffer[9] << 8) + g_protocolRcvBuffer[8];
- assert(rcvLen <= (PROTOCOL_MAX_LENGTH - 14));
- } else if (global_parser->rcvCount == rcvLen + 13) {
- g_protocolRcvBuffer[global_parser->rcvCount] = data[i];
- sendBuf = ProtocolParse(g_protocolRcvBuffer, rcvLen + 14, &outLen);
+ } else if (g_internalRcvCount == 9) {
+ g_protocolRcvBuffer[g_internalRcvCount++] = data[i];
+ g_internalRcvLen = ((uint32_t)g_protocolRcvBuffer[9] << 8) + g_protocolRcvBuffer[8];
+ assert(g_internalRcvLen <= (PROTOCOL_MAX_LENGTH - 14));
+ } else if (g_internalRcvCount == g_internalRcvLen + 13) {
+ g_protocolRcvBuffer[g_internalRcvCount] = data[i];
+ sendBuf = ProtocolParse(g_protocolRcvBuffer, g_internalRcvLen + 14, &outLen);
if (sendBuf) {
g_sendFunc(sendBuf, outLen);
SRAM_FREE(sendBuf);
}
- global_parser->rcvCount = 0;
- rcvLen = 0;
+ ResetRcvCount();
} else {
- g_protocolRcvBuffer[global_parser->rcvCount++] = data[i];
+ g_protocolRcvBuffer[g_internalRcvCount++] = data[i];
}
}
}
@@ -77,16 +77,27 @@ static void RegisterSendFunc(ProtocolSendCallbackFunc_t sendFunc)
}
}
-struct ProtocolParser *NewInternalProtocolParser()
+static uint32_t GetRcvCount(void)
{
- if (!global_parser) {
- global_parser = (struct ProtocolParser *)SRAM_MALLOC(sizeof(struct ProtocolParser));
- global_parser->name = INTERNAL_PROTOCOL_PARSER_NAME;
- global_parser->parse = InternalProtocol_Parse;
- global_parser->registerSendFunc = RegisterSendFunc;
- global_parser->rcvCount = 0;
- }
- return global_parser;
+ return g_internalRcvCount;
+}
+
+static void ResetRcvCount(void)
+{
+ g_internalRcvCount = 0;
+ g_internalRcvLen = 0;
+}
+
+const struct ProtocolParser *NewInternalProtocolParser()
+{
+ static const struct ProtocolParser g_internalParser = {
+ .name = INTERNAL_PROTOCOL_PARSER_NAME,
+ .parse = InternalProtocol_Parse,
+ .registerSendFunc = RegisterSendFunc,
+ .getRcvCount = GetRcvCount,
+ .resetRcvCount = ResetRcvCount,
+ };
+ return &g_internalParser;
}
static uint8_t *ProtocolParse(const uint8_t *inData, uint32_t inLen, uint32_t *outLen)
@@ -157,4 +168,4 @@ static uint8_t *ExecuteService(FrameHead_t *head, const uint8_t *tlvData, uint32
printf("err, serviceId=%d not found\n", head->serviceId);
return NULL;
-}
\ No newline at end of file
+}
diff --git a/src/webusb_protocol/internal_protocol_parser.h b/src/webusb_protocol/internal_protocol_parser.h
index 2bb7f2b..e353818 100644
--- a/src/webusb_protocol/internal_protocol_parser.h
+++ b/src/webusb_protocol/internal_protocol_parser.h
@@ -6,6 +6,6 @@
#define INTERNAL_PROTOCOL_HEADER 0x6B
#define INTERNAL_PROTOCOL_PARSER_NAME "internal_protocol_parser"
-struct ProtocolParser* NewInternalProtocolParser();
+const struct ProtocolParser* NewInternalProtocolParser();
-#endif
\ No newline at end of file
+#endif
diff --git a/src/webusb_protocol/protocol_parse.c b/src/webusb_protocol/protocol_parse.c
index 1d96cc4..e90e407 100644
--- a/src/webusb_protocol/protocol_parse.c
+++ b/src/webusb_protocol/protocol_parse.c
@@ -14,26 +14,30 @@
#define PROTOCOL_PARSE_OVERTIME 500
-void ProtocolReceivedData(const uint8_t *data, uint32_t len, ProtocolSendCallbackFunc_t sendFunc)
-{
- static uint32_t lastTick = 0;
- uint32_t tick;
- static struct ProtocolParser *currentParser = NULL;
-
- tick = osKernelGetTickCount();
- currentParser = NewInternalProtocolParser();
-#ifndef BTC_ONLY
+void ProtocolReceivedData(const uint8_t *data, uint32_t len, ProtocolSendCallbackFunc_t sendFunc)
+{
+ static uint32_t lastTick = 0;
+ uint32_t tick;
+ static const struct ProtocolParser *currentParser = NULL;
+
+ if (data == NULL || len == 0) {
+ return;
+ }
+
+ tick = osKernelGetTickCount();
+ currentParser = NewInternalProtocolParser();
+#ifndef BTC_ONLY
if (data[0] == EAPDU_PROTOCOL_HEADER && !GetIsReceivingFile()) {
currentParser = NewEApduProtocolParser();
}
#endif
- if (currentParser->rcvCount != 0) {
- if (tick - lastTick > PROTOCOL_PARSE_OVERTIME) {
- currentParser->rcvCount = 0;
- }
- }
- lastTick = tick;
- currentParser->registerSendFunc(sendFunc);
+ if (currentParser->getRcvCount() != 0) {
+ if (tick - lastTick > PROTOCOL_PARSE_OVERTIME) {
+ currentParser->resetRcvCount();
+ }
+ }
+ lastTick = tick;
+ currentParser->registerSendFunc(sendFunc);
currentParser->parse(data, len);
-}
\ No newline at end of file
+}
diff --git a/src/webusb_protocol/protocol_parse.h b/src/webusb_protocol/protocol_parse.h
index 451394e..4d61eaf 100644
--- a/src/webusb_protocol/protocol_parse.h
+++ b/src/webusb_protocol/protocol_parse.h
@@ -21,10 +21,11 @@ typedef void (*ProtocolSendCallbackFunc_t)(const uint8_t *data, uint32_t len);
void ProtocolReceivedData(const uint8_t *data, uint32_t len, ProtocolSendCallbackFunc_t sendFunc);
struct ProtocolParser {
- char *name;
- uint32_t rcvCount;
+ const char *name;
void (*parse)(const uint8_t *data, uint32_t len);
void (*registerSendFunc)(ProtocolSendCallbackFunc_t sendFunc);
+ uint32_t (*getRcvCount)(void);
+ void (*resetRcvCount)(void);
};
#endif
diff --git a/src/webusb_protocol/services/service_file_trans.c b/src/webusb_protocol/services/service_file_trans.c
index 28b6220..95b8e49 100644
--- a/src/webusb_protocol/services/service_file_trans.c
+++ b/src/webusb_protocol/services/service_file_trans.c
@@ -5,7 +5,6 @@
#include "log_print.h"
#include "user_utils.h"
#include "assert.h"
-#include "md5.h"
#include "cmsis_os.h"
#include "user_fatfs.h"
#include "ff.h"
@@ -21,10 +20,12 @@
#include "user_memory.h"
#include "drv_gd25qxx.h"
#include "data_parser_task.h"
+#include "screen_manager.h"
+#include "power_manager.h"
#define TYPE_FILE_INFO_FILE_NAME 1
#define TYPE_FILE_INFO_FILE_SIZE 2
-#define TYPE_FILE_INFO_FILE_MD5 3
+#define TYPE_FILE_INFO_FILE_SHA256 3
#define TYPE_FILE_INFO_FILE_SIGN 4
#define TYPE_FILE_INFO_FILE_IV 5
@@ -57,7 +58,7 @@
typedef struct {
char fileName[MAX_FILE_NAME_LENGTH + 4];
uint32_t fileSize;
- uint8_t md5[16];
+ uint8_t sha256[32];
uint8_t iv[16];
uint8_t signature[64];
} FileTransInfo_t;
@@ -68,7 +69,7 @@ typedef struct {
uint32_t offset;
} FileTransCtrl_t;
-static MD5_CTX g_md5Ctx;
+static struct sha256_ctx g_sha256Ctx;
static uint8_t *ServiceFileTransInfo(FrameHead_t *head, const uint8_t *tlvData, uint32_t *outLen);
static uint8_t *ServiceFileTransContent(FrameHead_t *head, const uint8_t *tlvData, uint32_t *outLen);
@@ -112,8 +113,11 @@ static const uint8_t g_webUsbPubKey[] = {
};
static const uint8_t g_webUsbUpdatePubKey[] = {
- 4, 63, 231, 127, 215, 161, 146, 39, 178, 99, 72, 5, 235, 237, 64, 202, 34, 106, 164, 5, 185, 127, 141, 97, 212, 234, 38, 101, 157, 218, 241, 31, 235, 233, 251,
- 53, 233, 51, 65, 68, 24, 39, 255, 68, 23, 134, 161, 100, 23, 215, 79, 56, 199, 34, 47, 163, 145, 255, 39, 93, 87, 55, 19, 239, 153
+ 0x04, 0x3F, 0xE7, 0x7F, 0xD7, 0xA1, 0x92, 0x27, 0xB2, 0x63, 0x48, 0x05, 0xEB, 0xED, 0x40, 0xCA,
+ 0x22, 0x6A, 0xA4, 0x05, 0xB9, 0x7F, 0x8D, 0x61, 0xD4, 0xEA, 0x26, 0x65, 0x9D, 0xDA, 0xF1, 0x1F,
+ 0xEB, 0xE9, 0xFB, 0x35, 0xE9, 0x33, 0x41, 0x44, 0x18, 0x27, 0xFF, 0x44, 0x17, 0x86, 0xA1, 0x64,
+ 0x17, 0xD7, 0x4F, 0x38, 0xC7, 0x22, 0x2F, 0xA3, 0x91, 0xFF, 0x27, 0x5D, 0x57, 0x37, 0x13, 0xEF,
+ 0x99
};
const ProtocolServiceCallbackFunc_t g_fileTransInfoServiceFunc[] = {
@@ -161,7 +165,6 @@ static uint8_t *ServiceFileTransInfo(FrameHead_t *head, const uint8_t *tlvData,
Tlv_t sendTlvArray[1] = {0};
uint32_t tlvNumber;
FrameHead_t sendHead = {0};
- uint8_t hash[32];
printf("ServiceFileTransInfo\n");
tlvNumber = GetTlvFromData(tlvArray, 5, tlvData, head->length);
@@ -179,9 +182,9 @@ static uint8_t *ServiceFileTransInfo(FrameHead_t *head, const uint8_t *tlvData,
CHECK_LENGTH(tlvArray[i].length, 4);
g_fileTransInfo.fileSize = *(uint32_t *)tlvArray[i].pValue;
break;
- case TYPE_FILE_INFO_FILE_MD5:
- CHECK_LENGTH(tlvArray[i].length, 16);
- memcpy_s(g_fileTransInfo.md5, sizeof(g_fileTransInfo.md5), tlvArray[i].pValue, 16);
+ case TYPE_FILE_INFO_FILE_SHA256:
+ CHECK_LENGTH(tlvArray[i].length, 32);
+ memcpy_s(g_fileTransInfo.sha256, sizeof(g_fileTransInfo.sha256), tlvArray[i].pValue, 32);
break;
case TYPE_FILE_INFO_FILE_SIGN:
CHECK_LENGTH(tlvArray[i].length, 64);
@@ -198,7 +201,7 @@ static uint8_t *ServiceFileTransInfo(FrameHead_t *head, const uint8_t *tlvData,
printf("file name=%s\n", g_fileTransInfo.fileName);
printf("file size=%d\n", g_fileTransInfo.fileSize);
- PrintArray("md5", g_fileTransInfo.md5, 16);
+ PrintArray("sha256", g_fileTransInfo.sha256, 32);
PrintArray("signature", g_fileTransInfo.signature, 64);
PrintArray("iv", g_fileTransInfo.iv, 16);
SetDeviceParserIv(g_fileTransInfo.iv);
@@ -208,8 +211,7 @@ static uint8_t *ServiceFileTransInfo(FrameHead_t *head, const uint8_t *tlvData,
sendTlvArray[0].value = 4;
break;
}
- sha256((struct sha256 *)hash, g_fileTransInfo.md5, 16);
- if (k1_verify_signature(g_fileTransInfo.signature, hash, (uint8_t *)g_webUsbPubKey) == false) {
+ if (k1_verify_signature(g_fileTransInfo.signature, g_fileTransInfo.sha256, (uint8_t *)g_webUsbPubKey) == false) {
printf("verify signature fail\n");
sendTlvArray[0].value = 3;
break;
@@ -228,7 +230,7 @@ static uint8_t *ServiceFileTransInfo(FrameHead_t *head, const uint8_t *tlvData,
break;
}
g_fileTransCtrl.startTick = osKernelGetTickCount();
- MD5_Init(&g_md5Ctx);
+ sha256_init(&g_sha256Ctx);
if (FatfsFileCreate(g_fileTransInfo.fileName) != RES_OK) {
printf("create file %s err\n", g_fileTransInfo.fileName);
@@ -244,6 +246,8 @@ static uint8_t *ServiceFileTransInfo(FrameHead_t *head, const uint8_t *tlvData,
g_fileTransTimeOutTimer = osTimerNew(FileTransTimeOutTimerFunc, osTimerOnce, NULL, NULL);
}
+ ClearLockScreenTime();
+ ClearShutdownTime();
g_isReceivingFile = true;
osTimerStart(g_fileTransTimeOutTimer, FILE_TRANS_TIME_OUT);
} while (0);
@@ -274,6 +278,8 @@ static uint8_t *ServiceFileTransContent(FrameHead_t *head, const uint8_t *tlvDat
CHECK_POINTER(g_fileTransTimeOutTimer);
osTimerStart(g_fileTransTimeOutTimer, FILE_TRANS_TIME_OUT);
+ ClearLockScreenTime();
+ ClearShutdownTime();
tlvNumber = GetTlvFromData(tlvArray, 2, tlvData, head->length);
@@ -336,7 +342,7 @@ static uint8_t *ServiceFileTransContent(FrameHead_t *head, const uint8_t *tlvDat
return NULL;
}
- MD5_Update(&g_md5Ctx, fileData, fileDataSize);
+ sha256_update(&g_sha256Ctx, fileData, fileDataSize);
return GetFileContent(head, g_fileTransCtrl.offset, outLen);
}
@@ -367,8 +373,7 @@ static uint8_t *GetFileContent(const FrameHead_t *head, uint32_t offset, uint32_
static uint8_t *ServiceFileTransComplete(FrameHead_t *head, const uint8_t *tlvData, uint32_t *outLen)
{
FrameHead_t sendHead = {0};
- uint8_t md5Result[16];
- uint8_t hash[32];
+ struct sha256 sha256Result;
int ret = 0;
if (!g_isReceivingFile) {
@@ -380,16 +385,15 @@ static uint8_t *ServiceFileTransComplete(FrameHead_t *head, const uint8_t *tlvDa
osTimerStop(g_fileTransTimeOutTimer);
g_fileTransCtrl.endTick = osKernelGetTickCount();
PrintArray("tlvData", tlvData, head->length);
- MD5_Final(md5Result, &g_md5Ctx);
+ sha256_done(&g_sha256Ctx, &sha256Result);
do {
- PrintArray("g_fileTransInfo.md5", g_fileTransInfo.md5, 16);
- PrintArray("md5Result", md5Result, 16);
- sha256((struct sha256 *)hash, g_fileTransInfo.md5, 16);
- if (memcmp(md5Result, g_fileTransInfo.md5, 16) != 0) {
+ PrintArray("g_fileTransInfo.sha256", g_fileTransInfo.sha256, 32);
+ PrintArray("sha256Result", sha256Result.u.u8, 32);
+ if (memcmp(sha256Result.u.u8, g_fileTransInfo.sha256, 32) != 0) {
ret = ERR_INVALID_FILE;
break;
}
- if (k1_verify_signature(g_fileTransInfo.signature, hash, (uint8_t *)g_webUsbPubKey) == false) {
+ if (k1_verify_signature(g_fileTransInfo.signature, g_fileTransInfo.sha256, (uint8_t *)g_webUsbPubKey) == false) {
printf("verify signature fail\n");
ret = ERR_INVALID_FILE;
break;
@@ -473,11 +477,11 @@ static uint8_t *ServiceFileTransGetPubkey(FrameHead_t *head, const uint8_t *tlvD
uint8_t hash[32] = {0};
sha256((struct sha256 *)hash, pubKey, 33);
if (k1_verify_signature(pubKeySign, hash, (uint8_t *)g_webUsbUpdatePubKey) == false) {
- printf("verify signature fail\n");
+ printf("verify pubkey signature fail\n");
tlvArray[0].length = 4;
tlvArray[0].value = 3;
} else {
- printf("verify signature success\n");
+ printf("verify pubkey signature success\n");
tlvArray[0].length = 33;
tlvArray[0].pValue = GetDeviceParserPubKey(pubKey, sizeof(pubKey) - 1);
}
@@ -545,8 +549,7 @@ static void WriteNftToFlash(void)
static uint8_t *ServiceNftFileTransComplete(FrameHead_t *head, const uint8_t *tlvData, uint32_t *outLen)
{
FrameHead_t sendHead = {0};
- uint8_t md5Result[16];
- uint8_t hash[32];
+ struct sha256 sha256Result;
int ret = 0;
if (!g_isReceivingFile) {
@@ -559,18 +562,17 @@ static uint8_t *ServiceNftFileTransComplete(FrameHead_t *head, const uint8_t *tl
osTimerStop(g_fileTransTimeOutTimer);
g_fileTransCtrl.endTick = osKernelGetTickCount();
PrintArray("tlvData", tlvData, head->length);
- PrintArray("g_fileTransInfo.md5", g_fileTransInfo.md5, 16);
- MD5_Final(md5Result, &g_md5Ctx);
- PrintArray("md5Result", md5Result, 16);
+ PrintArray("g_fileTransInfo.sha256", g_fileTransInfo.sha256, 32);
+ sha256_done(&g_sha256Ctx, &sha256Result);
+ PrintArray("sha256Result", sha256Result.u.u8, 32);
printf("total tick=%d\n", g_fileTransCtrl.endTick - g_fileTransCtrl.startTick);
do {
- sha256((struct sha256 *)hash, g_fileTransInfo.md5, 16);
- if (memcmp(md5Result, g_fileTransInfo.md5, 16) != 0) {
+ if (memcmp(sha256Result.u.u8, g_fileTransInfo.sha256, 32) != 0) {
ret = ERR_INVALID_FILE;
break;
}
- if (k1_verify_signature(g_fileTransInfo.signature, hash, (uint8_t *)g_webUsbPubKey) == false) {
+ if (k1_verify_signature(g_fileTransInfo.signature, g_fileTransInfo.sha256, (uint8_t *)g_webUsbPubKey) == false) {
printf("verify signature fail\n");
ret = ERR_INVALID_FILE;
break;
@@ -598,4 +600,4 @@ static uint8_t *ServiceNftFileTransComplete(FrameHead_t *head, const uint8_t *tl
return BuildFrame(&sendHead, NULL, 0);
}
-#endif
\ No newline at end of file
+#endif
Why this scored 57/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.