Как включить оператор переключения для этого кода шифрования / дешифрования? - PullRequest
1 голос
/ 13 мая 2019

Я только начал использовать микроконтроллер, и я должен внедрить в него шифрование / дешифрование. Извините за супер длинный пост.

Это скрипт на 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, так как число байт будет больше 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;
}

Однако в цикле мне было поручено добавить регистр коммутатора, чтобы он переключался между шифрованием и дешифрованием. Но я понятия не имею, какое условие использовать, чтобы различать шифрование и дешифрование.

Это код для шифрования.

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

Спасибо за помощь заранее, сейчас я действительно не знаю.

1 Ответ

0 голосов
/ 14 мая 2019

Однако в цикле мне было поручено добавить регистр коммутатора, чтобы он переключался между шифрованием и дешифрованием.Но я понятия не имею, какое условие использовать для дифференциации шифрования и дешифрования.

Согласно вашим комментариям, вызовы для шифрования и дешифрования происходят внутри CDC_Device_ReceiveByte и CDC_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();

}
...