Ejemplo n.º 1
0
/* check mcapi des3 */
static int check_des3(void)
{
    CRYPT_TDES_CTX mcDes3;
    Des3           defDes3;
    int            ret;
    byte           out1[TDES_TEST_SIZE];
    byte           out2[TDES_TEST_SIZE];

    strncpy((char*)key, "1234567890abcdefghijklmn", 24);
    strncpy((char*)iv,  "12345678", 8);

    /* cbc encrypt */
    ret = CRYPT_TDES_KeySet(&mcDes3, key, iv, CRYPT_TDES_ENCRYPTION);
    if (ret != 0) {
        printf("mcapi tdes key set failed\n");
        return -1;
    }
    Des3_SetKey(&defDes3, key, iv, DES_ENCRYPTION);

    ret = CRYPT_TDES_CBC_Encrypt(&mcDes3, out1, ourData, TDES_TEST_SIZE);
    if (ret != 0) {
        printf("mcapi tdes cbc encrypt failed\n");
        return -1;
    }
    Des3_CbcEncrypt(&defDes3, out2, ourData, TDES_TEST_SIZE);

    if (memcmp(out1, out2, TDES_TEST_SIZE) != 0) {
        printf("mcapi tdes cbc encrypt cmp failed\n");
        return -1;
    }

    /* cbc decrypt */
    ret = CRYPT_TDES_KeySet(&mcDes3, key, iv, CRYPT_TDES_DECRYPTION);
    if (ret != 0) {
        printf("mcapi tdes key set failed\n");
        return -1;
    }
    Des3_SetKey(&defDes3, key, iv, DES_DECRYPTION);

    ret = CRYPT_TDES_CBC_Decrypt(&mcDes3, out2, out1, TDES_TEST_SIZE);
    if (ret != 0) {
        printf("mcapi tdes cbc decrypt failed\n");
        return -1;
    }
    Des3_CbcDecrypt(&defDes3, out1, out1, TDES_TEST_SIZE);

    if (memcmp(out1, out2, TDES_TEST_SIZE) != 0) {
        printf("mcapi tdes cbc decrypt cmp failed\n");
        return -1;
    }

    if (memcmp(out1, ourData, TDES_TEST_SIZE) != 0) {
        printf("mcapi tdes cbc decrypt orig cmp failed\n");
        return -1;
    }

    printf("tdes        mcapi test passed\n");

    return 0;
}
Ejemplo n.º 2
0
int des3_test()
{
    const byte vector[] = { /* "Now is the time for all " w/o trailing 0 */
        0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
        0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
        0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20
    };

    byte plain[24];
    byte cipher[24];

    Des3 enc;
    Des3 dec;

    const byte key3[] = 
    {
        0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
        0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
        0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
    };
    const byte iv3[] = 
    {
        0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,
        0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
        0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81
        
    };

    const byte verify3[] = 
    {
        0x43,0xa0,0x29,0x7e,0xd1,0x84,0xf8,0x0e,
        0x89,0x64,0x84,0x32,0x12,0xd5,0x08,0x98,
        0x18,0x94,0x15,0x74,0x87,0x12,0x7d,0xb0
    };


    Des3_SetKey(&enc, key3, iv3, DES_ENCRYPTION);
    Des3_CbcEncrypt(&enc, cipher, vector, sizeof(vector));
    Des3_SetKey(&dec, key3, iv3, DES_DECRYPTION);
    Des3_CbcDecrypt(&dec, plain, cipher, sizeof(cipher));

    if (memcmp(plain, vector, sizeof(plain)))
        return -33;

    if (memcmp(cipher, verify3, sizeof(cipher)))
        return -34;

    return 0;
}
Ejemplo n.º 3
0
void bench_des(void)
{
    Des3   enc;
    double start, total, persec;
    int    i, ret;

#ifdef HAVE_CAVIUM
    if (Des3_InitCavium(&enc, CAVIUM_DEV_ID) != 0)
        printf("des3 init cavium failed\n");
#endif
    ret = Des3_SetKey(&enc, key, iv, DES_ENCRYPTION);
    if (ret != 0) {
        printf("Des3_SetKey failed, ret = %d\n", ret);
        return;
    }
    start = current_time(1);

    for(i = 0; i < numBlocks; i++)
        Des3_CbcEncrypt(&enc, plain, cipher, sizeof(plain));

    total = current_time(0) - start;

    persec = 1 / total * numBlocks;
#ifdef BENCH_EMBEDDED
    /* since using kB, convert to MB/s */
    persec = persec / 1024;
#endif

    printf("3DES     %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
                                              blockType, total, persec);
#ifdef HAVE_CAVIUM
    Des3_FreeCavium(&enc);
#endif
}
Ejemplo n.º 4
0
/* Triple DES Key Set, may have iv, will have direction */
int CRYPT_TDES_KeySet(CRYPT_TDES_CTX* tdes, const unsigned char* key,
                      const unsigned char* iv, int dir)
{
    typedef char tdes_test[sizeof(CRYPT_TDES_CTX) >= sizeof(Des3) ? 1 : -1];
    (void)sizeof(tdes_test);

    if (tdes == NULL || key == NULL)
        return BAD_FUNC_ARG;

    return Des3_SetKey((Des3*)tdes, key, iv, dir);
}
Ejemplo n.º 5
0
Archivo: des3.c Proyecto: b055man/krb5
/*
 * k5_des3_encrypt: Encrypt data buffer using 3DES.  
 *  
 * @key      DES key (with odd parity)
 * @ivec     Initialization Vector
 * @data     Input/Output buffer (in-place encryption, block-by-block)
 * @num_data Number of blocks
 *
 * Returns 0 on success, krb5_error_code on error
 */
static krb5_error_code
k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
                size_t num_data)
{
    int ret;
    Des3 des3;
    unsigned char iv[DES_BLOCK_SIZE];
    unsigned char iblock[DES_BLOCK_SIZE];
    unsigned char oblock[DES_BLOCK_SIZE];
    //struct iov_block_state input_pos, output_pos;
    struct iov_cursor cursor;

    krb5_boolean empty;

    ret = validate(key, ivec, data, num_data, &empty);
    if (ret != 0 || empty)
        return ret;

    memset(iv, 0, sizeof(iv));
    
    /* Check if IV exists and is the correct size */
    if (ivec && ivec->data) {
        if (ivec->length != sizeof(iv))
            return KRB5_CRYPTO_INTERNAL;
        memcpy(iv, ivec->data, ivec->length);
    }

    Des3_SetKey(&des3, key->keyblock.contents, iv, DES_ENCRYPTION);

    k5_iov_cursor_init(&cursor, data, num_data, DES_BLOCK_SIZE, FALSE);

    for (;;) {

        if (!k5_iov_cursor_get(&cursor, iblock))
            break;


        Des3_CbcEncrypt(&des3, oblock, iblock, DES_BLOCK_SIZE);

        k5_iov_cursor_put(&cursor, oblock);

    }

    if (ivec != NULL)
        memcpy(ivec->data, oblock, DES_BLOCK_SIZE);

    zap(iv, sizeof(iv));
    zap(iblock, sizeof(iblock));
    zap(oblock, sizeof(oblock));

    return 0;
}
Ejemplo n.º 6
0
void bench_des(void)
{
    Des3   enc;
    double start, total, persec;
    int    i;

    Des3_SetKey(&enc, key, iv, DES_ENCRYPTION);
    start = current_time();

    for(i = 0; i < megs; i++)
        Des3_CbcEncrypt(&enc, plain, cipher, sizeof(plain));

    total = current_time() - start;

    persec = 1 / total * megs;

    printf("3DES     %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
           persec);
}
Ejemplo n.º 7
0
static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
                   byte side)
{
#ifdef BUILD_ARC4
    word32 sz = specs->key_size;
    if (specs->bulk_cipher_algorithm == rc4) {
        if (side == CLIENT_END) {
            Arc4SetKey(&enc->arc4, keys->client_write_key, sz);
            Arc4SetKey(&dec->arc4, keys->server_write_key, sz);
        }
        else {
            Arc4SetKey(&enc->arc4, keys->server_write_key, sz);
            Arc4SetKey(&dec->arc4, keys->client_write_key, sz);
        }
    }
#endif
    
#ifdef BUILD_HC128
    if (specs->bulk_cipher_algorithm == hc128) {
        if (side == CLIENT_END) {
            Hc128_SetKey(&enc->hc128, keys->client_write_key,
                                          keys->client_write_IV);
            Hc128_SetKey(&dec->hc128, keys->server_write_key,
                                          keys->server_write_IV);
        }
        else {
            Hc128_SetKey(&enc->hc128, keys->server_write_key,
                                         keys->server_write_IV);
            Hc128_SetKey(&dec->hc128, keys->client_write_key,
                                         keys->client_write_IV);
        }
    }
#endif
    
#ifdef BUILD_RABBIT
    if (specs->bulk_cipher_algorithm == rabbit) {
        if (side == CLIENT_END) {
            RabbitSetKey(&enc->rabbit, keys->client_write_key,
                                           keys->client_write_IV);
            RabbitSetKey(&dec->rabbit, keys->server_write_key,
                                           keys->server_write_IV);
        }
        else {
            RabbitSetKey(&enc->rabbit, keys->server_write_key,
                                           keys->server_write_IV);
            RabbitSetKey(&dec->rabbit, keys->client_write_key,
                                           keys->client_write_IV);
        }
    }
#endif
    
#ifdef BUILD_DES3
    if (specs->bulk_cipher_algorithm == triple_des) {
        if (side == CLIENT_END) {
            Des3_SetKey(&enc->des3, keys->client_write_key,
                        keys->client_write_IV, DES_ENCRYPTION);
            Des3_SetKey(&dec->des3, keys->server_write_key,
                        keys->server_write_IV, DES_DECRYPTION);
        }
        else {
            Des3_SetKey(&enc->des3, keys->server_write_key,
                        keys->server_write_IV, DES_ENCRYPTION);
            Des3_SetKey(&dec->des3, keys->client_write_key,
                keys->client_write_IV, DES_DECRYPTION);
        }
    }
#endif

#ifdef BUILD_AES
    if (specs->bulk_cipher_algorithm == aes) {
        if (side == CLIENT_END) {
            AesSetKey(&enc->aes, keys->client_write_key,
                      specs->key_size, keys->client_write_IV,
                      AES_ENCRYPTION);
            AesSetKey(&dec->aes, keys->server_write_key,
                      specs->key_size, keys->server_write_IV,
                      AES_DECRYPTION);
        }
        else {
            AesSetKey(&enc->aes, keys->server_write_key,
                      specs->key_size, keys->server_write_IV,
                      AES_ENCRYPTION);
            AesSetKey(&dec->aes, keys->client_write_key,
                      specs->key_size, keys->client_write_IV,
                      AES_DECRYPTION);
        }
    }
#endif

    keys->sequence_number      = 0;
    keys->peer_sequence_number = 0;
    keys->encryptionOn         = 0;

    return 0;
}
Ejemplo n.º 8
0
static int SetKeys(SSL* ssl)
{
#ifdef BUILD_ARC4
    word32 sz = ssl->specs.key_size;
    if (ssl->specs.bulk_cipher_algorithm == rc4) {
        if (ssl->options.side == CLIENT_END) {
            Arc4SetKey(&ssl->encrypt.arc4, ssl->keys.client_write_key, sz);
            Arc4SetKey(&ssl->decrypt.arc4, ssl->keys.server_write_key, sz);
        }
        else {
            Arc4SetKey(&ssl->encrypt.arc4, ssl->keys.server_write_key, sz);
            Arc4SetKey(&ssl->decrypt.arc4, ssl->keys.client_write_key, sz);
        }
    }
#endif
    
#ifdef BUILD_HC128
    if (ssl->specs.bulk_cipher_algorithm == hc128) {
        if (ssl->options.side == CLIENT_END) {
            Hc128_SetKey(&ssl->encrypt.hc128, ssl->keys.client_write_key,
                                              ssl->keys.client_write_IV);
            Hc128_SetKey(&ssl->decrypt.hc128, ssl->keys.server_write_key,
                                              ssl->keys.server_write_IV);
        }
        else {
            Hc128_SetKey(&ssl->encrypt.hc128, ssl->keys.server_write_key,
                                              ssl->keys.server_write_IV);
            Hc128_SetKey(&ssl->decrypt.hc128, ssl->keys.client_write_key,
                                              ssl->keys.client_write_IV);
        }
    }
#endif
    
#ifdef BUILD_RABBIT
    if (ssl->specs.bulk_cipher_algorithm == rabbit) {
        if (ssl->options.side == CLIENT_END) {
            RabbitSetKey(&ssl->encrypt.rabbit, ssl->keys.client_write_key,
                                               ssl->keys.client_write_IV);
            RabbitSetKey(&ssl->decrypt.rabbit, ssl->keys.server_write_key,
                                               ssl->keys.server_write_IV);
        }
        else {
            RabbitSetKey(&ssl->encrypt.rabbit, ssl->keys.server_write_key,
                                               ssl->keys.server_write_IV);
            RabbitSetKey(&ssl->decrypt.rabbit, ssl->keys.client_write_key,
                                               ssl->keys.client_write_IV);
        }
    }
#endif
    
#ifdef BUILD_DES3
    if (ssl->specs.bulk_cipher_algorithm == triple_des) {
        if (ssl->options.side == CLIENT_END) {
            Des3_SetKey(&ssl->encrypt.des3, ssl->keys.client_write_key,
                        ssl->keys.client_write_IV, DES_ENCRYPTION);
            Des3_SetKey(&ssl->decrypt.des3, ssl->keys.server_write_key,
                        ssl->keys.server_write_IV, DES_DECRYPTION);
        }
        else {
            Des3_SetKey(&ssl->encrypt.des3, ssl->keys.server_write_key,
                        ssl->keys.server_write_IV, DES_ENCRYPTION);
            Des3_SetKey(&ssl->decrypt.des3, ssl->keys.client_write_key,
                ssl->keys.client_write_IV, DES_DECRYPTION);
        }
    }
#endif

#ifdef BUILD_AES
    if (ssl->specs.bulk_cipher_algorithm == aes) {
        if (ssl->options.side == CLIENT_END) {
            AesSetKey(&ssl->encrypt.aes, ssl->keys.client_write_key,
                      ssl->specs.key_size, ssl->keys.client_write_IV,
                      AES_ENCRYPTION);
            AesSetKey(&ssl->decrypt.aes, ssl->keys.server_write_key,
                      ssl->specs.key_size, ssl->keys.server_write_IV,
                      AES_DECRYPTION);
        }
        else {
            AesSetKey(&ssl->encrypt.aes, ssl->keys.server_write_key,
                      ssl->specs.key_size, ssl->keys.server_write_IV,
                      AES_ENCRYPTION);
            AesSetKey(&ssl->decrypt.aes, ssl->keys.client_write_key,
                      ssl->specs.key_size, ssl->keys.client_write_IV,
                      AES_DECRYPTION);
        }
    }
#endif

    ssl->keys.sequence_number      = 0;
    ssl->keys.peer_sequence_number = 0;
    ssl->keys.encryptionOn         = 0;

    return 0;
}
Ejemplo n.º 9
0
/* build PKCS#7 envelopedData content type, return enveloped size */
int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
{
    int i, ret = 0, idx = 0;
    int totalSz = 0, padSz = 0, desOutSz = 0;

    int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
    byte contentInfoSeq[MAX_SEQ_SZ];
    byte outerContentType[MAX_ALGO_SZ];
    byte outerContent[MAX_SEQ_SZ];

    int envDataSeqSz, verSz;
    byte envDataSeq[MAX_SEQ_SZ];
    byte ver[MAX_VERSION_SZ];

    RNG rng;
    int contentKeyEncSz, blockKeySz;
    int dynamicFlag = 0;
    byte contentKeyPlain[MAX_CONTENT_KEY_LEN];
    byte contentKeyEnc[MAX_ENCRYPTED_KEY_SZ];
    byte* plain;
    byte* encryptedContent;

    int recipSz, recipSetSz;
    byte recip[MAX_RECIP_SZ];
    byte recipSet[MAX_SET_SZ];

    int encContentOctetSz, encContentSeqSz, contentTypeSz;
    int contentEncAlgoSz, ivOctetStringSz;
    byte encContentSeq[MAX_SEQ_SZ];
    byte contentType[MAX_ALGO_SZ];
    byte contentEncAlgo[MAX_ALGO_SZ];
    byte tmpIv[DES_BLOCK_SIZE];
    byte ivOctetString[MAX_OCTET_STR_SZ];
    byte encContentOctet[MAX_OCTET_STR_SZ];

    if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
        pkcs7->encryptOID == 0 || pkcs7->singleCert == NULL)
        return BAD_FUNC_ARG;

    if (output == NULL || outputSz == 0)
        return BAD_FUNC_ARG;

    /* PKCS#7 only supports DES, 3DES for now */
    switch (pkcs7->encryptOID) {
        case DESb:
            blockKeySz = DES_KEYLEN;
            break;

        case DES3b:
            blockKeySz = DES3_KEYLEN;
            break;

        default:
            CYASSL_MSG("Unsupported content cipher type");
            return ALGO_ID_E;
    };

    /* outer content type */
    outerContentTypeSz = SetContentType(ENVELOPED_DATA, outerContentType);

    /* version, defined as 0 in RFC 2315 */
    verSz = SetMyVersion(0, ver, 0);

    /* generate random content encryption key */
    ret = InitRng(&rng);
    if (ret != 0)
        return ret;

    ret = RNG_GenerateBlock(&rng, contentKeyPlain, blockKeySz);
    if (ret != 0)
        return ret;

    /* build RecipientInfo, only handle 1 for now */
    recipSz = CreateRecipientInfo(pkcs7->singleCert, pkcs7->singleCertSz, RSAk,
                                  blockKeySz, &rng, contentKeyPlain,
                                  contentKeyEnc, &contentKeyEncSz, recip,
                                  MAX_RECIP_SZ);

    if (recipSz < 0) {
        CYASSL_MSG("Failed to create RecipientInfo");
        return recipSz;
    }
    recipSetSz = SetSet(recipSz, recipSet);

    /* generate IV for block cipher */
    ret = RNG_GenerateBlock(&rng, tmpIv, DES_BLOCK_SIZE);
    if (ret != 0)
        return ret;

    /* EncryptedContentInfo */
    contentTypeSz = SetContentType(pkcs7->contentOID, contentType);
    if (contentTypeSz == 0)
        return BAD_FUNC_ARG;

    /* allocate encrypted content buffer, pad if necessary, PKCS#7 padding */
    padSz = DES_BLOCK_SIZE - (pkcs7->contentSz % DES_BLOCK_SIZE);
    desOutSz = pkcs7->contentSz + padSz;

    if (padSz != 0) {
        plain = XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        if (plain == NULL) {
            return MEMORY_E;
        }
        XMEMCPY(plain, pkcs7->content, pkcs7->contentSz);
        dynamicFlag = 1;

        for (i = 0; i < padSz; i++) {
            plain[pkcs7->contentSz + i] = padSz;
        }

    } else {
        plain = pkcs7->content;
        desOutSz = pkcs7->contentSz;
    }

    encryptedContent = XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (encryptedContent == NULL) {
        if (dynamicFlag)
            XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        return MEMORY_E;
    }

    /* put together IV OCTET STRING */
    ivOctetStringSz = SetOctetString(DES_BLOCK_SIZE, ivOctetString);

    /* build up our ContentEncryptionAlgorithmIdentifier sequence,
     * adding (ivOctetStringSz + DES_BLOCK_SIZE) for IV OCTET STRING */
    contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
                                 blkType, ivOctetStringSz + DES_BLOCK_SIZE);
    if (contentEncAlgoSz == 0)
        return BAD_FUNC_ARG;

    /* encrypt content */
    if (pkcs7->encryptOID == DESb) {
        Des des;

        ret = Des_SetKey(&des, contentKeyPlain, tmpIv, DES_ENCRYPTION);

        if (ret == 0)
            Des_CbcEncrypt(&des, encryptedContent, plain, desOutSz);

        if (ret != 0) {
            XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            if (dynamicFlag)
                XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            return ret;
        }
    }
    else if (pkcs7->encryptOID == DES3b) {
        Des3 des3;

        ret = Des3_SetKey(&des3, contentKeyPlain, tmpIv, DES_ENCRYPTION);

        if (ret == 0)
            ret = Des3_CbcEncrypt(&des3, encryptedContent, plain, desOutSz);

        if (ret != 0) {
            XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            if (dynamicFlag)
                XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            return ret;
        }
    }

    encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0,
                                    desOutSz, encContentOctet);

    encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
                                  ivOctetStringSz + DES_BLOCK_SIZE +
                                  encContentOctetSz + desOutSz, encContentSeq);

    /* keep track of sizes for outer wrapper layering */
    totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
              contentEncAlgoSz + ivOctetStringSz + DES_BLOCK_SIZE +
              encContentOctetSz + desOutSz;

    /* EnvelopedData */
    envDataSeqSz = SetSequence(totalSz, envDataSeq);
    totalSz += envDataSeqSz;

    /* outer content */
    outerContentSz = SetExplicit(0, totalSz, outerContent);
    totalSz += outerContentTypeSz;
    totalSz += outerContentSz;

    /* ContentInfo */
    contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
    totalSz += contentInfoSeqSz;

    if (totalSz > (int)outputSz) {
        CYASSL_MSG("Pkcs7_encrypt output buffer too small");
        XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        if (dynamicFlag)
            XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        return BUFFER_E;
    }

    XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
    idx += contentInfoSeqSz;
    XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
    idx += outerContentTypeSz;
    XMEMCPY(output + idx, outerContent, outerContentSz);
    idx += outerContentSz;
    XMEMCPY(output + idx, envDataSeq, envDataSeqSz);
    idx += envDataSeqSz;
    XMEMCPY(output + idx, ver, verSz);
    idx += verSz;
    XMEMCPY(output + idx, recipSet, recipSetSz);
    idx += recipSetSz;
    XMEMCPY(output + idx, recip, recipSz);
    idx += recipSz;
    XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
    idx += encContentSeqSz;
    XMEMCPY(output + idx, contentType, contentTypeSz);
    idx += contentTypeSz;
    XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
    idx += contentEncAlgoSz;
    XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
    idx += ivOctetStringSz;
    XMEMCPY(output + idx, tmpIv, DES_BLOCK_SIZE);
    idx += DES_BLOCK_SIZE;
    XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
    idx += encContentOctetSz;
    XMEMCPY(output + idx, encryptedContent, desOutSz);
    idx += desOutSz;

#ifdef NO_RC4
    FreeRng(&rng);
#endif

    XMEMSET(contentKeyPlain, 0, MAX_CONTENT_KEY_LEN);
    XMEMSET(contentKeyEnc,   0, MAX_ENCRYPTED_KEY_SZ);

    if (dynamicFlag)
        XFREE(plain, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
    XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);

    return idx;
}
Ejemplo n.º 10
0
/* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */
CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
                                         word32 pkiMsgSz, byte* output,
                                         word32 outputSz)
{
    int recipFound = 0;
    int ret, version, length;
    word32 savedIdx = 0, idx = 0;
    word32 contentType, encOID;
    byte   issuerHash[SHA_DIGEST_SIZE];
    mp_int serialNum;

    int encryptedKeySz, keySz;
    byte tmpIv[DES_BLOCK_SIZE];
    byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
    byte* decryptedKey = NULL;

    RsaKey privKey;
    int encryptedContentSz;
    byte padLen;
    byte* encryptedContent = NULL;

    if (pkcs7 == NULL || pkcs7->singleCert == NULL ||
        pkcs7->singleCertSz == 0 || pkcs7->privateKey == NULL ||
        pkcs7->privateKeySz == 0)
        return BAD_FUNC_ARG;

    if (pkiMsg == NULL || pkiMsgSz == 0 ||
        output == NULL || outputSz == 0)
        return BAD_FUNC_ARG;

    /* load private key */
    ret = InitRsaKey(&privKey, 0);
    if (ret != 0) return ret;
    ret = RsaPrivateKeyDecode(pkcs7->privateKey, &idx, &privKey,
                              pkcs7->privateKeySz);
    if (ret != 0) {
        CYASSL_MSG("Failed to decode RSA private key");
        return ret;
    }

    idx = 0;

    /* read past ContentInfo, verify type is envelopedData */
    if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    if (contentType != ENVELOPED_DATA) {
        CYASSL_MSG("PKCS#7 input not of type EnvelopedData");
        return PKCS7_OID_E;
    }

    if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
        return ASN_PARSE_E;

    if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    /* remove EnvelopedData and version */
    if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    if (GetMyVersion(pkiMsg, &idx, &version) < 0)
        return ASN_PARSE_E;

    if (version != 0) {
        CYASSL_MSG("PKCS#7 envelopedData needs to be of version 0");
        return ASN_VERSION_E;
    }

    /* walk through RecipientInfo set, find correct recipient */
    if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    savedIdx = idx;
    recipFound = 0;

    /* when looking for next recipient, use first sequence and version to
     * indicate there is another, if not, move on */
    while(recipFound == 0) {

        /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to
         * last good saved one */
        if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
            idx = savedIdx;
            break;
        }

        if (GetMyVersion(pkiMsg, &idx, &version) < 0) {
            idx = savedIdx;
            break;
        }

        if (version != 0)
            return ASN_VERSION_E;

        /* remove IssuerAndSerialNumber */
        if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
            return ASN_PARSE_E;

        if (GetNameHash(pkiMsg, &idx, issuerHash, pkiMsgSz) < 0)
            return ASN_PARSE_E;

        /* if we found correct recipient, issuer hashes will match */
        if (XMEMCMP(issuerHash, pkcs7->issuerHash, SHA_DIGEST_SIZE) == 0) {
            recipFound = 1;
        }

        if (GetInt(&serialNum, pkiMsg, &idx, pkiMsgSz) < 0)
            return ASN_PARSE_E;
        mp_clear(&serialNum);

        if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0)
            return ASN_PARSE_E;

        /* key encryption algorithm must be RSA for now */
        if (encOID != RSAk)
            return ALGO_ID_E;

        /* read encryptedKey */
        if (pkiMsg[idx++] != ASN_OCTET_STRING)
            return ASN_PARSE_E;

        if (GetLength(pkiMsg, &idx, &encryptedKeySz, pkiMsgSz) < 0)
            return ASN_PARSE_E;

        if (recipFound == 1)
            XMEMCPY(encryptedKey, &pkiMsg[idx], encryptedKeySz);
        idx += encryptedKeySz;

        /* update good idx */
        savedIdx = idx;
    }

    if (recipFound == 0) {
        CYASSL_MSG("No recipient found in envelopedData that matches input");
        return PKCS7_RECIP_E;
    }

    /* remove EncryptedContentInfo */
    if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
    if (pkiMsg[idx++] != ASN_OCTET_STRING)
        return ASN_PARSE_E;

    if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    if (length != DES_BLOCK_SIZE) {
        CYASSL_MSG("Incorrect IV length, must be of DES_BLOCK_SIZE");
        return ASN_PARSE_E;
    }

    XMEMCPY(tmpIv, &pkiMsg[idx], length);
    idx += length;

    /* read encryptedContent, cont[0] */
    if (pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0))
        return ASN_PARSE_E;

    if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    encryptedContent = XMALLOC(encryptedContentSz, NULL,
                               DYNAMIC_TYPE_TMP_BUFFER);

    XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);

    /* decrypt encryptedKey */
    keySz = RsaPrivateDecryptInline(encryptedKey, encryptedKeySz,
                                    &decryptedKey, &privKey);
    FreeRsaKey(&privKey);
    if (keySz <= 0)
        return keySz;

    /* decrypt encryptedContent */
    if (encOID == DESb) {
        Des des;
        ret = Des_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION);

        if (ret == 0)
            Des_CbcDecrypt(&des, encryptedContent, encryptedContent,
                                 encryptedContentSz);

        if (ret != 0) {
            XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            return ret;
        }
    }
    else if (encOID == DES3b) {
        Des3 des;
        ret = Des3_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION);
        if (ret == 0)
            ret = Des3_CbcDecrypt(&des, encryptedContent, encryptedContent,
                                  encryptedContentSz);

        if (ret != 0) {
            XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            return ret;
        }
    } else {
        CYASSL_MSG("Unsupported content encryption OID type");
        return ALGO_ID_E;
    }

    padLen = encryptedContent[encryptedContentSz-1];

    /* copy plaintext to output */
    XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);

    /* free memory, zero out keys */
    XMEMSET(encryptedKey, 0, MAX_ENCRYPTED_KEY_SZ);
    XMEMSET(encryptedContent, 0, encryptedContentSz);
    XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);

    return encryptedContentSz - padLen;
}
Ejemplo n.º 11
0
static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
                   byte side, void* heap, RNG* rng)
{
#ifdef BUILD_ARC4
    word32 sz = specs->key_size;
    if (specs->bulk_cipher_algorithm == rc4) {
        enc->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER);
        if (enc->arc4 == NULL)
            return MEMORY_E;
        dec->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER);
        if (dec->arc4 == NULL)
            return MEMORY_E;
        if (side == CLIENT_END) {
            Arc4SetKey(enc->arc4, keys->client_write_key, sz);
            Arc4SetKey(dec->arc4, keys->server_write_key, sz);
        }
        else {
            Arc4SetKey(enc->arc4, keys->server_write_key, sz);
            Arc4SetKey(dec->arc4, keys->client_write_key, sz);
        }
    }
#endif
    
#ifdef HAVE_HC128
    if (specs->bulk_cipher_algorithm == hc128) {
        enc->hc128 = (HC128*)XMALLOC(sizeof(HC128), heap, DYNAMIC_TYPE_CIPHER);
        if (enc->hc128 == NULL)
            return MEMORY_E;
        dec->hc128 = (HC128*)XMALLOC(sizeof(HC128), heap, DYNAMIC_TYPE_CIPHER);
        if (dec->hc128 == NULL)
            return MEMORY_E;
        if (side == CLIENT_END) {
            Hc128_SetKey(enc->hc128, keys->client_write_key,
                                          keys->client_write_IV);
            Hc128_SetKey(dec->hc128, keys->server_write_key,
                                          keys->server_write_IV);
        }
        else {
            Hc128_SetKey(enc->hc128, keys->server_write_key,
                                         keys->server_write_IV);
            Hc128_SetKey(dec->hc128, keys->client_write_key,
                                         keys->client_write_IV);
        }
    }
#endif
    
#ifdef BUILD_RABBIT
    if (specs->bulk_cipher_algorithm == rabbit) {
        enc->rabbit = (Rabbit*)XMALLOC(sizeof(Rabbit),heap,DYNAMIC_TYPE_CIPHER);
        if (enc->rabbit == NULL)
            return MEMORY_E;
        dec->rabbit = (Rabbit*)XMALLOC(sizeof(Rabbit),heap,DYNAMIC_TYPE_CIPHER);
        if (dec->rabbit == NULL)
            return MEMORY_E;
        if (side == CLIENT_END) {
            RabbitSetKey(enc->rabbit, keys->client_write_key,
                                           keys->client_write_IV);
            RabbitSetKey(dec->rabbit, keys->server_write_key,
                                           keys->server_write_IV);
        }
        else {
            RabbitSetKey(enc->rabbit, keys->server_write_key,
                                           keys->server_write_IV);
            RabbitSetKey(dec->rabbit, keys->client_write_key,
                                           keys->client_write_IV);
        }
    }
#endif
    
#ifdef BUILD_DES3
    if (specs->bulk_cipher_algorithm == triple_des) {
        enc->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER);
        if (enc->des3 == NULL)
            return MEMORY_E;
        dec->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER);
        if (dec->des3 == NULL)
            return MEMORY_E;
        if (side == CLIENT_END) {
            Des3_SetKey(enc->des3, keys->client_write_key,
                        keys->client_write_IV, DES_ENCRYPTION);
            Des3_SetKey(dec->des3, keys->server_write_key,
                        keys->server_write_IV, DES_DECRYPTION);
        }
        else {
            Des3_SetKey(enc->des3, keys->server_write_key,
                        keys->server_write_IV, DES_ENCRYPTION);
            Des3_SetKey(dec->des3, keys->client_write_key,
                keys->client_write_IV, DES_DECRYPTION);
        }
    }
#endif

#ifdef BUILD_AES
    if (specs->bulk_cipher_algorithm == aes) {
        enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
        if (enc->aes == NULL)
            return MEMORY_E;
        dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
        if (dec->aes == NULL)
            return MEMORY_E;
        if (side == CLIENT_END) {
            AesSetKey(enc->aes, keys->client_write_key,
                      specs->key_size, keys->client_write_IV,
                      AES_ENCRYPTION);
            AesSetKey(dec->aes, keys->server_write_key,
                      specs->key_size, keys->server_write_IV,
                      AES_DECRYPTION);
        }
        else {
            AesSetKey(enc->aes, keys->server_write_key,
                      specs->key_size, keys->server_write_IV,
                      AES_ENCRYPTION);
            AesSetKey(dec->aes, keys->client_write_key,
                      specs->key_size, keys->client_write_IV,
                      AES_DECRYPTION);
        }
    }
#endif

#ifdef BUILD_AESGCM
    if (specs->bulk_cipher_algorithm == aes_gcm) {
        byte iv[AES_GCM_EXP_IV_SZ];
        enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
        if (enc->aes == NULL)
            return MEMORY_E;
        dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
        if (dec->aes == NULL)
            return MEMORY_E;

        /* Initialize the AES-GCM explicit IV to a random number. */
        RNG_GenerateBlock(rng, iv, sizeof(iv));
        AesGcmSetExpIV(enc->aes, iv);

        if (side == CLIENT_END) {
            AesGcmSetKey(enc->aes, keys->client_write_key, specs->key_size,
                        keys->client_write_IV);
            AesGcmSetKey(dec->aes, keys->server_write_key, specs->key_size,
                        keys->server_write_IV);
        }
        else {
            AesGcmSetKey(enc->aes, keys->server_write_key, specs->key_size,
                        keys->server_write_IV);
            AesGcmSetKey(dec->aes, keys->client_write_key, specs->key_size,
                        keys->client_write_IV);
        }
    }
#endif

    keys->sequence_number      = 0;
    keys->peer_sequence_number = 0;
    keys->encryptionOn         = 0;
    (void)rng;

    return 0;
}