【问题标题】:How do I include a switch-case statement for this encryption/decryption code?如何包含此加密/解密代码的 switch-case 语句?
【发布时间】:2019-05-13 11:08:38
【问题描述】:

我刚开始使用微控制器,我必须在其中实现加密/解密。抱歉,帖子太长了。

这是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)

这是 main.c 文件。我知道 CDC_Device_BytesReceived 将接收来自 python 脚本的输入。如果有输入,它将运行 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;
}

但是,在循环中,我的任务是添加一个 switch case,以便它在加密和解密之间切换。但我不知道用什么样的条件来区分加密和解密。

这是加密代码。

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

以及解密代码

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

提前谢谢你的帮助,我现在真的很无能为力。

【问题讨论】:

  • crypto_aead_encryptcrypto_aead_decrypt 的呼叫在哪里?我会假设它们发生在 CDC_Device_ReceiveByteCDC_Device_SendByte...
  • @bigwillydos yesm 他们正在里面发生,但我需要有一个 switch case 语句,我不知道如何将它放入 switch case,因为我不能让任何用户定义输入,也不能我对任何输入进行硬编码。

标签: c switch-statement microcontroller


【解决方案1】:

但是,在循环中,我的任务是添加一个开关盒,以便它 将在加密和解密之间切换。但我不知道是什么 用于区分加密和 解密。

根据您的 cmets,加密和解密调用发生在 CDC_Device_ReceiveByteCDC_Device_SendByte 内部,这意味着您需要创建一个状态机来发送和接收字节。您将用于此的条件是 CDC_Device_BytesReceived 的返回值。

您可以为状态创建一个enum,并为保存当前状态以及任何其他相关信息创建一个简单的struct。您可以为状态机创建一个函数,该函数映射出在给定当前状态的情况下要做什么。您的while(1) 循环将简单地调用该函数以确保状态机继续运行。你可以这样实现:

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;

        }

    }

}

现在你的循环只是

while(1){

    myFSM();

}

【讨论】:

  • 在这种情况下,如何将我的函数 int crypto_aead_decrypt() 和 int crypto_aead_encrypt() 包含在其中?
猜你喜欢
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 1970-01-01
相关资源
最近更新 更多