# M2354(Lin)
## qualifiers
### const
read-only variable, but still can be changed by pointer.
global const varialbe is placed in read only memory(FLASH memory) which can't be changed by pointer.
### volatile
The input might change manually but software didn't notice that. We have to give volatile to port on the harware to not ignore the changes in hardware.
be careful of empty loop.
## pin read
make sure the pin is free I/O if you want to use it.
## Union
1. bit extraction
2. storing mutually exclusive data thus saving memory.
## Operational mode of M0/M3/M4
All will start with Thread mode (User mode)
### Thread mode
application code will execute under "Thread mode" of the processor. This is also called as "User mode"
### handler mode
exception handlers or interrupt handlers will run under the "Handler mode" of the processor.
## Check operation mode implementation
### ISR_NUMBER
0 means in Thread mode, other wise in handler mode.

The first 9 bits of the register.

- In handler mode (line 50)

the interruption if from software for IRQ3 (which is 19 in ISR_NUMBER)
## Access level
#### Privileged Access Level (PAL)
Default
#### Non-privileged Access Level (NPAL)
- possible to get in NPAL in thread mode. Once moving out of PAL in thread mode, it's not possible to come back unless the operational mode changed to "handler mode"
## Core register
- R0 to R12 registers are for general purpose.
- All core registers are 32 bit wide.
- R13 is SP (stack pointer.)
- R14 (LR) Link Register, which store the return information when function called for exceptino handling.
- R15 Program Counter, which holds the address of the next instruction to be executed.
### Special registers
#### Program Status Register
- Application Program Status Register (APSR)
- Interrupt Program Status Register (IPSR)
- Execution Program Status Register (EPSR)
For EPSR, the 'T' bit is important.
If 'T' bit is set to 1, processor thinks that the next instruction which it is about to execute is from Thumb ISA
If 'T' bit is reset to 0, processor thinks that the next instruction which is about to execute is from ARM ISA.
## inline assembly
### __asm volatile("")
__asm or asm
general form
- __asm volatile (code : output operand list : input operand list : clobber list);
##### __asm volatile ("MOV R0,%0": : "r"(val));
output operand will be empty for MOV
"r" is a constraint character, which means to use the General registers r0 ... r15, and "val" is a "C" vaiable

### MRS and MSR instructions
S stands for special register
##### __asm volatile ("MRS %0,CONTROL":"=r"(control_reg)::)

only r for MRS since the destination must be general registers.
##### __asm ("MOV %0,%1": "=r"(p1): "r"(p2));
considering
```cpp
int p1, *p2;
p2 = ((int*)0x20000008);
```
## Switch between privileged and unprivileged access level
It's possible to change to Unpriv in priv access level, but once you were in Unpriv, you can't directly change back. Instead, you should go into Handler Mode and since it's always priviledge access in ISR(where for handler mode), you will be able to return privileged access level

## T bit of the EPSR
- T bit decide whether the next instruction is from Thumb IS or ARM ISA
cortex Mx processor doesn't support ARM state, which means the T bit must be 1.
## Bit Band
#### General formula
Alias address = alias_base + (32 * (bit_band_memory_addr - bit_band_base)) + bit * 4
##### only for SRAM region and peripheral regions
## Stack Pointers
### R13, MSP and PSP
- MSP will be selected as current stack pointer by default after reset. SP copies the contents of MSP.
- PSP is used in Thread mode by configuring the CONTROL register's SPSEL bit. PSP will be selected when SPSEL = 1. SP will cpoies PSP in this situation.
- MSP is always used in Handler mode whatever the SPSEL is.
- MSP will be initialized by reading the content of the address 0x0000_0000.
## Exception Model
- system exceptions (internal)
- interrupts (external)
### NVIC
1) Cortex M processor supports 240 interrupts
2) These interrupts are managed and configured using NVIC
3) What are those 240 interrupts?
this is highly vendor specific and it is triggered by various on chip peripherals of the MCU like SPI, gpios, timers, dmas, etc.
## Faults
### Hard-fault exception
##### Causes
1) Escalation of configuable fault exceptions
2) Bus error returned during a vector fetch Execution of break point instruction when both halt mode and debug monitor is disabled
3) Executing SVC instruction inside SVC handler
#### HardFault Status Register
[1] VECTTBL : whether Bus Fault on vector table is read.
[30] FORCED : Hard fault generated by escalation of a fault with configurable priority.
[31] DEBUGEVT : This bit should be 0 when writing to the register.
### Mem manage fault exception
##### Causes
1) when memory access violation is detected (access permission by the processor or MPU)
2) Unprivileged thread mode code tries to access a memory region which is marked as "priviledge access only" by the MPU
3) Writing to memory regions which are marked as read-only by the MPU4.
4) when trying to execute program code from "peripheral" memory regions, which are marked as XN(eXecute Never) regions by the processor design to avoid code injection attacks through peripherals.
### Bus-fault exception
##### Causes
1) error response returned by the processor bus interfaces during access to memory devices
2) If bus error happens during vector fetch, it will be escalated to a hard fault even if bus fault exception is enabled.
3) Memory device sends error response when the processor bus interface tries to access invalid or restricted memory locations which could generate a bus fault
4) When the device is not ready to accept memory transfer
5) When playing with external memories such as SDRAM connected via DRAM controllers
6) Unprivileged access to the private peripheral bus
### Usage-fault exception
##### Causes
1) Execution of undefined instructions
2) Executing floating point instruction keeping floating point unit disabled
3) Trying to switch to ARM state to execute ARM ISA instructions. The T bit of the processor decides ARM state of THUMB state. (Marking T bit 0 in cortex M)
4) Trying to return to thread mode when an exception/interrupt is still active
5) Unaligned memory access with multiple load or multiple store insturcions.
6) Attempt to divicde by zero
7) For all unaligned data access from memory (only if enabled, otherwise cortex m supports unaligned data access)
# Week5

### SRL (secure region lock)
### ARL (all region lock)
lock when ARL != 0x5A

SRL lock after first development

ARL lock after second development



## AES algorithm
input a 128-bit plaintext (16 bytes)
using key with 128-bit (most used), 192-bit or 256-bit long
AES is strong because of its long key comparing to DES (56-bit key)
### state array
break down the 128 bits into the order below (starts from b0 to b15)
| $b_0$ | $b_4$ | $b_8$ | $b_{12}$ |
| ----- | ----- | ----- | -------- |
| $b_1$ | $b_5$ | $b_9$ | $b_{13}$ |
| $b_2$ | $b_6$ | $b_{10}$ | $b_{14}$ |
| $b_3$ | $b_7$ | $b_{11}$ | $b_{15}$ |
### steps
1) $\textbf{key expand}$ and plaintext $\oplus$ part of the key
2) substitute Bytes
3) shift rows
4) mix columns
5) Add Round key (using $\oplus$)
there are 10 rounds for 128-bit, 12 for 192-bit and 14 for 256-bit
### key expand
consider n rounds, the key should be expanded into n + 1 rounds
The first round is for $\oplus$ the plaintext
4 words in each key and each key is for a single round
### substitute Bytes
Using S-Box to substitute every block

### shift rows
1st row -> no changes
2nd row -> 1 to the left
3rd row -> 2 to the left
4the row -> 3 to the left
### mix columns
multiplication between the original grid and this const matrix for this step

### substitution permutation
[wiki for sp network](https://zh.wikipedia.org/zh-tw/代换-置换网络)
### application of AES
- wireless security
- encrypting browsing (ssl)
- general file encryption
## WIFI module
- ESP-12F


no response, but list the connected user when connecting or disconnecting to it.
用rt-thread,這好難用
## AT command
### command sent between wifi module and serial port
### some commonly used commands
- AT : to check if AT command is working
- AT+RST : reset the module
- AT+CWMODE : mode of the wifi module
- AT+CWJAP : to provide wifi info, usually add "SSID", "Password" after it
- AT+CWLAP : to list all available wifi around the device.
# Week 9 (RT-thread)
RT-Thread(Real-Time Thread)是一個開源的嵌入式即時作業系統(RTOS),專門設計用於嵌入式系統和物聯網設備。它致力於為資源有限的嵌入式平台提供高效的即時排程和管理功能,以滿足即時性要求。
### Download rt-thread bsp for numaker m2354
[link for all rt-thread bsp](https://github.com/RT-Thread/rt-thread), which has some problem for numaker m2354.
#### Codes I can run correctly
[link for rt-thread bsp (m2354)](https://github.com/wosayttn/sdk-bsp-numaker-m2354)
### rt-thread env download
[link for rt-thread env](https://www.rt-thread.io/download.html?download=Env)
Unzip to the folder you want.
### How to use and how to create a project
get into the m2354 bsp folder, right click and choose ConEmu Here.


Terminal will jump out and type "menuconfig --generate", "pkgs --list", "pkgs --update" to update the settings.
Type "scons" to compile the bsp, type "scons --target=mdk5" to create a mdk5 project.
Now you can open the mdk5 project in uvision.
### Settings in uvision
The default debugger will be Ulink, click here and select the debugger to be Nulink and click setting, change the MCU to m2354.
Finally we can compile and download the code into the board.

### After Downloading the code into m2354
Open PuTTy as we learnt before. we can see that rt-thread done the communication between the board and wifi module for us. we only have to type "at client" then we can start setting the wifi module through AT command.


### demo command
AT
AT+CWJAP?
AT+CWLAP
AT+CWJAP="",""
AT+CWQAP
http://yhhuang1966.blogspot.com/2015/07/esp8266-wifi-at-command.html
https://www.rt-thread.io/document/site/programming-manual/env/env/
https://club.rt-thread.org/ask/article/03f1452dd9d849a5.html
# Week 10
## BlueTooth HC-05/UART1
### Code Explain
#### In Non-secure world file "cp.c"

# Google Test / Mock
- Base on xUnit architecture
- Write Unit test in and for C++
## Environment Setting
[github link](https://github.com/google/googletest)
I'm running this in wsl.
clone the project
- command
```=
git clone https://github.com/google/googletest.git
cd googletest # Main directory of the cloned repository.
mkdir build # Create a directory to hold the build output.
cd build
cmake .. # Generate native build scripts for GoogleTest.
make
sudo make install # sudo to make sure the highest authority
```
make sure you have Cmake, install it if you don't
```=
# Ubuntu
sudo apt install cmake
# Mac
sudo brew install cmake
```
I don't know how to install in windows, maybe in their website
compile code
```=
g++ [filename] -lgtest -lgtest_main -pthread -lgmock (if you are running gmock)
```
## Assertion
- EXPECT : non-fatal error
- ASSERT : fatal error


## Unit test
#### Arrange
- to arrange everything required to run in the Test
#### Act
- Run the test
#### Assert
- verify the output
```c++=
#include <iostream>
#include <gtest/gtest.h>
using namespace std;
using namespace testing;
class TestFunction {
int V;
public:
TestFunction (int _V) : V(_V) {}
int get_number () {
return V;
}
};
TEST (TestName, subTestName) {
//Arrange
int a;
TestFunction tmp(5);
//Act
a = tmp.get_number();
//ASSERT
ASSERT_EQ(a, 5);
}
int main (int argc, char **argv) {
InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
```
### More about
- Run extremely fast
- Must be able to run independently
- Doesn't depend upon any external input
## Test Fixtures
- To test multiple tasks with same data
- Declare a struct with variables you want to test for different cases.
```c++=
#include <iostream>
#include <vector>
#include <gtest/gtest.h>
using namespace std;
class Stack {
vector<int> vstack = {};
public:
void push (int value) { vstack.push_back(value); }
int pop () {
if (vstack.size() > 0) {
int value = vstack.back();
vstack.pop_back();
return value;
} else {
return -1;
}
}
int size () { return vstack.size(); }
};
struct stackTest : public testing::Test {
Stack s1;
void SetUp () {
int value[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (auto &val : value) {
s1.push(val);
}
}
void TearDown () {}
};
TEST_F (stackTest, PopTest) {
int lastPoppedValue = 9;
while (lastPoppedValue != 1) {
EXPECT_EQ(s1.pop(), lastPoppedValue--);
}
}
TEST_F (stackTest, sizeTest) {
int val = 9;
for (int i = 0; i < 9; ++i) {
EXPECT_EQ(s1.size(), val--);
s1.pop();
}
}
int main (int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
```
## Google Mock (gmock)
- Used to test code which needs to interact with other Objects. For example, database.
- You can build a simulated environment which mock the behaviour of the object you will interact with, including return values, exception throwing, and the number of function calls.
### EXPECT_CALL
- .Times() to set how many times to call the function
- .WillOnce(Return()) to set the return value
- .WillRepeatedly(Return()) to set the return value for repeatedly called function in .Times()
```c++=
#include <iostream>
#include <vector>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using namespace std;
using ::testing::AtLeast;
using ::testing::Return;
using ::testing::_;
class DataBaseConnect {
public :
virtual bool login (string username, string password) {
return true;
}
virtual bool logout (string username) {
return true;
}
virtual int fetchRecord() {
return -1;
}
};
class MockDB :public DataBaseConnect {
public:
MOCK_METHOD0(fetchRecord, int ());
MOCK_METHOD1(logout, bool (string username));
MOCK_METHOD2(login, bool (string username, string password));
};
class MyDatabase {
DataBaseConnect & dbC;
public:
MyDatabase(DataBaseConnect &_dbC) : dbC(_dbC) {}
int Init (string username, string password) {
if (dbC.login(username, password) != true) {
if (dbC.login(username, password) != true) {
cout << "DB FALIURE\n";
return -1;
}
} else {
cout << "DB SUCCESS\n";
return 1;
}
}
};
TEST (MyDBTest, LoginTest) {
//Arrange
MockDB mdb;
MyDatabase db(mdb);
EXPECT_CALL(mdb, login(_, _))
.Times(1)
.WillOnce(Return(true));
/*
.Times(2)
.WillRepeatedly(Return());
*/
//Act
int rev = db.Init("shuchen", "hello");
//ASSERT
EXPECT_EQ(rev, 1);
}
TEST (MyDBTest, LoginFailure) {
//Arrange
MockDB mdb;
MyDatabase db(mdb);
EXPECT_CALL(mdb, login(_, _))
.Times(AtLeast(1))
.WillOnce(Return(false));
//Act
int rev = db.Init("shuchen", "byebye");
//Assert
EXPECT_EQ(rev, -1);
}
int main (int argc, char **argv) {
testing:: InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
```
### ON_CALL
EXPECT_CALL require us to call the functions for times, however, ON_CALL only tell function what to return but didn't require the times for calling the functions.
Here's an example
```c++=
TEST(CalculatorTest, AddFunctionWithExpectCall) {
MockCalculator mockCalculator;
EXPECT_CALL(mockCalculator, Add(2, 3))
.WillOnce(testing::Return(5));
int result = mockCalculator.Add(2, 3);
ASSERT_EQ(result, 5);
}
TEST(CalculatorTest, AddFunctionWithOnCall) {
MockCalculator mockCalculator;
ON_CALL(mockCalculator, Add(testing::_, testing::_))
.WillByDefault(testing::Return(10));
int result = mockCalculator.Add(4, 6);
ASSERT_EQ(result, 10);
}
TEST(CalculatorTest, AddFunctionWithFallback) {
MockCalculator mockCalculator;
int result = mockCalculator.Add(4, 6);
// It will pass the test since we set the default return value of Add to 10
ASSERT_EQ(result, 10);
}
```
- DoDefault()
```c++=
TEST (MyDBTest, LoginFailure) {
//Arrange
MockDB mdb;
MyDatabase db(mdb);
ON_CALL(mdb, login(_, _)).WillByDefault(return(true))
EXPECT_CALL(mdb, login(_, _))
.Times(AtLeast(1))
.WillOnce(DoDefault());
//Act
int rev = db.Init("shuchen", "byebye");
//Assert
EXPECT_EQ(rev, -1);
}
```
### Invoke
- Use with EXPECT_CALL or ON_CALL
可以另外呼叫自定義的函式,可以執行一些函式裡面的功能像是cout
```c++=
struct testABC {
bool dummylogin (string a, string b) {
cout << "Dummy login\n";
return true;
}
};
TEST (MyDBTest, LoginTest) {
//Arrange
MockDB mdb;
MyDatabase db(mdb);
testABC dbTest;
EXPECT_CALL(mdb, login(_, _))
.Times(1)
.WillOnce(Invoke(&dbTest, &testABC::dummylogin));
//Act
int rev = db.Init("shuchen", "hello");
//ASSERT
EXPECT_EQ(rev, 1);
}
```
輸出

#### InvokeWithoutArgs
```c++=
bool Dummyfn() {
cout << "Global function called\n";
return true;
}
TEST (MyDBTest, LoginTest) {
//Arrange
MockDB mdb;
MyDatabase db(mdb);
EXPECT_CALL(mdb, login(_, _))
.Times(1)
.WillOnce(InvokeWithoutArgs(Dummyfn));
//Act
int rev = db.Init("shuchen", "hello");
//ASSERT
EXPECT_EQ(rev, 1);
}
```
#### Invoke multiple actions
```c++=
struct testABC {
void dummylogin (string a, string b) {
cout << "Dummy login called\n";
return;
}
void dummylogin2 (string a, string b) {
cout << "Dummy login2 test\n";
return;
}
};
TEST (MyDBTest, LoginTest) {
//Arrange
MockDB mdb;
MyDatabase db(mdb);
testABC dbTest;
EXPECT_CALL(mdb, login(_, _))
.Times(1)
.WillOnce(DoAll(Invoke(&dbTest, &testABC::dummylogin),
Invoke(&dbTest, &testABC::dummylogin2),
Return(true)));
/*
.Times(2)
.WillRepeatedly(Return());
*/
//Act
int rev = db.Init("shuchen", "hello");
//ASSERT
EXPECT_EQ(rev, 1);
}
```
parameter should be the same as the original function you call
output

# Elliptic Curve Cryptography (ECC)
## Overview
Elliptic Curve Cryptography (ECC) is a branch of public-key cryptography that leverages the mathematical properties of elliptic curves over finite fields. ECC provides a powerful and efficient means of ensuring the confidentiality, integrity, and authenticity of digital communications.
## Key Components
### 1. Elliptic Curves
- ECC is based on the mathematical properties of elliptic curves, defined by the equation $y^2 = x^3 + ax + b$, where $a$ and $b$ are constants. The curve is defined over a finite field $GF(p)$, where $p$ is a prime number.
### 2. Key Generation
- **Private Key ($d$):** A random integer chosen from the range $[1, n-1]$, where $n$ is the order of the elliptic curve group.
- **Public Key ($Q$):** Computed as $Q = d \times G$, where $G$ is the generator point on the elliptic curve.
## Encryption and Decryption
- **Encryption:** The sender computes a shared secret ($S$) by multiplying the recipient's public key ($Q$) with their private key ($d$). The shared secret is then used to derive a symmetric key for encrypting the message.
- **Decryption:** The recipient computes the shared secret ($S$) by multiplying their private key ($d$) with the sender's public key ($Q$). The same symmetric key is derived for decrypting the message.
## Digital Signatures
- ECC can be used for digital signatures through algorithms like ECDSA (Elliptic Curve Digital Signature Algorithm). It involves generating a signature using the private key and verifying it using the public key.
## Security Advantages
- ECC provides the same level of security as traditional cryptographic systems but with shorter key lengths, making it computationally more efficient.
- Resistance to attacks such as the elliptic curve discrete logarithm problem contributes to ECC's robust security.
# Elliptic Curve Diffie-Hellman (ECDH)
## Overview
Elliptic Curve Diffie-Hellman (ECDH) is a key exchange algorithm based on Elliptic Curve Cryptography (ECC). It allows two parties to jointly establish a shared secret over an insecure communication channel. This shared secret can then be used for secure communication or as a basis for deriving symmetric encryption keys.
## Key Exchange Process
1. **Alice's Key Exchange:**
- Alice generates her private key $a$ and corresponding public key $A = a \times G$.
2. **Bob's Key Exchange:**
- Bob generates his private key $b$ and corresponding public key $B = b \times G$.
3. **Shared Secret Calculation:**
- Alice computes the shared secret $S$ as $S = a \times B$.
- Bob computes the shared secret $S$ as $S = b \times A$.
4. **Result:**
- Both Alice and Bob now share the same secret $S$ without explicitly transmitting it.
## Security Advantages
- ECDH provides a secure method for two parties to agree on a shared secret over an insecure channel.
- The security of ECDH relies on the difficulty of the elliptic curve discrete logarithm problem.
# Elliptic Curve Digital Signature Algorithm (ECDSA)
## Overview
The Elliptic Curve Digital Signature Algorithm (ECDSA) is a widely used public-key cryptography algorithm for securing digital signatures. It is based on the mathematical properties of elliptic curves over finite fields. ECDSA is commonly employed for ensuring the integrity and authenticity of digital messages.
## Key Components
### 1. Elliptic Curves
ECDSA relies on the mathematical properties of elliptic curves. An elliptic curve is defined by the equation: y^2 = x^3 + ax + b, where a and b are constants. The curve is defined over a finite field, often denoted as GF(p), where p is a prime number.
### 2. Key Generation
- **Private Key (d):** A random integer chosen from the range [1, n-1], where n is the order of the elliptic curve group.
- **Public Key (Q):** Computed as (Q = d $\times$ G), where G is the generator point on the elliptic curve.
### 3. Signing
To sign a message (m):
1. Generate a random integer (k) from [1, n-1].
2. Compute the temporary point P = k $\times$ G.
3. Calculate r = $x_P$ mod n, where $x_P$ is the x-coordinate of point P.
4. Compute s = $k^{-1} \times$ (H(m) + d $\times$ r) mod n, where H(m) is the hash of the message.
5. The signature is (r, s).
### 4. Verification
To verify a signature (r, s) for a message (m):
1. Verify that ( r ) and ( s ) are in the range [1, n-1].
2. Compute (w = $s^{-1}$ mod n).
3. Calculate ($u_1$ = H(m) times w mod n) and ($u_2$ = r times w mod n).
4. Compute the temporary point (P = $u_1$ times G + $u_2$ times Q).
5. If ($x_P$ mod n = r), the signature is valid.
## Security Considerations
ECDSA provides a high level of security when implemented correctly. The security of ECDSA relies on the difficulty of the elliptic curve discrete logarithm problem.
## Conclusion
Elliptic Curve Digital Signature Algorithm is a powerful cryptographic technique for ensuring the integrity and authenticity of digital signatures. When properly implemented and with secure key management, it provides a robust solution for secure communication and data integrity.
| Block Factor | integer instructions | Shared Load (GB/s) | Shared Store (GB/s) | Global Load (GB/s) | Global Store (GB/s) | Execution Time (ms) |
|--------------|------------------------|---------------------|----------------------|---------------------|----------------------|---------------------|
| 64 | 2847117312 | 3331.8 | 277.56 | 208.24 | 69.413 | 108.39 |
| 32 | 1601114112 | 2344.2 | 586.06 | 293.03 | 97.676 | 147.53 |
| 16 | 1003032576 | 573.85 | 286.93 | 143.46 | 95.642 | 678.49 |
| 8 | 703991808 | 625.27 | 312.63 | 312.63 | 104.21 | 1170.29 |
### 3/5
cold wallet (hardware wallet) with secure element and microcontroller.
| Name | Secure Element | SE Model + Microcontroller |
|---------------|----------------|------------------------------|
| Trezor | NO | N/A |
| Ledger Nano X | YES | ST33J2M0 + STM32WB55 |
| Bitbox02 | YES | ATECC608B + ATSAMD51J20A |
| Passport | YES | ATECC608A + STM32H753 |
| Ledger Nano S | YES | ST31H320 + STM32F042K6 |
| Ledger Nano S Plus | YES | ST33K1M5C + STM32... |
如果把trustzone中的secure world 獨立出來並用另外一個板子當作microcontroller 的話,我們的架構就會與市面上許多的冷錢包相同(尤其是我們之前特別關注的ledger)
可以看到ledger不但使用了有trustzone技術的cortex M35p(base of their secure element),他們的安全晶片也比我們的m2354更安全。