C ++ / Arduino: strcpy (), strncpy () и memcpy () на неподписанных символах не работают - PullRequest
0 голосов
/ 28 апреля 2018

Я пытаюсь реализовать AES128 и 256 на Arduino (Adafruit Feather M0, для любых других людей, использующих процессоры SAMD21!). Шифрование и дешифрование работает , но я не могу «сохранить» зашифрованное значение. Я полагаю, что пример передает указатель для массива char в void encrypt(), но при использовании strcpy, strncpy или memcpy для копирования значения из локального массива char в значение, указанное в моем loop(), значение никогда не копируется.

Обратите внимание, что зависание происходит только в методе void encrypt(), и мне интересно, связано ли это со строкой encode_base64, в которой пример кода приводит данные как unsigned char*. Я смог успешно использовать strcpy, strncpy и memcpy в void decrypt(), поэтому я могу думать только о том, что это тип unsigned char.

Хотя в соответствии с этот символ в конечном итоге рассматривается как неподписанный символ в стандартных библиотеках, и я предполагаю, что функция strcpy является частью стандартной библиотеки строк, а не чем-то особенным для Arduino.

Я очень плохо знаком с C / C ++ и далеко не эксперт, я не совсем уверен, как обойти эту проблему, поэтому я надеюсь, что кто-то может указать мне правильное направление.

Код (я включил ссылки на libs вверху для каждого #include)

#include <Crypto.h>   // https://github.com/intrbiz/arduino-crypto
#include <base64.hpp> // https://github.com/Densaugeo/base64_arduino


#define BLOCK_SIZE 16

uint8_t key[BLOCK_SIZE] = { 0x1C,0x3E,0x4B,0xAF,0x13,0x4A,0x89,0xC3,0xF3,0x87,0x4F,0xBC,0xD7,0xF3, 0x31, 0x31 };
uint8_t iv[BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
char plain_text[] = "1234567890ABCDEF1234567890ABCDEF";

void bufferSize(char* text, int &length)
{
    int i = strlen(text);
    int buf = round(i / BLOCK_SIZE) * BLOCK_SIZE;
    length = (buf <= i) ? buf + BLOCK_SIZE : length = buf;
}

void encrypt(char* plain_text, char* output, int length)
{
    byte enciphered[length];
    // RNG::fill(iv, BLOCK_SIZE); // Using fixed test iv
    AES aesEncryptor(key, iv, AES::AES_MODE_128, AES::CIPHER_ENCRYPT);
    aesEncryptor.process((uint8_t*)plain_text, enciphered, length);
    int encrypted_size = sizeof(enciphered);

    char encoded[encrypted_size];
    encode_base64(enciphered, encrypted_size, (unsigned char*)encoded);

    Serial.print("void encrypt :: Encrypted: ");
    Serial.println(encoded);

    // strcpy(output, encoded); //- Hangs
    // strncpy(output, encoded, strlen((char*)encoded)); - Hangs
    // memcpy(output, encoded, strlen((char*)encoded)); - Hangs
}

void decrypt(char* enciphered, char* output, int length)
{
    length = length + 1; //re-adjust

    char decoded[length];
    decode_base64((unsigned char*)enciphered, (unsigned char*)decoded);
    bufferSize(enciphered, length);
    byte deciphered[length];
    AES aesDecryptor(key, iv, AES::AES_MODE_128, AES::CIPHER_DECRYPT);
    aesDecryptor.process((uint8_t*)decoded, deciphered, length);

    Serial.print("void decrypt :: Decrypted: ");
    Serial.println((char*)deciphered);

    strcpy(output, (char*)deciphered);
    // strncpy(output, (char*)deciphered, strlen((char*)deciphered));
    // memcpy(output, (char*)deciphered, strlen((char*)deciphered));
}

void setup() {
    Serial.begin(115200);
    while (!Serial) {
      ; //wait
    }

    Serial.println("AES128-CBC Test :: Starting...");
    Serial.print("Plaintext input "); Serial.println(plain_text);
}

void loop() {

  Serial.println(" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = \n");

  // encrypt
  int length = 0;
  bufferSize(plain_text, length);
  // Serial.print("Buffer length: ");
  // Serial.println(length);

  char encrypted[128];
  encrypt(plain_text, encrypted, length);

  // Serial.println("");
  Serial.print("RETURNED Encrypted Value: ");
  Serial.println(encrypted);


  // decrypt
  length = 128; // WAS strlen(encrypted);
  char decrypted[length];
  char testEncryptedPayload[] = "pJUX0k/h/63Jywlyvn7vTMa9NdJF9Mz6JOB1T1gDMq+0NUkNycBR780kMvCYILGP"; // Added for testing purposes

  decrypt(testEncryptedPayload, decrypted, length);

  Serial.print("RETURNED Decrypted Value: ");
  Serial.println(decrypted);

  delay(5000);
}

/*
EXAMPLE FROM DOCS => loop()

void loop() {
  char plain_text[] = "1234567890ABCDEF1234567890ABCDEF";

  // encrypt
  int length = 0;
  bufferSize(plain_text, length);
  char encrypted[length];
  encrypt(plain_text, encrypted, length);

  Serial.println("");
  Serial.print("Encrypted: ");
  Serial.println(encrypted);

  // decrypt
  length = strlen(encrypted);
  char decrypted[length];
  decrypt(encrypted, decrypted, length);

  Serial.print("Decrypted: ");
  Serial.println(decrypted);

  delay(5000);
}


*/

Пример вывода:

AES128-CBC Test :: Starting...
Plaintext input 1234567890ABCDEF1234567890ABCDEF
 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

void encrypt :: Encrypted: pJUX0k/h/63Jywlyvn7vTMa9NdJF9Mz6JOB1T1gDMq/eQVoPjf/UYv+9SuzV8LQa
RETURNED Encrypted Value: L
void decrypt :: Decrypted: 1234567890ABCDEF1234567890ABCDEF
RETURNED Decrypted Value: 1234567890ABCDEF1234567890ABCDEF
 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

1 Ответ

0 голосов
/ 10 июля 2019

Я не запускал код, но в целом "зависания" с M0 были связаны с памятью в моем опыте.

Эти две строки:

// strncpy(output, encoded, strlen((char*)encoded)); - Hangs
// memcpy(output, encoded, strlen((char*)encoded)); - Hangs

Возможно, что на самом деле терпит неудачу, это strlen. Может быть, encoded не не NULL прекращено? Можете ли вы попробовать с реальной длиной? (например, memcpy(output, encoded, encoded_length);)

...