示例#1
0
文件: c4cipher.c 项目: rhardman/C4
C4Err ECB_Decrypt(Cipher_Algorithm algorithm,
                  const void *	key,
                  const void *	in,
                  size_t         bytesIn,
                  void *         out )
{
    int             err = kC4Err_NoErr;
    int             status  =  CRYPT_OK;
    symmetric_ECB   ECB;
    
    int             keylen  = 0;
    int             cipher  = -1;
    
    switch(algorithm)
    {
        case kCipher_Algorithm_AES128:
            keylen = 128 >> 3;
            cipher = find_cipher("aes");
            
            break;
        case kCipher_Algorithm_AES192:
            keylen = 192 >> 3;
            cipher = find_cipher("aes");
            
            break;
        case kCipher_Algorithm_AES256:
            keylen = 256 >> 3;
            cipher = find_cipher("aes");
            break;
            
        case kCipher_Algorithm_2FISH256:
            keylen = 256 >> 3;
            cipher = find_cipher("twofish");
            break;
            
        default:
            RETERR(kC4Err_BadCipherNumber);
    }
    
    status  = ecb_start(cipher, key, keylen, 0, &ECB ); CKSTAT;
    
    status  = ecb_decrypt(in, out, bytesIn, &ECB); CKSTAT;
    
    
done:
    
    ecb_done(&ECB);
    
    if(status != CRYPT_OK)
        err = sCrypt2C4Err(status);
    
    return err;
}
示例#2
0
static int
DecryptECB(
    int cipher,
    int rounds,
    int counterMode,
    unsigned char *iv,
    unsigned char *key,
    unsigned long keyLength,
    unsigned char *data,
    unsigned long dataLength,
    unsigned char *dest
    )
{
    int status;
    symmetric_ECB state;

    status = ecb_start(cipher, key, keyLength, rounds, &state);
    if (status == CRYPT_OK) {
        status = ecb_decrypt(data, dest, dataLength, &state);
        ecb_done(&state);
    }

    return status;
}
示例#3
0
static int RunCipherKAT(  katvector *kat)

{
    int err = CRYPT_OK;
    char* name = NULL;
    uint8_t *out = NULL;
    
    size_t  alloc_len =   MAX(kat->EBClen, kat->CBClen);
    
    symmetric_ECB ECB;
    symmetric_CBC CBC;
    
    out = malloc(alloc_len); 
    ZERO(out, alloc_len);
    
    
    //   err = cipher_is_valid(kat->algor); CKERR;
    
    name = cipher_name(kat->algor);
    
    printf("\t%-7s %d ", name, kat->keysize);
    
    printf("%6s", "ECB");
    
    DO( ecb_start(kat->algor, kat->key, kat->keysize>>3, 0, &ECB));
    
    DO( ecb_encrypt(kat->PT, out, kat->PTlen, &ECB))
    
    /* check against know-answer */
    DO( compareResults( kat->EBC, out, kat->EBClen , kResultFormat_Byte, "Symmetric Encrypt"));
    
    DO(ecb_decrypt(out, out, kat->PTlen, &ECB));
    
    /* check against orginal plain-text  */
    DO(compareResults( kat->PT, out, kat->PTlen , kResultFormat_Byte, "Symmetric Decrypt"));
    
    
    printf("%6s", "CBC");
    
    DO(cbc_start(kat->algor, kat->IV,  kat->key, kat->keysize>>3, 0, &CBC));
    
    DO(cbc_encrypt(kat->PT, out, kat->PTlen, &CBC));
    
    /* check against know-answer */
    DO(compareResults( kat->CBC, out, kat->CBClen , kResultFormat_Byte, "Symmetric Encrypt"));
    
    // reset CBC befire decrypt*/
    cbc_done(&CBC);
    DO(cbc_start(kat->algor, kat->IV,  kat->key, kat->keysize>>3, 0, &CBC));
    
    DO(cbc_decrypt(out, out, kat->PTlen, &CBC));
    
    /* check against orginal plain-text  */
    DO( compareResults( kat->PT, out, kat->PTlen , kResultFormat_Byte, "Symmetric Decrypt"));
    
done:
    
    ecb_done(&ECB);
    cbc_done(&CBC);
    
    free(out);
    
    printf("\n");
    return err;
}
示例#4
0
/*!
 * \brief Main application function.                              \n
 * -> Initialize clock                                            \n
 * -> Initialize USART for print functions                        \n
 * -> Initialize AES to generate Key schedule for AES-128         \n
 * -> Based on the AES mode enabled in conf_example.h file,       \n
 *    execute encryption and decryption of a message and          \n
 *    compare them against input data to check its functionality. \n
 * -> The decrypted message can be viewed on the COM port terminal \n
 */
int main(void)
{

	/*
	 * Initialize the System clock 
	 * Note: Clock should be configured in conf_clock.h
	 */
	system_init();

	/* Configure EDBG SERCOM UART to print messages */
	configure_usart();

	/* Generate key schedule for AES-128 from the Cipher Key */
	aes_init(key_vectors); 

	/* Print status messages */
	printf("AES key generated successfully!..\r\n");
	/* Print Input message for user */
	printf("\n The message to be encrypted is:\r\n");
	printf("\n %s \r\n",pText);

	/*
	 * Perform ECB, CFB, OFB, CTR and CBC Encryption and Decryption
	 * based on the mode enabled in conf_example.h. User can choose
	 * the mode that he wants to evaluate. By default, all modes are
	 * enabled.
	 * The decrypted message is printed to EDBG virtual COM port.
	 * If the decrypted message is same as the input plain text,
	 * it ensures the working of each mode.
	 */
#if (AES_ECB == true)
        
     	//Perform ECB Encryption
	ecb_encrypt( pText, cText, sizeof(pText) );
	for (volatile int i = 0; i < 1000; i++);
	//Perform ECB Decryption
	ecb_decrypt( cText, pText1, sizeof(cText));
	//Print decrypted message
	printf("\n Decrypted message using AES-ECB mode : \r\n");
	printf("\n %s \r\n",pText1);

#endif

#if (AES_CFB == true)

	//Perform CFB Encryption
	cfb_encrypt(pText, cText, init_vector, CFB_MODE_128, sizeof(pText));
	for (volatile int i = 0; i < 1000; i++);
	//Perform CFB Decryption
	cfb_decrypt(cText, pText1, init_vector, CFB_MODE_128, sizeof(cText));
	//Print decrypted message
	printf("\n Decrypted message using AES-CFB mode : \r\n");
	printf("\n %s \r\n",pText1);
 
#endif

#if (AES_OFB == true)

	//Perform OFB Encryption
	ofb_encrypt(pText, cText, init_vector, sizeof(pText));
	for (volatile int i = 0; i < 1000; i++);
	//Perform OFB Decryption
	ofb_encrypt(cText, pText1, init_vector, sizeof(cText));
	//Print decrytped message
	printf("\n Decrypted message using AES-OFB mode : \r\n");
	printf("\n %s \r\n",pText1);

#endif

#if (AES_CTR == true)

	/* Initialize Counter block with initialization vector, 
	 * nonce and counter value
	 */
	ctr_blk_t counter_vector = {
		.i_vector = AES_CTR_IVECTOR,
		.nonce = AES_CTR_NONCE,
		.counter = AES_CTR_COUNTER
	};
	//Perform CTR Encryption
	ctr_encrypt_decrypt(pText, cText, &counter_vector, sizeof(pText));
	//Send Counter block value to decryptor
	for (volatile int i = 0; i < 1000; i++);
	counter_vector.i_vector = AES_CTR_IVECTOR;
	counter_vector.nonce = AES_CTR_NONCE;
	counter_vector.counter = AES_CTR_COUNTER;
	//Perform CTR Decryption
	ctr_encrypt_decrypt(cText, pText1, &counter_vector, sizeof(pText1));
	//Print decrypted message
	printf("\n Decrypted message using AES-CTR mode : \r\n");
	printf("\n %s \r\n",pText1);

#endif

/*! \warning CBC mode is done at the last as it process input plain text 
 * during encryption and so the plain text value is not retained.
 * For testing purpose, to preserve the input plan text for testing with
 * other modes, this mode is added at the last.
 */
#if (AES_CBC == true)

	//Perform CBC Encryption
	cbc_encrypt(pText, cText, init_vector, sizeof(pText));
	for (volatile int i = 0; i < 1000; i++);
	//Perform CBC Decryption
	cbc_decrypt(cText, pText1, init_vector, sizeof(cText));
	//Print decrypted message
	printf("\n Decrypted message using AES-CBC mode : \r\n");
	printf("\n %s \r\n",pText1);

#endif

	/* Forever loop */
	while(1);

}
示例#5
0
int ltc_decrypt(const unsigned char * cipherText, unsigned char * plainText, unsigned int length)
{
#if defined(ENCRYPTION_ECB)
    if (ecb_decrypt(cipherText, plainText, length, &sECB) != CRYPT_OK) {
#elif defined(ENCRYPTION_CBC)
    if (cbc_decrypt(cipherText, plainText, length, &sCBC) != CRYPT_OK) {
#elif defined(ENCRYPTION_CTR)
    if (ctr_decrypt(cipherText, plainText, length, &sCTR) != CRYPT_OK) {
#endif
        return 0;
    }
    else {
        return 1;
    }
}
#endif

//------------------------------------------------------------------------------
/// Decrypts a block of data in CBC mode
/// \param Data to decrypt
/// \param Buffer to store decrypted data
/// \param Length of data
/// \return 1 if successful, 0 otherwise.
//------------------------------------------------------------------------------
#ifndef ONLY_ONE_ENCRYPTION
int ltc_decrypt_CBC(const unsigned char * cipherText, unsigned char * plainText, unsigned int length)
{
    if (cbc_decrypt(cipherText, plainText, length, &sCBC) != CRYPT_OK) {
        return 0;
    }
    else {
        return 1;
    }
}

//------------------------------------------------------------------------------
/// Decrypts a block of data in CTR mode
/// \param Data to decrypt
/// \param Buffer to store decrypted data
/// \param Length of data
/// \return 1 if successful, 0 otherwise.
//------------------------------------------------------------------------------
int ltc_decrypt_CTR(const unsigned char * cipherText, unsigned char * plainText, unsigned int length)
{
    if (ctr_decrypt(cipherText, plainText, length, &sCTR) != CRYPT_OK) {
        return 0;
    }
    else {
        return 1;
    }
}

//------------------------------------------------------------------------------
/// Decrypts a block of data in ECB mode
/// \param Data to decrypt
/// \param Buffer to store decrypted data
/// \param Length of data
/// \return 1 if successful, 0 otherwise.
//------------------------------------------------------------------------------
int ltc_decrypt_ECB(const unsigned char * cipherText, unsigned char * plainText, unsigned int length)
{
    if (ecb_decrypt(cipherText, plainText, length, &sECB) != CRYPT_OK) {
        return 0;
    }
    else {
        return 1;
    }
}
示例#6
0
TEE_Result tee_cipher_update(void *ctx, uint32_t algo,
			     TEE_OperationMode mode, bool last_block,
			     const uint8_t *data, size_t len, uint8_t *dst)
{
	TEE_Result res;
	int ltc_res = CRYPT_OK;
	size_t block_size;
	uint8_t tmp_block[64], tmp2_block[64];
	int nb_blocks, len_last_block;
	struct symmetric_CTS *cts;

	/*
	 * Check that the block contains the correct number of data, apart
	 * for the last block in some XTS / CTR / XTS mode
	 */
	res = tee_cipher_get_block_size(algo, &block_size);
	if (res != TEE_SUCCESS)
		return res;
	if ((len % block_size) != 0) {
		if (!last_block)
			return TEE_ERROR_BAD_PARAMETERS;

		switch (algo) {
		case TEE_ALG_AES_ECB_NOPAD:
		case TEE_ALG_DES_ECB_NOPAD:
		case TEE_ALG_DES3_ECB_NOPAD:
		case TEE_ALG_AES_CBC_NOPAD:
		case TEE_ALG_DES_CBC_NOPAD:
		case TEE_ALG_DES3_CBC_NOPAD:
			return TEE_ERROR_BAD_PARAMETERS;

		case TEE_ALG_AES_CTR:
		case TEE_ALG_AES_XTS:
		case TEE_ALG_AES_CTS:
			/*
			 * These modes doesn't require padding for the last
			 * block.
			 *
			 * This isn't entirely true, both XTS and CTS can only
			 * encrypt minimum one block and also they need at least
			 * one complete block in the last update to finish the
			 * encryption. The algorithms are supposed to detect
			 * that, we're only making sure that all data fed up to
			 * that point consists of complete blocks.
			 */
			break;

		default:
			return TEE_ERROR_NOT_SUPPORTED;
		}
	}

	switch (algo) {
	case TEE_ALG_AES_ECB_NOPAD:
	case TEE_ALG_DES_ECB_NOPAD:
	case TEE_ALG_DES3_ECB_NOPAD:
		if (mode == TEE_MODE_ENCRYPT)
		    ltc_res = ecb_encrypt(data, dst, len, (symmetric_ECB *)ctx);
		else
		    ltc_res = ecb_decrypt(data, dst, len, (symmetric_ECB *)ctx);
		break;

	case TEE_ALG_AES_CBC_NOPAD:
	case TEE_ALG_DES_CBC_NOPAD:
	case TEE_ALG_DES3_CBC_NOPAD:
		if (mode == TEE_MODE_ENCRYPT)
		    ltc_res = cbc_encrypt(data, dst, len, (symmetric_CBC *)ctx);
		else
		    ltc_res = cbc_decrypt(data, dst, len, (symmetric_CBC *)ctx);
		break;

	case TEE_ALG_AES_CTR:
		if (mode == TEE_MODE_ENCRYPT)
		    ltc_res = ctr_encrypt(data, dst, len, (symmetric_CTR *)ctx);
		else
		    ltc_res = ctr_decrypt(data, dst, len, (symmetric_CTR *)ctx);
		break;

	case TEE_ALG_AES_XTS:
		return TEE_ERROR_NOT_SUPPORTED;
/*
if (mode == TEE_MODE_ENCRYPT) {
	ltc_res = xts_encrypt(data, dst, len, (symmetric_xts *)ctx);
} else {
	ltc_res = xts_decrypt(data, dst, len, (symmetric_xts *)ctx);
}
*/
		break;

	case TEE_ALG_AES_CTS:
		/*
		 * From http://en.wikipedia.org/wiki/Ciphertext_stealing
		 * CBC ciphertext stealing encryption using a standard
		 * CBC interface:
		 *	1. Pad the last partial plaintext block with 0.
		 *	2. Encrypt the whole padded plaintext using the
		 *	   standard CBC mode.
		 *	3. Swap the last two ciphertext blocks.
		 *	4. Truncate the ciphertext to the length of the
		 *	   original plaintext.
		 *
		 * CBC ciphertext stealing decryption using a standard
		 * CBC interface
		 *	1. Dn = Decrypt (K, Cn-1). Decrypt the second to last
		 *	   ciphertext block.
		 *	2. Cn = Cn || Tail (Dn, B-M). Pad the ciphertext to the
		 *	   nearest multiple of the block size using the last
		 *	   B-M bits of block cipher decryption of the
		 *	   second-to-last ciphertext block.
		 *	3. Swap the last two ciphertext blocks.
		 *	4. Decrypt the (modified) ciphertext using the standard
		 *	   CBC mode.
		 *	5. Truncate the plaintext to the length of the original
		 *	   ciphertext.
		 */
		cts = (struct symmetric_CTS *)ctx;
		if (!last_block)
			return tee_cipher_update(
				&cts->cbc, TEE_ALG_AES_CBC_NOPAD, mode,
				last_block, data, len, dst);

		/* Compute the last block length and check constraints */
		if (block_size > 64)
			return TEE_ERROR_BAD_STATE;
		nb_blocks = ((len + block_size - 1) / block_size);
		if (nb_blocks < 2)
			return TEE_ERROR_BAD_STATE;
		len_last_block = len % block_size;
		if (len_last_block == 0)
			len_last_block = block_size;

		if (mode == TEE_MODE_ENCRYPT) {
			memcpy(tmp_block,
			       data + ((nb_blocks - 1) * block_size),
			       len_last_block);
			memset(tmp_block + len_last_block,
			       0,
			       block_size - len_last_block);

			res = tee_cipher_update(
				&cts->cbc, TEE_ALG_AES_CBC_NOPAD, mode, 0,
				data, (nb_blocks - 1) * block_size, dst);
			if (res != TEE_SUCCESS)
				return res;

			memcpy(dst + (nb_blocks - 1) * block_size,
			       dst + (nb_blocks - 2) * block_size,
			       len_last_block);

			res = tee_cipher_update(
				&cts->cbc, TEE_ALG_AES_CBC_NOPAD, mode, 0,
				tmp_block,
				block_size,
				dst + (nb_blocks - 2) * block_size);
			if (res != TEE_SUCCESS)
				return res;
		} else {
			/* 1. Decrypt the second to last ciphertext block */
			res = tee_cipher_update(
				&cts->ecb, TEE_ALG_AES_ECB_NOPAD, mode, 0,
				data + (nb_blocks - 2) * block_size,
				block_size,
				tmp2_block);
			if (res != TEE_SUCCESS)
				return res;

			/* 2. Cn = Cn || Tail (Dn, B-M) */
			memcpy(tmp_block,
			       data + ((nb_blocks - 1) * block_size),
			       len_last_block);
			memcpy(tmp_block + len_last_block,
			       tmp2_block + len_last_block,
			       block_size - len_last_block);

			/* 3. Swap the last two ciphertext blocks */
			/* done by passing the correct buffers in step 4. */

			/* 4. Decrypt the (modified) ciphertext */
			if (nb_blocks > 2) {
				res = tee_cipher_update(
					&cts->cbc, TEE_ALG_AES_CBC_NOPAD,
					mode, 0,
					data,
					(nb_blocks - 2) * block_size,
					dst);
				if (res != TEE_SUCCESS)
					return res;
			}

			res = tee_cipher_update(
				&cts->cbc, TEE_ALG_AES_CBC_NOPAD, mode, 0,
				tmp_block,
				block_size,
				dst + ((nb_blocks - 2) * block_size));
			if (res != TEE_SUCCESS)
				return res;

			res = tee_cipher_update(
				&cts->cbc, TEE_ALG_AES_CBC_NOPAD, mode, 0,
				data + ((nb_blocks - 2) * block_size),
				block_size,
				tmp_block);
			if (res != TEE_SUCCESS)
				return res;

			/* 5. Truncate the plaintext */
			memcpy(dst + (nb_blocks - 1) * block_size,
			       tmp_block,
			       len_last_block);
			break;
		}
		break;

	default:
		return TEE_ERROR_NOT_SUPPORTED;
	}

	if (ltc_res == CRYPT_OK)
		return TEE_SUCCESS;
	else
		return TEE_ERROR_BAD_STATE;
}
示例#7
0
static inline void ecb_wrapper(void* inbuf, void* outbuf, size_t size, uint32_t mode, uint8_t *ctr)
{
	ecb_decrypt(inbuf, outbuf, size, mode);
}