Exemple #1
0
// encryption: data must be NUL-padded to BLOCKSIZE
// decryption: data must be padded to BLOCKSIZE
// len must be < 2^31
void SymmCipher::ctr_crypt(byte* data, unsigned len, m_off_t pos, ctr_iv ctriv, byte* mac, bool encrypt, bool initmac)
{
    assert(!(pos & (KEYLENGTH - 1)));

    byte ctr[BLOCKSIZE], tmp[BLOCKSIZE];

    MemAccess::set<int64_t>(ctr,ctriv);
    setint64(pos / BLOCKSIZE, ctr + sizeof ctriv);

    if (mac && initmac)
    {
        memcpy(mac, ctr, sizeof ctriv);
        memcpy(mac + sizeof ctriv, ctr, sizeof ctriv);
    }

    while ((int)len > 0)
    {
        if (encrypt)
        {
            if(mac)
            {
                xorblock(data, mac);
                ecb_encrypt(mac);
            }

            ecb_encrypt(ctr, tmp);
            xorblock(tmp, data);
        }
        else
        {
            ecb_encrypt(ctr, tmp);
            xorblock(tmp, data);

            if (mac)
            {
                if (len >= (unsigned)BLOCKSIZE)
                {
                    xorblock(data, mac);
                }
                else
                {
                    xorblock(data, mac, len);
                }

                ecb_encrypt(mac);
            }
        }

        len -= BLOCKSIZE;
        data += BLOCKSIZE;

        incblock(ctr);
    }
}
Exemple #2
0
static void convert_passwd(char *buf, char *newpwd, const int keyfd)
{
    uint8_t key[HEXPASSWDLEN];
    Key_schedule schedule;
    unsigned int i, j;

    if (!newpwd) {
        /* convert to binary */
        for (i = j = 0; i < sizeof(key); i += 2, j++)
            buf[j] = (unhex(buf[i]) << 4) | unhex(buf[i + 1]);
        if (j <= DES_KEY_SZ)
            memset(buf + j, 0, sizeof(key) - j);
    }

    if (keyfd > -1) {
        lseek(keyfd, 0, SEEK_SET);
        read(keyfd, key, sizeof(key));
        /* convert to binary */
        for (i = j = 0; i < sizeof(key); i += 2, j++)
            key[j] = (unhex(key[i]) << 4) | unhex(key[i + 1]);
        if (j <= DES_KEY_SZ)
            memset(key + j, 0, sizeof(key) - j);
        key_sched((C_Block *) key, schedule);
        memset(key, 0, sizeof(key));
        if (newpwd) {
            ecb_encrypt((C_Block *) newpwd, (C_Block *) newpwd, schedule,
                        DES_ENCRYPT);
        } else {
            /* decrypt the password */
            ecb_encrypt((C_Block *) buf, (C_Block *) buf, schedule, DES_DECRYPT);
        }
        memset(&schedule, 0, sizeof(schedule));
    }

    if (newpwd) {
        const unsigned char hextable[] = "0123456789ABCDEF";

        /* convert to hex */
        for (i = j = 0; i < DES_KEY_SZ; i++, j += 2) {
            buf[j] = hextable[(newpwd[i] & 0xF0) >> 4];
            buf[j + 1] = hextable[newpwd[i] & 0x0F];
        }
    }
}
Exemple #3
0
C4Err ECB_Encrypt(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_encrypt(in, out, bytesIn, &ECB); CKSTAT;
    
    
done:
    
    ecb_done(&ECB);
    
    if(status != CRYPT_OK)
        err = sCrypt2C4Err(status);
    
    return err;
    
}
Exemple #4
0
// encryption: data must be NUL-padded to BLOCKSIZE
// decryption: data must be padded to BLOCKSIZE
// len must be < 2^31
void SymmCipher::ctr_crypt(byte* data, unsigned len, m_off_t pos, ctr_iv ctriv, byte* mac, int encrypt)
{
    assert(!(pos&(KEYLENGTH-1)));

    byte ctr[BLOCKSIZE], tmp[BLOCKSIZE];

    *(uint64_t*)ctr = ctriv;
    setint64(pos/BLOCKSIZE,ctr+sizeof ctriv);

    memcpy(mac,ctr,sizeof ctriv);
    memcpy(mac+sizeof ctriv,ctr,sizeof ctriv);

    while ((int)len > 0)
    {
        if (encrypt)
        {
            xorblock(data,mac);
            ecb_encrypt(mac);
            ecb_encrypt(ctr,tmp);
            xorblock(tmp,data);
        }
        else
        {
            ecb_encrypt(ctr,tmp);
            xorblock(tmp,data);
            if (len >= (unsigned)BLOCKSIZE) xorblock(data,mac);
            else xorblock(data,mac,len);
            ecb_encrypt(mac);
        }

        len -= BLOCKSIZE;
        data += BLOCKSIZE;

        incblock(ctr);
    }
}
Exemple #5
0
uint32_t ecb_ut(void)
{
	uint8_t key[16] = {
	    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00,
	0x11, 0x22, 0x33, 0x44, 0x55 };
	uint8_t clear_text[16] = {
	    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00,
	0x11, 0x22, 0x33, 0x44, 0x55 };
	uint8_t cipher_text[16];
	uint32_t status = 0;
	struct ecb ecb;
	struct ecb_ut_context context;

	ecb_encrypt(key, clear_text, cipher_text, 0);

	context.done = 0;
	ecb.in_key_le = key;
	ecb.in_clear_text_le = clear_text;
	ecb.fp_ecb = ecb_cb;
	ecb.context = &context;
	status = ecb_encrypt_nonblocking(&ecb);
	do {
		__WFE();
		__SEV();
		__WFE();
	} while (!context.done);

	if (context.status != 0) {
		return context.status;
	}

	status = memcmp(cipher_text, context.cipher_text, sizeof(cipher_text));
	if (status) {
		return status;
	}

	return status;
}
Exemple #6
0
static int
EncryptECB(
    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_encrypt(data, dest, dataLength, &state);
        ecb_done(&state);
    }

    return status;
}
Exemple #7
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;
}
/*!
 * \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);

}
Exemple #9
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;
}