简体   繁体   English

如何包含此加密/解密代码的switch-case语句?

[英]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_ReceiveByteCDC_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM