[英]How do I include a switch-case statement for this encryption/decryption code?
I just started using a microcontroller and I have to implement encryption/decryption in it. 我刚刚开始使用微控制器,并且必须在其中实现加密/解密。 Sorry for the super long post.
对不起,超长职位。
This is the python script and do not need to be edited. 这是python脚本,不需要进行编辑。
DEVPATH = "/dev"
TTYPREFIX = "ttyACM"
INPUT = b"Hello!"
#OUTPUT = b"Ifmmp!"
if __name__=='__main__':
for tty in (os.path.join(DEVPATH,tty) for tty in os.listdir(DEVPATH) \
if tty.startswith(TTYPREFIX)):
try:
ctt = serial.Serial(tty, timeout=1, writeTimeout=1)
except serial.SerialException:
continue
ctt.flushInput()
ctt.flushOutput()
# print(ctt)
try:
ctt.write(INPUT)
except serial.SerialTimeoutException:
ctt.__exit__()
continue
for retry in range(3): # Try three times to read connection test result
ret = ctt.read(2*len(INPUT))
print("ret: " + repr(ret))
if INPUT in ret:
sys.exit(0)
break
else:
ctt.__exit__()
continue
break
else:
print("Failed")
sys.exit(1)
This is the main.c file. 这是main.c文件。 I know that CDC_Device_BytesReceived will receive the input from the python script.
我知道CDC_Device_BytesReceived将接收来自python脚本的输入。 And if there are input, it will run the while loop since Bytes will be more than 0.
如果有输入,它将运行while循环,因为Bytes将大于0。
while (1)
{
/* Check if data received */
Bytes = CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface);
while(Bytes > 0)
{
/* Send data back to the host */
ch = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
CDC_Device_SendByte(&VirtualSerial_CDC_Interface, ch);
--Bytes;
}
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
}
return 0;
}
However, in the loop, I was tasked to add a switch case so that it will switch between encryption and decryption. 但是,在循环中,我受命添加一个切换盒,以便它可以在加密和解密之间切换。 But I have no idea what kind of condition to use to differentiate the encryption and decryption.
但是我不知道使用哪种条件来区分加密和解密。
This is the code for encryption. 这是加密代码。
int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen,
const unsigned char* m, unsigned long long mlen,
const unsigned char* ad, unsigned long long adlen,
const unsigned char* nsec, const unsigned char* npub,
const unsigned char* k)
{
int klen = CRYPTO_KEYBYTES; // 16 bytes
int size = 320 / 8; // 40 bytes
int rate = 128 / 8; // 16 bytes
// int capacity = size - rate;
// Permutation
int a = 12;
int b = 8;
// Padding process appends a 1 to the associated data
i64 s = adlen / rate + 1;
// Padding process appends a 1 to the plain text
i64 t = mlen / rate + 1;
// Length = plaintext mod r
// i64 l = mlen % rate;
u8 S[size];
// Resulting Padded associated data is split into s blocks of r bits
u8 A[s * rate];
// Resulting Padded plain text is split into t blocks of r bits
u8 P[t * rate];
i64 i, j;
// Pad Associated Data
for(i = 0; i < adlen; ++i)
{
A[i] = ad[i];
A[adlen] = 0x80; // 128 bits
// No Padding Applied
for(i = adlen + 1; i < s * rate; ++i)
{
A[i] = 0;
}
}
// Pad Plaintext
for(i = 0; i < mlen; ++i)
{
P[i] = m[i];
P[mlen] = 0x80; // 128 bits
// No Padding Applied
for(i = mlen + 1; i < t * rate; ++i)
{
P[i] = 0;
}
}
// Initialization
// IV = k || r || a || b || 0
// S = IV || K || N
S[0] = klen * 8;
S[1] = rate * 8;
S[2] = a;
S[3] = b;
// i < 40 - 2 * 16 = 8
for(i = 4; i < size - 2 * klen; ++i)
{
// S[4] until S[7] = 0
S[i] = 0;
}
// i < 16
for(i = 0; i < klen; ++i)
{
// S[8] = k[0], S[9] = k[1] until S[23] = k[15]
S[size - 2 * klen + i] = k[i];
}
// i < 16
for(i = 0; i < klen; i++)
{
// S[24] = npub[0], S[25] = npub[1] until S[39] = npub[15]
S[size - klen + i] = npub[i];
}
printstate("Initial Value: ", S);
// S - state, 12-a - start, a - 12 rounds
permutations(S, 12 - a, a);
// i < 16
for(i = 0; i < klen; ++i)
{
// S[24] ^= k[0], S[25] ^= k[1] until S[39] ^= k[15]
S[size - klen + i] ^= k[i];
}
printstate("Initialization: ", S);
// Process Associated Data
if(adlen != 0)
{
// i < s = (adlen / rate + 1)
for(i = 0; i < s; ++i)
{
// rate = 16
for(j = 0; j < rate; ++i)
{
// S ^= A
S[j] ^= A[i * rate + j];
}
// S - state, 12-b - start, b - 8 rounds
permutations(S, 12 - b, b);
}
}
// S <- S ^= 1
S[size - 1] ^= 1;
printstate("Process Associated Data: ", S);
// Process Plain Text
for(i = 0; i < t - 1; ++i)
{
for(j = 0; j < rate; ++j)
{
// S <- S ^= P
S[j] ^= P[i * rate + j];
// c <- S
c[i * rate + j] = S[j];
}
// S <- permutation b (S)
permutations(S, 12 - b, b);
}
for(j = 0; j < rate; ++j)
{
// S <- S ^= Pt
S[j] ^= P[(t-1) * rate + j];
}
for(j = 0; j < 1; ++j);
{
// C <- S
// Bitstring S truncated to the first (most significant) k bits
c[(t - 1) * rate + j] = S[j];
}
printstate("Process Plaintext: ", S);
// Finalization
for(i = 0; i < klen; ++i)
{
S[rate + i] ^= k[i];
}
permutations(S, 12 - a, a);
for(i = 0; i < klen; ++i)
{
// T <- S ^= k
// Bitstring S truncated to the last (least significant) k bits
S[size - klen + i] ^= k[i];
}
printstate("Finalization: ", S);
// Return Cipher Text & Tag
for(i = 0; i < klen; ++i)
{
c[mlen + i] = S[size - klen + i];
}
*clen = mlen + klen;
return 0;
}
and the code for decryption 和解密代码
int crypto_aead_decrypt(unsigned char *m, unsigned long long *mlen,
unsigned char *nsec, const unsigned char *c,
unsigned long long clen, const unsigned char *ad,
unsigned long long adlen, const unsigned char *npub,
const unsigned char *k)
{
*mlen = 0;
if (clen < CRYPTO_KEYBYTES)
return -1;
int klen = CRYPTO_KEYBYTES;
// int nlen = CRYPTO_NPUBBYTES;
int size = 320 / 8;
int rate = 128 / 8;
// int capacity = size - rate;
int a = 12;
int b = 8;
i64 s = adlen / rate + 1;
i64 t = (clen - klen) / rate + 1;
i64 l = (clen - klen) % rate;
u8 S[size];
u8 A[s * rate];
u8 M[t * rate];
i64 i, j;
// pad associated data
for (i = 0; i < adlen; ++i)
{
A[i] = ad[i];
}
A[adlen] = 0x80;
for (i = adlen + 1; i < s * rate; ++i)
{
A[i] = 0;
}
// initialization
S[0] = klen * 8;
S[1] = rate * 8;
S[2] = a;
S[3] = b;
for (i = 4; i < size - 2 * klen; ++i)
{
S[i] = 0;
}
for (i = 0; i < klen; ++i)
{
S[size - 2 * klen + i] = k[i];
}
for (i = 0; i < klen; ++i)
{
S[size - klen + i] = npub[i];
}
printstate("initial value:", S);
permutations(S, 12 - a, a);
for (i = 0; i < klen; ++i)
{
S[size - klen + i] ^= k[i];
}
printstate("initialization:", S);
// process associated data
if (adlen)
{
for (i = 0; i < s; ++i)
{
for (j = 0; j < rate; ++j)
{
S[j] ^= A[i * rate + j];
}
permutations(S, 12 - b, b);
}
}
S[size - 1] ^= 1;
printstate("process associated data:", S);
// process plaintext
for (i = 0; i < t - 1; ++i)
{
for (j = 0; j < rate; ++j)
{
M[i * rate + j] = S[j] ^ c[i * rate + j];
S[j] = c[i * rate + j];
}
permutations(S, 12 - b, b);
}
for (j = 0; j < l; ++j)
{
M[(t - 1) * rate + j] = S[j] ^ c[(t - 1) * rate + j];
}
for (j = 0; j < l; ++j)
{
S[j] = c[(t - 1) * rate + j];
S[l] ^= 0x80;
}
printstate("process plaintext:", S);
// finalization
for (i = 0; i < klen; ++i)
{
S[rate + i] ^= k[i];
}
permutations(S, 12 - a, a);
for (i = 0; i < klen; ++i)
{
S[size - klen + i] ^= k[i];
}
printstate("finalization:", S);
// return -1 if verification fails
for (i = 0; i < klen; ++i)
{
if (c[clen - klen + i] != S[size - klen + i])
{
return -1;
}
}
// return plaintext
*mlen = clen - klen;
for (i = 0; i < *mlen; ++i)
{
m[i] = M[i];
}
return 0;
}
Thanks for the help in advance, I am really clueless right now. 感谢您的事先帮助,我现在真的很笨。
However, in the loop, I was tasked to add a switch case so that it will switch between encryption and decryption.
但是,在循环中,我受命添加一个切换盒,以便它可以在加密和解密之间切换。 But I have no idea what kind of condition to use to differentiate the encryption and decryption.
但是我不知道使用哪种条件来区分加密和解密。
According to your comments, the calls for encryption and decryption are happening inside of CDC_Device_ReceiveByte
and CDC_Device_SendByte
, which means you need to create a state machine for sending and receiving of the bytes. 根据您的评论,对加密和解密的调用发生在
CDC_Device_ReceiveByte
和CDC_Device_SendByte
内部,这意味着您需要创建一个状态机来发送和接收字节。 The condition that you would use for this is the return value of CDC_Device_BytesReceived
. 您要使用的条件是
CDC_Device_BytesReceived
的返回值。
You can create an enum
for the states, and a simple struct
for holding the current state along with any other pertinent information. 您可以为状态创建一个
enum
,并为保存当前状态以及任何其他相关信息创建一个简单的struct
。 You can create a function for the state machine that maps out what to do given the current state. 您可以为状态机创建一个函数,该函数可以映射给定当前状态的操作。 Your
while(1)
loop will simply call the function to ensure the state machine moves along. while(1)
循环将仅调用该函数以确保状态机继续运行。 You might implement that like this: 您可以这样实现:
typedef enum{
IDLE,
DECRYPTING,
ENCRYPTING,
}state_t;
typedef struct{
state_t current_state;
}fsm_t;
fsm_t my_fsm = {0}; //initial state is idle
void myFSM(void){
switch(my_fsm.current_state){
case IDLE:
{
/* Check if data received */
Bytes = CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface);
if(Bytes) my_fsm.current_state = DECRYPTING; //we have data, decrypt it
break;
}
case DECRYPTING:
{
/* Send data back to the host */
ch = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
my_fsm.current_state = ENCRYPTING; // encrypt byte that we are going to send to host
break;
}
case ENCRYPTING:
{
CDC_Device_SendByte(&VirtualSerial_CDC_Interface, ch);
--Bytes;
if(Bytes){
my_fsm.current_state = DECRYPTING; // still have bytes left to decrypt
}
else my_fsm.current_state = IDLE;
break;
}
default:
{
asm("nop"); // whoops
break;
}
}
}
Now your loop is just 现在你的循环就是
while(1){
myFSM();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.