0

I am using the library Crypto++ for encrypting/decrypting data. The official page is https://www.cryptopp.com. I am following this tutorial. It shows how to use block cipher with Crypto++. You can see this part with find keyword "using block cipher".

I can run the demo smoothly. They encrypt the data using the key, then decrypt data using the same key. I want to split the code to an encrypt() and a decrypt() function. You can see my encrypt() function below.
The include part:

#include "E:\Working\Improve\CPP\cryptopp565\osrng.h"
using CryptoPP::AutoSeededRandomPool;

#include <iostream>
using std::cout;
using std::cerr;
using std::endl;

#include <string>
using std::string;

#include <cstdlib>
using std::exit;

#include "E:\Working\Improve\CPP\cryptopp565\cryptlib.h"
using CryptoPP::Exception;

#include "E:\Working\Improve\CPP\cryptopp565\hex.h"
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;

#include "E:\Working\Improve\CPP\cryptopp565\filters.h"
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::StreamTransformationFilter;

#include "E:\Working\Improve\CPP\cryptopp565\aes.h"
using CryptoPP::AES;

#include "E:\Working\Improve\CPP\cryptopp565\ccm.h"
#include "E:\Working\Improve\CPP\cryptopp565\modes.h"
using CryptoPP::ECB_Mode;
#include <fstream>

#include "assert.h"


Code body:

// My encrypt function
void encrypt(byte cbCipherText[AES::BLOCKSIZE], byte *plainText,
             byte key[AES::DEFAULT_KEYLENGTH], int sizeKey) {
  int size = sizeof(key);
  ECB_Mode<AES>::Encryption Encryptor(key, sizeKey);

  Encryptor.ProcessData(cbCipherText, plainText, sizeof(plainText));
}

void main() {
  byte PlainText[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o',
                      'r', 'l', 'd', 0x0, 0x0, 0x0, 0x0, 0x0};

  byte key[AES::DEFAULT_KEYLENGTH];
  ::memset(key, 0x01, AES::DEFAULT_KEYLENGTH);

  // Encrypt data
  int size = sizeof(key);
  int default = AES::DEFAULT_KEYLENGTH;
  ECB_Mode<AES>::Encryption Encryptor(key, size);

  // Next three lines are tutorial's code for encrypt
  byte cbCipherText[AES::BLOCKSIZE];
  Encryptor.ProcessData(cbCipherText, PlainText, sizeof(PlainText));
  ECB_Mode<AES>::Decryption Decryptor(key, sizeof(key));

  // Next two lines are my code to call the encrypt() function, I "cloned" the
  // code
  // from above three line!. Comment out them we will have the code like the
  // demo.

  byte myCipherText[AES::BLOCKSIZE];
  encrypt(myCipherText, PlainText, key, size);

  // Decrypt
  byte cbRecoveredText[AES::BLOCKSIZE];

  Decryptor.ProcessData(cbRecoveredText, cbCipherText, sizeof(cbCipherText));

  //    std::string PlainText ="Voltaire said, Prejudices are what fools use for
  //reason";

  cout << endl << "Recovered text: " << cbRecoveredText << endl;
  getchar();
}

The key was created with value \x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1. In the demo code, the key's value is never changed and its size is always 16. When I call my encrypt() function and pass key to it, the key size (sizeof(key)) is 16 when it was created, but after passed to function, the length is always 4 (!). And the key value is x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1ĂŒĂŒĂŒĂŒĂŒĂŒĂŒĂŒHello World (!!!). Therefore, my code always gets the error "AES: 4 is not valid key length" if I jump into the function. I don't understand why this happened and how to fix it. Any help would be appreciated!

2
  • You claim that you get "AES: 4 is not valid key length" error. However, you never pass size (calculated as sizeof(key)) anywhere in your encrypt function. How did you manage to get that error then? Commented Nov 11, 2016 at 7:46
  • Please, change the first #include. It stops me from continuing reading. Commented Nov 11, 2016 at 15:05

2 Answers 2

3

Top-level arrays in function prototypes are nothing more than hints to the programmer, if that.

The following prototypes are exactly the same

void foo(int x[20]);
void foo(int x[]);
void foo(int* x);

In other words, with sizeof(x), you're measuring the size of a pointer.

You can avoid this using std::array instead (but you'll probably want to avoid passing it by value).

If you absolutely need to work with a C-like API, you need to pass the number of elements in the array as a separate parameter. There's no standard way of getting it from a pointer.

Sign up to request clarification or add additional context in comments.

9 Comments

Because I am using ProcessData() function from the API, so I have to pass an byte* or byte[] to it Encryptor.ProcessData(cbCipherText, plainText, sizeof(plainText)). May be I can't using std::array in this case :\
@Andiana why do you think ProcessData requires you to pass size as another parameter? Why they cannot just call sizeof(data)?
@Andiana then you need to add another parameter to your function.
@Andiana sizeKey seems to be size of the key. Not that of plainText. You need to pass the size of each array you're passing
@krzaq: OMG! you saved my lifed! I add the size of plainText as paramter and its worked.
|
1

Thank for @krzaq comment. I fixed my problem. Problem is: key's size and plainText's sizes must be passed as a number to function. You cannot retrieve size by use sizeof() after passing the pointer into function.

I fixed the code:

// My encrypt function
void encrypt(byte cbCipherText[AES::BLOCKSIZE], byte *plainText,
             byte key[AES::DEFAULT_KEYLENGTH], int sizeKey, int sizeKey) {
  int size = sizeof(key);
  ECB_Mode<AES>::Encryption Encryptor(key, sizeKey);

  Encryptor.ProcessData(cbCipherText, plainText, textKey);
}
...
void main() {
 ...
  int sizeText = sizeOf(plainText);
  encrypt(myCipherText, PlainText, key, sizeKey, sizeText);

...
  }

And now its worked!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.