Exemplo n.º 1
0
int pad_aes_decrypt (char *from, int from_len, char *to, int size) {
  if (from_len <= 0 || from_len > size || (from_len & 15)) {
    return -1;
  }
  AES_ige_encrypt ((unsigned char *) from, (unsigned char *) to, from_len, &aes_key, aes_iv, AES_DECRYPT); 
  return from_len;
}
qint32 CryptoUtils::padAESDecrypt (const char *from, qint32 fromLen, char *to, qint32 size) {
    if (fromLen <= 0 || fromLen > size || (fromLen & 15)) {
        return -1;
    }
    AES_ige_encrypt ((const uchar *) from, (uchar *) to, fromLen, &aes_key, aes_iv, AES_DECRYPT);
    return fromLen;
}
Exemplo n.º 3
0
void aesIgeDecrypt(const void *src, void *dst, uint32 len, const void *key, const void *iv) {
	uchar aes_key[32], aes_iv[32];
	memcpy(aes_key, key, 32);
	memcpy(aes_iv, iv, 32);

	AES_KEY aes;
	AES_set_decrypt_key(aes_key, 256, &aes);
	AES_ige_encrypt(static_cast<const uchar*>(src), static_cast<uchar*>(dst), len, &aes, aes_iv, AES_DECRYPT);
}
Exemplo n.º 4
0
int pad_aes_encrypt (char *from, int from_len, char *to, int size) {
  int padded_size = (from_len + 15) & -16;
  assert (from_len > 0 && padded_size <= size);
  if (from_len < padded_size) {
    assert (RAND_pseudo_bytes ((unsigned char *) from + from_len, padded_size - from_len) >= 0);
  }
  AES_ige_encrypt ((unsigned char *) from, (unsigned char *) to, padded_size, &aes_key, aes_iv, AES_ENCRYPT);
  return padded_size;
}
Exemplo n.º 5
0
void aesDecrypt(const void *src, void *dst, uint32 len, void *key, void *iv) {
	uchar aes_key[32], aes_iv[32];
	memcpy(aes_key, key, 32);
	memcpy(aes_iv, iv, 32);

	AES_KEY aes;
	AES_set_decrypt_key(aes_key, 256, &aes);
	AES_ige_encrypt((const uchar*)src, (uchar*)dst, len, &aes, aes_iv, AES_DECRYPT);
}
Exemplo n.º 6
0
QByteArray Utils::aesEncrypt(const QByteArray &data, const SAesKey &key)
{
    QByteArray result = data;

    QByteArray initVector = key.iv;

    AES_KEY enc_key;
    AES_set_encrypt_key((const uchar *) key.key.constData(), key.key.length() * 8, &enc_key);

    AES_ige_encrypt((const uchar *) data.constData(), (uchar *) result.data(), data.length(), &enc_key, (uchar *) initVector.data(), AES_ENCRYPT);
    return result;
}
QByteArray CryptoUtils::decryptFilePart(const QByteArray &partBytes, uchar *key, uchar *iv) {
    qint32 length = partBytes.length();
    uchar *buffer = (uchar *)partBytes.constData();

    ASSERT(!(length & 15));
    AES_KEY aesKey;
    AES_set_decrypt_key(key, 256, &aesKey);
    AES_ige_encrypt(buffer, buffer, length, &aesKey, iv, AES_DECRYPT);
    Utils::secureZeroMemory(&aesKey, 0, sizeof(aesKey));

    return QByteArray::fromRawData((char *)buffer, length);
}
qint32 CryptoUtils::padAESEncrypt (const char *from, qint32 fromLen, char *to, qint32 size) {
    qint32 paddedSize = (fromLen + 15) & -16;
    Q_UNUSED(size);
    Q_ASSERT(fromLen > 0 && paddedSize <= size);
    if (fromLen < paddedSize) {
        qint32 isRandSupported = RAND_pseudo_bytes ((uchar *) from + fromLen, paddedSize - fromLen);
        Q_UNUSED(isRandSupported);
        Q_ASSERT(isRandSupported >= 0);
    }
    AES_ige_encrypt ((uchar *) from, (uchar *) to, paddedSize, &aes_key, aes_iv, AES_ENCRYPT);
    return paddedSize;
}
Exemplo n.º 9
0
vector<unsigned char> AES256_ige_decrypt(vector<unsigned char> encrypted_answer,vector<unsigned char> tmp_aes_iv,vector<unsigned char> tmp_aes_key)
{
    vector<unsigned char> res(encrypted_answer.size(),0);
    AES_KEY key;

//    vector<unsigned char> x_0(tmp_aes_iv.begin(), tmp_aes_iv.begin()+10);
  //  vector<unsigned char> y_0(tmp_aes_iv.begin()+10, tmp_aes_iv.end());
    
   // tmp_aes_iv = mergeVectors(y_0, x_0);
    
    AES_set_decrypt_key(&tmp_aes_key[0], 256, &key);
    
    AES_ige_encrypt(&encrypted_answer[0], &res[0], encrypted_answer.size(), &key, &tmp_aes_iv[0], AES_DECRYPT);
    return res;
}
Exemplo n.º 10
0
static char *encrypt_decrypted_message (struct tgl_secret_chat *E) {
  static int msg_key[4];
  static unsigned char sha1a_buffer[20];
  static unsigned char sha1b_buffer[20];
  static unsigned char sha1c_buffer[20];
  static unsigned char sha1d_buffer[20];
  int x = *(encr_ptr);  
  assert (x >= 0 && !(x & 3));
  sha1 ((void *)encr_ptr, 4 + x, sha1a_buffer);
  memcpy (msg_key, sha1a_buffer + 4, 16);
 
  static unsigned char buf[64];
  memcpy (buf, msg_key, 16);
  memcpy (buf + 16, E->key, 32);
  sha1 (buf, 48, sha1a_buffer);
  
  memcpy (buf, E->key + 8, 16);
  memcpy (buf + 16, msg_key, 16);
  memcpy (buf + 32, E->key + 12, 16);
  sha1 (buf, 48, sha1b_buffer);
  
  memcpy (buf, E->key + 16, 32);
  memcpy (buf + 32, msg_key, 16);
  sha1 (buf, 48, sha1c_buffer);
  
  memcpy (buf, msg_key, 16);
  memcpy (buf + 16, E->key + 24, 32);
  sha1 (buf, 48, sha1d_buffer);

  static unsigned char key[32];
  memcpy (key, sha1a_buffer + 0, 8);
  memcpy (key + 8, sha1b_buffer + 8, 12);
  memcpy (key + 20, sha1c_buffer + 4, 12);

  static unsigned char iv[32];
  memcpy (iv, sha1a_buffer + 8, 12);
  memcpy (iv + 12, sha1b_buffer + 0, 8);
  memcpy (iv + 20, sha1c_buffer + 16, 4);
  memcpy (iv + 24, sha1d_buffer + 0, 8);

  AES_KEY aes_key;
  AES_set_encrypt_key (key, 256, &aes_key);
  AES_ige_encrypt ((void *)encr_ptr, (void *)encr_ptr, 4 * (encr_end - encr_ptr), &aes_key, iv, 1);
  memset (&aes_key, 0, sizeof (aes_key));

  return (void *)msg_key;
}
QByteArray CryptoUtils::encryptFilePart(const QByteArray &partBytes, uchar *key, uchar *iv) {
    qint32 length = partBytes.length();
    uchar *buffer = (uchar *)partBytes.constData();
    // Use an output buffer for not to modify original one.
    // Max size of the output buffer, included padding, will be length + 15
    QScopedArrayPointer<uchar> out(new uchar[length + 15]);
    memcpy(out.data(), buffer, length);

    // in case this part length % 0xF != 0, it means is the last part and we must pad the size to match AES block size (16)
    qint32 paddedSize = length;
    if (length & 15) {
        paddedSize = (length + 15) & -16;
        if (length < paddedSize) {
            RAND_pseudo_bytes(out.data() + length, paddedSize - length);
        }
    }

    AES_KEY aesKey;
    AES_set_encrypt_key(key, 256, &aesKey);
    AES_ige_encrypt(out.data(), out.data(), paddedSize, &aesKey, iv, AES_ENCRYPT);
    Utils::secureZeroMemory(&aesKey, 0, sizeof(aesKey));

    return QByteArray((char *)out.data(), paddedSize);
}
Exemplo n.º 12
0
int main (int argc, char **argv)
{
    unsigned char rkey[16];

    unsigned char rkey2[16];

    AES_KEY key;

    AES_KEY key2;

    unsigned char plaintext[BIG_TEST_SIZE];

    unsigned char ciphertext[BIG_TEST_SIZE];

    unsigned char checktext[BIG_TEST_SIZE];

    unsigned char iv[AES_BLOCK_SIZE * 4];

    unsigned char saved_iv[AES_BLOCK_SIZE * 4];

    int err = 0;

    unsigned int n;

    unsigned matches;

    assert (BIG_TEST_SIZE >= TEST_SIZE);

    RAND_pseudo_bytes (rkey, sizeof rkey);
    RAND_pseudo_bytes (plaintext, sizeof plaintext);
    RAND_pseudo_bytes (iv, sizeof iv);
    memcpy (saved_iv, iv, sizeof saved_iv);

    /* Forward IGE only... */

    /* Straight encrypt/decrypt */
    AES_set_encrypt_key (rkey, 8 * sizeof rkey, &key);
    AES_ige_encrypt (plaintext, ciphertext, TEST_SIZE, &key, iv, AES_ENCRYPT);

    AES_set_decrypt_key (rkey, 8 * sizeof rkey, &key);
    memcpy (iv, saved_iv, sizeof iv);
    AES_ige_encrypt (ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);

    if (memcmp (checktext, plaintext, TEST_SIZE))
    {
        printf ("Encrypt+decrypt doesn't match\n");
        hexdump (stdout, "Plaintext", plaintext, TEST_SIZE);
        hexdump (stdout, "Checktext", checktext, TEST_SIZE);
        ++err;
    }

    /* Now check encrypt chaining works */
    AES_set_encrypt_key (rkey, 8 * sizeof rkey, &key);
    memcpy (iv, saved_iv, sizeof iv);
    AES_ige_encrypt (plaintext, ciphertext, TEST_SIZE / 2, &key, iv, AES_ENCRYPT);
    AES_ige_encrypt (plaintext + TEST_SIZE / 2, ciphertext + TEST_SIZE / 2, TEST_SIZE / 2, &key, iv, AES_ENCRYPT);

    AES_set_decrypt_key (rkey, 8 * sizeof rkey, &key);
    memcpy (iv, saved_iv, sizeof iv);
    AES_ige_encrypt (ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);

    if (memcmp (checktext, plaintext, TEST_SIZE))
    {
        printf ("Chained encrypt+decrypt doesn't match\n");
        hexdump (stdout, "Plaintext", plaintext, TEST_SIZE);
        hexdump (stdout, "Checktext", checktext, TEST_SIZE);
        ++err;
    }

    /* And check decrypt chaining */
    AES_set_encrypt_key (rkey, 8 * sizeof rkey, &key);
    memcpy (iv, saved_iv, sizeof iv);
    AES_ige_encrypt (plaintext, ciphertext, TEST_SIZE / 2, &key, iv, AES_ENCRYPT);
    AES_ige_encrypt (plaintext + TEST_SIZE / 2, ciphertext + TEST_SIZE / 2, TEST_SIZE / 2, &key, iv, AES_ENCRYPT);

    AES_set_decrypt_key (rkey, 8 * sizeof rkey, &key);
    memcpy (iv, saved_iv, sizeof iv);
    AES_ige_encrypt (ciphertext, checktext, TEST_SIZE / 2, &key, iv, AES_DECRYPT);
    AES_ige_encrypt (ciphertext + TEST_SIZE / 2, checktext + TEST_SIZE / 2, TEST_SIZE / 2, &key, iv, AES_DECRYPT);

    if (memcmp (checktext, plaintext, TEST_SIZE))
    {
        printf ("Chained encrypt+chained decrypt doesn't match\n");
        hexdump (stdout, "Plaintext", plaintext, TEST_SIZE);
        hexdump (stdout, "Checktext", checktext, TEST_SIZE);
        ++err;
    }

    /* make sure garble extends forwards only */
    AES_set_encrypt_key (rkey, 8 * sizeof rkey, &key);
    memcpy (iv, saved_iv, sizeof iv);
    AES_ige_encrypt (plaintext, ciphertext, sizeof plaintext, &key, iv, AES_ENCRYPT);

    /* corrupt halfway through */
    ++ciphertext[sizeof ciphertext / 2];
    AES_set_decrypt_key (rkey, 8 * sizeof rkey, &key);
    memcpy (iv, saved_iv, sizeof iv);
    AES_ige_encrypt (ciphertext, checktext, sizeof checktext, &key, iv, AES_DECRYPT);

    matches = 0;
    for (n = 0; n < sizeof checktext; ++n)
        if (checktext[n] == plaintext[n])
            ++matches;

    if (matches > sizeof checktext / 2 + sizeof checktext / 100)
    {
        printf ("More than 51%% matches after garbling\n");
        ++err;
    }

    if (matches < sizeof checktext / 2)
    {
        printf ("Garble extends backwards!\n");
        ++err;
    }

    /* Bi-directional IGE */

    /* Note that we don't have to recover the IV, because chaining isn't */
    /* possible with biIGE, so the IV is not updated. */

    RAND_pseudo_bytes (rkey2, sizeof rkey2);

    /* Straight encrypt/decrypt */
    AES_set_encrypt_key (rkey, 8 * sizeof rkey, &key);
    AES_set_encrypt_key (rkey2, 8 * sizeof rkey2, &key2);
    AES_bi_ige_encrypt (plaintext, ciphertext, TEST_SIZE, &key, &key2, iv, AES_ENCRYPT);

    AES_set_decrypt_key (rkey, 8 * sizeof rkey, &key);
    AES_set_decrypt_key (rkey2, 8 * sizeof rkey2, &key2);
    AES_bi_ige_encrypt (ciphertext, checktext, TEST_SIZE, &key, &key2, iv, AES_DECRYPT);

    if (memcmp (checktext, plaintext, TEST_SIZE))
    {
        printf ("Encrypt+decrypt doesn't match\n");
        hexdump (stdout, "Plaintext", plaintext, TEST_SIZE);
        hexdump (stdout, "Checktext", checktext, TEST_SIZE);
        ++err;
    }

    /* make sure garble extends both ways */
    AES_set_encrypt_key (rkey, 8 * sizeof rkey, &key);
    AES_set_encrypt_key (rkey2, 8 * sizeof rkey2, &key2);
    AES_ige_encrypt (plaintext, ciphertext, sizeof plaintext, &key, iv, AES_ENCRYPT);

    /* corrupt halfway through */
    ++ciphertext[sizeof ciphertext / 2];
    AES_set_decrypt_key (rkey, 8 * sizeof rkey, &key);
    AES_set_decrypt_key (rkey2, 8 * sizeof rkey2, &key2);
    AES_ige_encrypt (ciphertext, checktext, sizeof checktext, &key, iv, AES_DECRYPT);

    matches = 0;
    for (n = 0; n < sizeof checktext; ++n)
        if (checktext[n] == plaintext[n])
            ++matches;

    if (matches > sizeof checktext / 100)
    {
        printf ("More than 1%% matches after bidirectional garbling\n");
        ++err;
    }

    /* make sure garble extends both ways (2) */
    AES_set_encrypt_key (rkey, 8 * sizeof rkey, &key);
    AES_set_encrypt_key (rkey2, 8 * sizeof rkey2, &key2);
    AES_ige_encrypt (plaintext, ciphertext, sizeof plaintext, &key, iv, AES_ENCRYPT);

    /* corrupt right at the end */
    ++ciphertext[sizeof ciphertext - 1];
    AES_set_decrypt_key (rkey, 8 * sizeof rkey, &key);
    AES_set_decrypt_key (rkey2, 8 * sizeof rkey2, &key2);
    AES_ige_encrypt (ciphertext, checktext, sizeof checktext, &key, iv, AES_DECRYPT);

    matches = 0;
    for (n = 0; n < sizeof checktext; ++n)
        if (checktext[n] == plaintext[n])
            ++matches;

    if (matches > sizeof checktext / 100)
    {
        printf ("More than 1%% matches after bidirectional garbling (2)\n");
        ++err;
    }

    /* make sure garble extends both ways (3) */
    AES_set_encrypt_key (rkey, 8 * sizeof rkey, &key);
    AES_set_encrypt_key (rkey2, 8 * sizeof rkey2, &key2);
    AES_ige_encrypt (plaintext, ciphertext, sizeof plaintext, &key, iv, AES_ENCRYPT);

    /* corrupt right at the start */
    ++ciphertext[0];
    AES_set_decrypt_key (rkey, 8 * sizeof rkey, &key);
    AES_set_decrypt_key (rkey2, 8 * sizeof rkey2, &key2);
    AES_ige_encrypt (ciphertext, checktext, sizeof checktext, &key, iv, AES_DECRYPT);

    matches = 0;
    for (n = 0; n < sizeof checktext; ++n)
        if (checktext[n] == plaintext[n])
            ++matches;

    if (matches > sizeof checktext / 100)
    {
        printf ("More than 1%% matches after bidirectional garbling (3)\n");
        ++err;
    }

    err += run_test_vectors ();

    return err;
}
Exemplo n.º 13
0
static int run_test_vectors (void)
{
    unsigned int n;

    int errs = 0;

    for (n = 0; n < sizeof (ige_test_vectors) / sizeof (ige_test_vectors[0]); ++n)
    {
        const struct ige_test *const v = &ige_test_vectors[n];

        AES_KEY key;

        unsigned char buf[MAX_VECTOR_SIZE];

        unsigned char iv[AES_BLOCK_SIZE * 2];

        assert (v->length <= MAX_VECTOR_SIZE);

        if (v->encrypt == AES_ENCRYPT)
            AES_set_encrypt_key (v->key, 8 * sizeof v->key, &key);
        else
            AES_set_decrypt_key (v->key, 8 * sizeof v->key, &key);
        memcpy (iv, v->iv, sizeof iv);
        AES_ige_encrypt (v->in, buf, v->length, &key, iv, v->encrypt);

        if (memcmp (v->out, buf, v->length))
        {
            printf ("IGE test vector %d failed\n", n);
            hexdump (stdout, "key", v->key, sizeof v->key);
            hexdump (stdout, "iv", v->iv, sizeof v->iv);
            hexdump (stdout, "in", v->in, v->length);
            hexdump (stdout, "expected", v->out, v->length);
            hexdump (stdout, "got", buf, v->length);

            ++errs;
        }

        /* try with in == out */
        memcpy (iv, v->iv, sizeof iv);
        memcpy (buf, v->in, v->length);
        AES_ige_encrypt (buf, buf, v->length, &key, iv, v->encrypt);

        if (memcmp (v->out, buf, v->length))
        {
            printf ("IGE test vector %d failed (with in == out)\n", n);
            hexdump (stdout, "key", v->key, sizeof v->key);
            hexdump (stdout, "iv", v->iv, sizeof v->iv);
            hexdump (stdout, "in", v->in, v->length);
            hexdump (stdout, "expected", v->out, v->length);
            hexdump (stdout, "got", buf, v->length);

            ++errs;
        }
    }

    for (n = 0; n < sizeof (bi_ige_test_vectors) / sizeof (bi_ige_test_vectors[0]); ++n)
    {
        const struct bi_ige_test *const v = &bi_ige_test_vectors[n];

        AES_KEY key1;

        AES_KEY key2;

        unsigned char buf[MAX_VECTOR_SIZE];

        assert (v->length <= MAX_VECTOR_SIZE);

        if (v->encrypt == AES_ENCRYPT)
        {
            AES_set_encrypt_key (v->key1, 8 * v->keysize, &key1);
            AES_set_encrypt_key (v->key2, 8 * v->keysize, &key2);
        }
        else
        {
            AES_set_decrypt_key (v->key1, 8 * v->keysize, &key1);
            AES_set_decrypt_key (v->key2, 8 * v->keysize, &key2);
        }

        AES_bi_ige_encrypt (v->in, buf, v->length, &key1, &key2, v->iv, v->encrypt);

        if (memcmp (v->out, buf, v->length))
        {
            printf ("Bidirectional IGE test vector %d failed\n", n);
            hexdump (stdout, "key 1", v->key1, sizeof v->key1);
            hexdump (stdout, "key 2", v->key2, sizeof v->key2);
            hexdump (stdout, "iv", v->iv, sizeof v->iv);
            hexdump (stdout, "in", v->in, v->length);
            hexdump (stdout, "expected", v->out, v->length);
            hexdump (stdout, "got", buf, v->length);

            ++errs;
        }
    }

    return errs;
}
Exemplo n.º 14
0
QByteArray Decrypter::decryptEncryptedMessage() {

    qint32 *sharedKey = (qint32*)mSecretChat->sharedKey();
    qint32 *msgKey = m_inPtr;
    qint32 bufferLength = 4 * (m_inEnd - m_inPtr);

    fetchInts(4);
    static uchar sha1a_buffer[20];
    static uchar sha1b_buffer[20];
    static uchar sha1c_buffer[20];
    static uchar sha1d_buffer[20];
    static uchar key[32];
    static uchar iv[32];

    static uchar buf[64];
    memcpy(buf, msgKey, 16);
    memcpy(buf + 16, sharedKey, 32);
    SHA1(buf, 48, sha1a_buffer);

    memcpy(buf, sharedKey + 8, 16);
    memcpy(buf + 16, msgKey, 16);
    memcpy(buf + 32, sharedKey + 12, 16);
    SHA1(buf, 48, sha1b_buffer);

    memcpy(buf, sharedKey + 16, 32);
    memcpy(buf + 32, msgKey, 16);
    SHA1(buf, 48, sha1c_buffer);

    memcpy(buf, msgKey, 16);
    memcpy(buf + 16, sharedKey + 24, 32);
    SHA1(buf, 48, sha1d_buffer);

    memcpy(key, sha1a_buffer + 0, 8);
    memcpy(key + 8, sha1b_buffer + 8, 12);
    memcpy(key + 20, sha1c_buffer + 4, 12);

    memcpy(iv, sha1a_buffer + 8, 12);
    memcpy(iv + 12, sha1b_buffer + 0, 8);
    memcpy(iv + 20, sha1c_buffer + 16, 4);
    memcpy(iv + 24, sha1d_buffer + 0, 8);

    AES_KEY aesKey;
    AES_set_decrypt_key(key, 256, &aesKey);
    AES_ige_encrypt((uchar *)m_inPtr, (uchar *)m_inPtr, bufferLength, &aesKey, iv, 0);
    Utils::secureZeroMemory(&aesKey, 0, sizeof(aesKey));

    qint32 x = prefetchInt();
    if (x < 0 || (x & 3)) {
        qCWarning(TG_SECRET_DECRYPTER) << "Not valid value for internal data length" << x;
        return QByteArray();
    }
    ASSERT(x >= 0 && !(x & 3));
    SHA1((uchar *)m_inPtr, 4 + x, sha1a_buffer);

    if (memcmp(sha1a_buffer + 4, msgKey, 16)) {
        qCWarning(TG_SECRET_DECRYPTER) << "SHA1 mismatch";
        return QByteArray();
    }
    qCDebug(TG_SECRET_DECRYPTER) << "SHA1 checked and valid";

    qint32 plainDataLength = fetchInt();
    m_inEnd = m_inPtr + plainDataLength;
    qCDebug(TG_SECRET_DECRYPTER) << "decrypted data length" << plainDataLength;

    QByteArray plainData((char *)m_inPtr, plainDataLength);
    return plainData;
}