1

I'm using Crypto++ to encrypt string with AES. Ok it works fine, but now I want to create a function that return a byte value that is the key.

byte AESBest::gen_key()
{
    AutoSeededRandomPool prng;

    // warning: address of local variable ‘key’ returned [enabled by default]
    byte key[AES::MAX_KEYLENGTH];

    prng.GenerateBlock(key, sizeof(key));

    //Error: invalid conversion from ‘byte {aka unsigned char}’ to ‘const byte* {aka const unsigned char*}’ [-fpermissive] }
    return key;
}

Well. I cannot return the key because something is not clear. When I set byte key[AES::MAX_KEYLENGTH] eclipse show me the warning that seems to be returned. But when in the end return key, there is a strange error about the invalid conversion.

Why happen this?

How can I solve this problem?


EDIT: Well. Now I have these 2 function. But the first works good, returning the 64 chars of the aes key. (gen_all)

The second - I dunno why - return just 4! Why? (gen_part)

string AESBest::gen_all()
{
    AutoSeededRandomPool prng;
    byte key[AES::MAX_KEYLENGTH];
    prng.GenerateBlock(key, sizeof(key));

    string encoded;
    encoded.clear();
    StringSource(key, sizeof(key), true,
        new HexEncoder(
            new StringSink(encoded)
        )
    );
    return encoded;
}

And:

string AESBest::gen_part()
{
    AutoSeededRandomPool prng;
    std::vector<byte> key(AES::MAX_KEYLENGTH);
    prng.GenerateBlock(key.data(), key.size());

    string encoded;
    encoded.clear();
    StringSource(key.data(), sizeof(key.size()), true,
        new HexEncoder(
            new StringSink(encoded)
        )
    );

    return encoded;
}

Where is the bug in the second one?

EDIT: nevermind! The bug was in sizeof, so key.size() NO sizeof(key.size())

jww
  • 97,681
  • 90
  • 411
  • 885
  • 6
    You need [a good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). And you need it rather urgently. – sbi Oct 31 '11 at 13:23
  • You need to read better my question and know about Crypto++, because the type byte is native for this library. –  Oct 31 '11 at 13:26
  • @user840718 `:` I don't directly see any reason to assume that @sbi meant to imply that his remark was related to the appearance of any specific keyword (like, perhaps, `byte`) – sehe Oct 31 '11 at 13:28
  • 2
    @user840718: I have read your question. You attempt to return a local variable, that variable is an array where the function is defined to return a byte, you typed one of the two compiler messages the wrong way around, and you are unable to interpret those messages despite the fact that both plainly say what the problems are. I have seen many a student making small errors like this when I taught C++. This has nothing to do with Crypto++, you just seem to not know enough of C++ to properly use this API. Hence my comment. – sbi Oct 31 '11 at 13:40
  • 1
    Ok should me by bad. Thank you. –  Oct 31 '11 at 13:46
  • You could also declare them as a `SecByteBlock`. It has a copy constructor, so it can be returned from a function. That avoids the `byte*` and `byte[]` issues. It also side steps the hack of using a `string` as a container. – jww Feb 16 '15 at 20:55

2 Answers2

3

You cannot return raw arrays in C++ (nor can you pass them as function arguments by value). Instead, use a std::vector<byte>:

std::vector<byte> key(AES::MAX_KEYLENGTH);
prng.GenerateBlock(key.data(), key.size());
return key;

You'll have to modify the function return type accordingly. Use key.data() or &key[0] to get a pointer to the underlying data array.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Ok but then I need to enc and dec the string by the key. I need to use e.SetKey(key, sizeof(key)); and to do that, I need that key must be a byte. Is it possible? –  Oct 31 '11 at 13:28
  • You got it wrong; you need `key` to be a **pointer** to `byte`. As I just said, say `SetKey(key.data(), key.size())` to get at the data pointer and array size. – Kerrek SB Oct 31 '11 at 13:29
  • I have edited my question about your code. Can you take a fast look? Thank you. –  Nov 01 '11 at 19:45
  • 1
    Not `sizeof(key.size())`. Just `key.size()`. Please *really* pick up a good book -- you'll feel all the more powerful for it afterwards! – Kerrek SB Nov 01 '11 at 20:04
2
  • Warning reason: You are returning a pointer to a local array. It's wrong because the local variable will deleted after exiting the function.

  • Error reason: Compiler expected you return a byte value, but you are returning a pointer.

Try this:

void AESBest::gen_key(byte *key, int size)
{
  AutoSeededRandomPool prng;
  prng.GenerateBlock(key, size);
}

and call it like below:

byte key[AES::MAX_KEYLENGTH];
gen_key(key, AES::MAX_KEYLENGTH);
masoud
  • 55,379
  • 16
  • 141
  • 208