Exemplo n.º 1
0
int ccm_test( void )
{
    unsigned long taglen, x;
    unsigned char buf[64], buf2[64], tag2[16], tag[16];
    int stat;

    for( x = 0; x < (sizeof(tests) / sizeof(tests[0])); x++ )
    {
        taglen = tests[x].taglen;

        ccm_memory( tests[x].key, 16, tests[x].nonce, tests[x].noncelen, tests[x].header,
                    tests[x].headerlen, (unsigned char *)tests[x].pt, tests[x].ptlen, buf,
                    tag, taglen, 0, 0);

        if( memcmp(buf, tests[x].ct, tests[x].ptlen) )
            goto error;
        if( memcmp(tag, tests[x].tag, tests[x].taglen) )
            goto error;

        ccm_memory( tests[x].key, 16, tests[x].nonce, tests[x].noncelen, tests[x].header,
                    tests[x].headerlen, buf2, tests[x].ptlen, buf,
                    tag, taglen, 1 , &stat );

        if( memcmp(buf2, tests[x].pt, tests[x].ptlen) )
            goto error;
        if( stat == RETURN_ERROR )
            goto error;
    }

    printf( "\nOK\n" );
    return RETURN_OK;
error: printf( "\nerror\n" );
    return RETURN_ERROR;
}
Exemplo n.º 2
0
SCLError CCM_Decrypt(uint8_t *key,  size_t keyLen, 
                     uint8_t *seq,  size_t seqLen, 
                     uint8_t *in,   size_t inLen,
                     uint8_t *tag,      size_t tagSize, 
                     uint8_t **outData, size_t *outSize)
{
    SCLError err = kSCLError_NoErr;
    int     status = CRYPT_OK;
    
    uint8_t *buffer = NULL;
    size_t buffLen = inLen;
    int IVlen = keyLen >>1;
    uint8_t  bytes2Pad = 0;
     
    unsigned char  T[32];
    unsigned long tagLen = sizeof(T);
    
    buffer = XMALLOC(buffLen);
    
    status = ccm_memory(find_cipher("aes"), 
                        key, IVlen , 
                        NULL,
                        key+ IVlen, IVlen, 
                        seq, seqLen, 
                        buffer, buffLen, 
                        in, 
                        T, &tagLen ,
                        CCM_DECRYPT);CKSTAT;
    
// This will only compare as many bytes of the tag as you specify in tagSize
// we need to be careful with CCM to not leak key information, an easy way to do
// that is to only export half the hash.
    
     if((memcmp(T,tag,tagSize) != 0)) 
        RETERR(kSCLError_CorruptData);
    
    bytes2Pad = *(buffer+buffLen-1);
    
    *outData = buffer;
    *outSize = buffLen- bytes2Pad;
    
done:
    if(status != CRYPT_OK || err != kSCLError_NoErr)
    {
        if(buffer)
        {
            memset(buffer, buffLen, 0);
            XFREE(buffer);
        }
        
        err = IsSCLError(err)?err:sCrypt2SCLError(status);
    }
    
    
    return err;
}
Exemplo n.º 3
0
SCLError CCM_Encrypt(uint8_t *key, size_t keyLen, 
                     uint8_t *seq, size_t seqLen, 
                     const uint8_t *in, size_t inLen,
                     uint8_t **outData, size_t *outSize, 
                     uint8_t *outTag, size_t tagSize)

{
    SCLError err = kSCLError_NoErr;
    int     status = CRYPT_OK;
    
    uint8_t  bytes2Pad;
    uint8_t *buffer = NULL;
    size_t buffLen = 0;
    int IVlen = keyLen >>1;
    unsigned char  T[32];
    unsigned long tagLen = 0;
    unsigned long tag2Copy = tagSize;
    
    ValidateParam (tagSize <= sizeof(T));
    
    /* calclulate Pad byte */

    if(inLen < MIN_MSG_BLOCKSIZE)
    {
        bytes2Pad =  MIN_MSG_BLOCKSIZE - inLen;
    }
    else
    {
        bytes2Pad =  roundup(inLen, MSG_BLOCKSIZE) +  MSG_BLOCKSIZE - inLen;
    };
    
    
    buffLen = inLen + bytes2Pad;
    buffer = XMALLOC(buffLen);
    
    memcpy(buffer, in, inLen);
    memset(buffer+inLen, bytes2Pad, bytes2Pad);
    
    tagLen = sizeof(T);
    status = ccm_memory(find_cipher("aes"), 
                        key, IVlen , 
                        NULL,
                        key+ IVlen, IVlen, 
                        seq,    seqLen, 
                        buffer, buffLen, 
                        buffer, 
                        T, &tagLen ,
                        CCM_ENCRYPT); CKSTAT;
    
    *outData = buffer;
    *outSize = buffLen;
    memcpy(outTag, T, tag2Copy);
    
done:
    
    if(status != CRYPT_OK)
    {
        if(buffer)
        {
            memset(buffer, buffLen, 0);
            XFREE(buffer);
        }
        err = sCrypt2SCLError(status);
    }
    
    return err;
}
Exemplo n.º 4
0
TEE_Result tee_authenc_dec_final(
	void *ctx, uint32_t algo, const uint8_t *src_data,
	size_t src_len, uint8_t *dst_data, const uint8_t *tag, size_t tag_len)
{
	TEE_Result res = TEE_ERROR_BAD_STATE;
	struct tee_ccm_state *ccm;
	struct tee_gcm_state *gcm;
	int ltc_res;
	uint8_t dst_tag[TEE_xCM_TAG_MAX_LENGTH];
	size_t dst_len, init_len;
	unsigned long ltc_tag_len = tag_len;

	res = tee_cipher_get_block_size(algo, &dst_len);
	if (res != TEE_SUCCESS)
		return res;
	if (tag_len == 0)
		return TEE_ERROR_SHORT_BUFFER;
	if (tag_len > TEE_xCM_TAG_MAX_LENGTH)
		return TEE_ERROR_BAD_STATE;

	switch (algo) {
	case TEE_ALG_AES_CCM:
		ccm = ctx;

		init_len = ccm->current_payload_len;
		if (src_len) {
			memcpy(ccm->payload + ccm->current_payload_len,
			       src_data, src_len);
			ccm->current_payload_len += src_len;
		}

		if (ccm->payload_len != ccm->current_payload_len)
			return TEE_ERROR_BAD_PARAMETERS;

		ltc_res = ccm_memory(
			ccm->ltc_cipherindex,
			ccm->key, ccm->key_len,
			0,	/* not previously scheduled */
			ccm->nonce,  ccm->nonce_len,
			ccm->header, ccm->header_len,
			ccm->res_payload,
			ccm->current_payload_len, ccm->payload,
			dst_tag, &ltc_tag_len, CCM_DECRYPT);
		if (ltc_res != CRYPT_OK)
			return TEE_ERROR_BAD_STATE;

		if (src_len)
			memcpy(dst_data, ccm->res_payload + init_len, src_len);
		break;


	case TEE_ALG_AES_GCM:
		/* Process the last buffer, if any */
		gcm = ctx;
		res = tee_authenc_update_payload(
			&gcm->ctx, algo, TEE_MODE_DECRYPT,
			src_data, src_len, dst_data);
		if (res != TEE_SUCCESS)
			return res;

		/* Finalize the authentication */
		ltc_res = gcm_done(&gcm->ctx, dst_tag, &ltc_tag_len);
		if (ltc_res != CRYPT_OK)
			return TEE_ERROR_BAD_STATE;
		break;

	default:
		return TEE_ERROR_NOT_SUPPORTED;
	}

	if (buf_compare_ct(dst_tag, tag, tag_len) != 0)
		res = TEE_ERROR_MAC_INVALID;
	else
		res = TEE_SUCCESS;
	return res;
}
Exemplo n.º 5
0
TEE_Result tee_authenc_enc_final(
	void *ctx, uint32_t algo, const uint8_t *src_data,
	size_t src_len, uint8_t *dst_data,
	uint8_t *dst_tag, size_t *dst_tag_len)
{
	TEE_Result res, final_res = TEE_ERROR_MAC_INVALID;
	struct tee_ccm_state *ccm;
	struct tee_gcm_state *gcm;
	size_t digest_size;
	int ltc_res;
	int init_len;

	/* Check the resulting buffer is not too short */
	res = tee_cipher_get_block_size(algo, &digest_size);
	if (res != TEE_SUCCESS) {
		final_res = res;
		goto out;
	}

	switch (algo) {
	case TEE_ALG_AES_CCM:
		ccm = ctx;

		init_len = ccm->current_payload_len;
		if (src_len) {
			memcpy(ccm->payload + ccm->current_payload_len,
			       src_data, src_len);
			ccm->current_payload_len += src_len;
		}

		if (ccm->payload_len != ccm->current_payload_len)
			return TEE_ERROR_BAD_PARAMETERS;

		if (*dst_tag_len < ccm->tag_len) {
			*dst_tag_len = ccm->tag_len;
			return TEE_ERROR_SHORT_BUFFER;
		}
		*dst_tag_len = ccm->tag_len;

		ltc_res = ccm_memory(
			ccm->ltc_cipherindex,
			ccm->key, ccm->key_len,
			0,	/* not previously scheduled */
			ccm->nonce,  ccm->nonce_len,
			ccm->header, ccm->header_len,
			ccm->payload, ccm->current_payload_len,
			ccm->res_payload,
			dst_tag, (unsigned long *)dst_tag_len, CCM_ENCRYPT);
		if (ltc_res != CRYPT_OK)
			return TEE_ERROR_BAD_STATE;
		if (src_len)
			memcpy(dst_data, ccm->res_payload + init_len, src_len);
		break;

	case TEE_ALG_AES_GCM:
		/* Finalize the remaining buffer */
		gcm = ctx;
		res = tee_authenc_update_payload(
			&gcm->ctx, algo, TEE_MODE_ENCRYPT,
			src_data, src_len, dst_data);
		if (res != TEE_SUCCESS) {
			final_res = res;
			goto out;
		}

		if (*dst_tag_len < gcm->tag_len) {
			*dst_tag_len = gcm->tag_len;
			return TEE_ERROR_SHORT_BUFFER;
		}
		*dst_tag_len = gcm->tag_len;

		/* Process the last buffer, if any */
		ltc_res = gcm_done(
			&gcm->ctx,
			dst_tag, (unsigned long *)dst_tag_len);
		if (ltc_res != CRYPT_OK)
			goto out;
		break;

	default:
		return TEE_ERROR_NOT_SUPPORTED;
	}
	final_res = TEE_SUCCESS;

out:
	return final_res;
}
Exemplo n.º 6
0
TEE_Result tee_authenc_update_payload(
	void *ctx, uint32_t algo, TEE_OperationMode mode,
	const uint8_t *src_data, size_t src_len, uint8_t *dst_data)
{
	TEE_Result res;
	int ltc_res, dir;
	struct tee_ccm_state *ccm;
	struct tee_gcm_state *gcm;
	unsigned char *pt, *ct;	/* the plain and the cipher text */

	if (mode == TEE_MODE_ENCRYPT) {
		pt = (unsigned char *)src_data;
		ct = dst_data;
	} else {
		pt = dst_data;
		ct = (unsigned char *)src_data;
	}

	switch (algo) {
	case TEE_ALG_AES_CCM:
		/* Check aad has been correctly added */
		ccm = ctx;
		if (ccm->aad_len != ccm->header_len)
			return TEE_ERROR_BAD_STATE;

		/*
		 * check we do not add more data than what was defined at
		 * the init
		 */
		if (ccm->current_payload_len + src_len > ccm->payload_len)
			return TEE_ERROR_BAD_PARAMETERS;
		memcpy(ccm->payload + ccm->current_payload_len,
		       src_data, src_len);
		ccm->current_payload_len += src_len;

		dir = (mode == TEE_MODE_ENCRYPT ? CCM_ENCRYPT : CCM_DECRYPT);
		ltc_res = ccm_memory(
			ccm->ltc_cipherindex,
			ccm->key, ccm->key_len,
			0,	/* not presecheduled */
			ccm->nonce,  ccm->nonce_len,
			ccm->header, ccm->header_len,
			pt, src_len, ct,
			ccm->tag, &ccm->tag_len, dir);
		if (ltc_res != CRYPT_OK)
			return TEE_ERROR_BAD_STATE;
		break;

	case TEE_ALG_AES_GCM:
		/* aad is optional ==> add one without length */
		gcm = ctx;
		if (gcm->ctx.mode == LTC_GCM_MODE_IV) {
			res = tee_authenc_update_aad(
					&gcm->ctx, algo, mode, 0, 0);
			if (res != TEE_SUCCESS)
				return res;
		}

		/* process the data */
		dir = (mode == TEE_MODE_ENCRYPT ? GCM_ENCRYPT : GCM_DECRYPT);
		ltc_res = gcm_process(&gcm->ctx, pt, src_len, ct, dir);
		if (ltc_res != CRYPT_OK)
			return TEE_ERROR_BAD_STATE;
		break;

	default:
		return TEE_ERROR_NOT_SUPPORTED;
	}

	return TEE_SUCCESS;
}
void ccm_gen(void)
{
   int err, kl, x, y1, z;
   FILE *out;
   unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], 
                 plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE];
   unsigned long len;

   out = fopen("ccm_tv.txt", "w");
   fprintf(out, "CCM Test Vectors.  Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key.  The outputs\n"
                "are of the form ciphertext,tag for a given NN.  The key for step N>1 is the tag of the previous\n"
                "step repeated sufficiently.  The nonce is fixed throughout at 13 bytes 000102...\n\n");

   for (x = 0; cipher_descriptor[x].name != NULL; x++) {
      kl = cipher_descriptor[x].block_length;

      /* skip ciphers which do not have 128 bit block sizes */
      if (kl != 16) continue;

      if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) {
         kl = cipher_descriptor[x].max_key_length;
      }
      fprintf(out, "CCM-%s (%d byte key)\n", cipher_descriptor[x].name, kl);

      /* the key */
      for (z = 0; z < kl; z++) {
          key[z] = (z & 255);
      }

      /* fixed nonce */
      for (z = 0; z < cipher_descriptor[x].block_length; z++) {
          nonce[z] = z;
      }
      
      for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){
         for (z = 0; z < y1; z++) {
            plaintext[z] = (unsigned char)(z & 255);
         }
         len = sizeof(tag);
         if ((err = ccm_memory(x, key, kl, nonce, 13, plaintext, y1, plaintext, y1, plaintext, tag, &len, CCM_ENCRYPT)) != CRYPT_OK) {
            printf("Error CCM'ing: %s\n", error_to_string(err));
            exit(EXIT_FAILURE);
         }
         fprintf(out, "%3d: ", y1);
         for (z = 0; z < y1; z++) {
            fprintf(out, "%02X", plaintext[z]);
         }
         fprintf(out, ", ");
         for (z = 0; z <(int)len; z++) {
            fprintf(out, "%02X", tag[z]);
         }
         fprintf(out, "\n");

         /* forward the key */
         for (z = 0; z < kl; z++) {
             key[z] = tag[z % len];
         }
      }
      fprintf(out, "\n");
   }
   fclose(out);
}
Exemplo n.º 8
0
int ccm_test(void)
{
#ifndef LTC_TEST
   return CRYPT_NOP;
#else
   static const struct {
       unsigned char key[16];
       unsigned char nonce[16];
       int           noncelen;
       unsigned char header[64];
       int           headerlen;
       unsigned char pt[64];
       int           ptlen;
       unsigned char ct[64];
       unsigned char tag[16];
       unsigned long taglen;
   } tests[] = {

/* 13 byte nonce, 8 byte auth, 23 byte pt */
{
   { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
     0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF },
   { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0,
     0xA1, 0xA2, 0xA3, 0xA4, 0xA5 },
   13,
   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
   8,
   { 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
     0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E },
   23,
   { 0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2,
     0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
     0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84 },
   { 0x17, 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0 },
   8
},

/* 13 byte nonce, 12 byte header, 19 byte pt */
{
   { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
     0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF },
   { 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x03, 0xA0,
     0xA1, 0xA2, 0xA3, 0xA4, 0xA5 },
   13,
   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0A, 0x0B },
   12,
   { 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
     0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
     0x1C, 0x1D, 0x1E },
   19,
   { 0xA2, 0x8C, 0x68, 0x65, 0x93, 0x9A, 0x9A, 0x79,
     0xFA, 0xAA, 0x5C, 0x4C, 0x2A, 0x9D, 0x4A, 0x91,
     0xCD, 0xAC, 0x8C },
   { 0x96, 0xC8, 0x61, 0xB9, 0xC9, 0xE6, 0x1E, 0xF1 },
   8
},

/* supplied by Brian Gladman */
{
   { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
     0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f },
   { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16  },
   7,
   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
   8,
   { 0x20, 0x21, 0x22, 0x23 },
   4,
   { 0x71, 0x62, 0x01, 0x5b },
   { 0x4d, 0xac, 0x25, 0x5d },
   4
},

{
   { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
     0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f },
   { 0x00, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xb5,
     0x03, 0x97, 0x76, 0xe7, 0x0c },
   13,
   { 0x08, 0x40, 0x0f, 0xd2, 0xe1, 0x28, 0xa5, 0x7c,
     0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xab, 0xae,
     0xa5, 0xb8, 0xfc, 0xba, 0x00, 0x00 },
   22,
   { 0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
     0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
     0x7e, 0x78, 0xa0, 0x50 },
   20,
   { 0xf3, 0xd0, 0xa2, 0xfe, 0x9a, 0x3d, 0xbf, 0x23,
     0x42, 0xa6, 0x43, 0xe4, 0x32, 0x46, 0xe8, 0x0c,
     0x3c, 0x04, 0xd0, 0x19 },
   { 0x78, 0x45, 0xce, 0x0b, 0x16, 0xf9, 0x76, 0x23 },
   8
},

};
  unsigned long taglen, x, y;
  unsigned char buf[64], buf2[64], tag[16], tag2[16], tag3[16], zero[64];
  int           err, idx;
  symmetric_key skey;
  ccm_state ccm;
  
  zeromem(zero, 64);

  idx = find_cipher("aes");
  if (idx == -1) {
     idx = find_cipher("rijndael");
     if (idx == -1) {
        return CRYPT_NOP;
     }
  }

  for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) {
    for (y = 0; y < 2; y++) {
      taglen = tests[x].taglen;
      if (y == 0) {
         if ((err = cipher_descriptor[idx].setup(tests[x].key, 16, 0, &skey)) != CRYPT_OK) {
            return err;
         }

         if ((err = ccm_memory(idx,
                               tests[x].key, 16,
                               &skey,
                               tests[x].nonce, tests[x].noncelen,
                               tests[x].header, tests[x].headerlen,
                               (unsigned char*)tests[x].pt, tests[x].ptlen,
                               buf,
                               tag, &taglen, 0)) != CRYPT_OK) {
            return err;
         }
      } else {
         if ((err = ccm_init(&ccm, idx, tests[x].key, 16, tests[x].ptlen, tests[x].taglen, tests[x].headerlen)) != CRYPT_OK) {
            return err;
         }
         if ((err = ccm_add_nonce(&ccm, tests[x].nonce, tests[x].noncelen)) != CRYPT_OK) {
            return err;
         }
         if ((err = ccm_add_aad(&ccm, tests[x].header, tests[x].headerlen)) != CRYPT_OK) {
            return err;
         }
         if ((err = ccm_process(&ccm, (unsigned char*)tests[x].pt, tests[x].ptlen, buf, CCM_ENCRYPT)) != CRYPT_OK) {
            return err;
         }
         if ((err = ccm_done(&ccm, tag, &taglen)) != CRYPT_OK) {
            return err;
         }
      }

      if (XMEMCMP(buf, tests[x].ct, tests[x].ptlen)) {
#if defined(LTC_TEST_DBG)
         printf("\n%d: x=%lu y=%lu\n", __LINE__, x, y);
         print_hex("ct is    ", buf, tests[x].ptlen);
         print_hex("ct should", tests[x].ct, tests[x].ptlen);
#endif
         return CRYPT_FAIL_TESTVECTOR;
      }
      if (tests[x].taglen != taglen) {
#if defined(LTC_TEST_DBG)
         printf("\n%d: x=%lu y=%lu\n", __LINE__, x, y);
         printf("taglen %lu (is) %lu (should)\n", taglen, tests[x].taglen);
#endif
         return CRYPT_FAIL_TESTVECTOR;
      }
      if (XMEMCMP(tag, tests[x].tag, tests[x].taglen)) {
#if defined(LTC_TEST_DBG)
         printf("\n%d: x=%lu y=%lu\n", __LINE__, x, y);
         print_hex("tag is    ", tag, tests[x].taglen);
         print_hex("tag should", tests[x].tag, tests[x].taglen);
#endif
         return CRYPT_FAIL_TESTVECTOR;
      }

      if (y == 0) {
          XMEMCPY(tag3, tests[x].tag, tests[x].taglen);
          taglen = tests[x].taglen;
          if ((err = ccm_memory(idx,
                               tests[x].key, 16,
                               NULL,
                               tests[x].nonce, tests[x].noncelen,
                               tests[x].header, tests[x].headerlen,
                               buf2, tests[x].ptlen,
                               buf,
                               tag3, &taglen, 1   )) != CRYPT_OK) {
            return err;
         }
      } else {
         if ((err = ccm_init(&ccm, idx, tests[x].key, 16, tests[x].ptlen, tests[x].taglen, tests[x].headerlen)) != CRYPT_OK) {
            return err;
         }
         if ((err = ccm_add_nonce(&ccm, tests[x].nonce, tests[x].noncelen)) != CRYPT_OK) {
            return err;
         }
         if ((err = ccm_add_aad(&ccm, tests[x].header, tests[x].headerlen)) != CRYPT_OK) {
            return err;
         }
         if ((err = ccm_process(&ccm, buf2, tests[x].ptlen, buf, CCM_DECRYPT)) != CRYPT_OK) {
            return err;
         }
         if ((err = ccm_done(&ccm, tag2, &taglen)) != CRYPT_OK) {
            return err;
         }
      }

      if (XMEMCMP(buf2, tests[x].pt, tests[x].ptlen)) {
#if defined(LTC_TEST_DBG)
         printf("\n%d: x=%lu y=%lu\n", __LINE__, x, y);
         print_hex("pt is    ", buf2, tests[x].ptlen);
         print_hex("pt should", tests[x].pt, tests[x].ptlen);
#endif
         return CRYPT_FAIL_TESTVECTOR;
      }
      if (y == 0) {
        /* check if decryption with the wrong tag does not reveal the plaintext */
        XMEMCPY(tag3, tests[x].tag, tests[x].taglen);
        tag3[0] ^= 0xff; /* set the tag to the wrong value */
        taglen = tests[x].taglen;
        if ((err = ccm_memory(idx,
                              tests[x].key, 16,
                              NULL,
                              tests[x].nonce, tests[x].noncelen,
                              tests[x].header, tests[x].headerlen,
                              buf2, tests[x].ptlen,
                              buf,
                              tag3, &taglen, 1   )) != CRYPT_ERROR) {
          return CRYPT_FAIL_TESTVECTOR;
        }
        if (XMEMCMP(buf2, zero, tests[x].ptlen)) {
#if defined(LTC_CCM_TEST_DBG)
          printf("\n%d: x=%lu y=%lu\n", __LINE__, x, y);
          print_hex("pt is    ", buf2, tests[x].ptlen);
          print_hex("pt should", zero, tests[x].ptlen);
#endif
          return CRYPT_FAIL_TESTVECTOR;
        }
      } else {
        /* FIXME: Only check the tag if ccm_memory was not called: ccm_memory already
           validates the tag. ccm_process and ccm_done should somehow do the same,
           although with current setup it is impossible to keep the plaintext hidden
           if the tag is incorrect.
        */
        if (XMEMCMP(tag2, tests[x].tag, tests[x].taglen)) {
#if defined(LTC_TEST_DBG)
          printf("\n%d: x=%lu y=%lu\n", __LINE__, x, y);
          print_hex("tag is    ", tag2, tests[x].taglen);
          print_hex("tag should", tests[x].tag, tests[x].taglen);
#endif
          return CRYPT_FAIL_TESTVECTOR;
        }
      }

      if (y == 0) {
         cipher_descriptor[idx].done(&skey);
      }
    }
  }

  return CRYPT_OK;
#endif
}
Exemplo n.º 9
0
int
main(int argc, char **argv)
{
    symmetric_key skey;
    int err;

    /* Build the nonse */
    uint8_t nonse[13];
    uint8_t *ptr = nonse;
    memcpy(ptr, addr, 8);
    ptr += 8;
    memcpy(ptr, (uint8_t *)&frame_ctr, 4);
    ptr += 4;
    memcpy(ptr, &sec_level, 1);

    /* build the message */
    memset(msg, 0, sizeof(msg));
    msg[0] = 0xaa;

    printf("VARIABLES\n");
    printf("key: ");
    print_buffer(key, sizeof(key));
    printf("\n");

    printf("nonse: ");
    print_buffer(nonse, sizeof(nonse));
    printf("\n");

    printf("a: ");
    print_buffer(hdr, sizeof(hdr));
    printf("\n");
    printf("\n");

    register_cipher(&aes_desc);

    err = aes_setup(key, 16, 0, &skey);
    if (err != CRYPT_OK)
    {
        printf("setup failed with error %s\n", error_to_string(err));
        return -1;
    }

    err = ccm_memory(find_cipher("aes"),
                     NULL, 0,
                     &skey,
                     nonse, 13,
                     hdr, sizeof(hdr),
                     msg, 2,
                     ct,
                     tag, &tag_len,
                     CCM_ENCRYPT);
    if (err != CRYPT_OK)
    {
        printf("encryption failed with error %s\n", error_to_string(err));
        return -1;
    }

    printf("ENCRYPTED\n");
    printf("input: ");
    print_buffer(msg, sizeof(msg));
    printf("\n");

    printf("output: ");
    print_buffer(ct, sizeof(ct));
    printf("\n");

    printf("tag: ");
    print_buffer(tag, tag_len);
    printf("\n");
    printf("\n");

    memset(msg, 0xff, sizeof(msg));
    memset(tag, 0xff, sizeof(tag));
    memset(ct+2, 0x00, sizeof(ct)-2);

    err = ccm_memory(find_cipher("aes"),
                     NULL, 0,
                     &skey,
                     nonse, 13,
                     hdr, sizeof(hdr),
                     msg, 2,
                     ct,
                     tag, &tag_len,
                     CCM_DECRYPT);
    if (err != CRYPT_OK)
    {
        printf("encryption failed with error %s\n", error_to_string(err));
        return -1;
    }

    printf("DECRYPTED\n");
    printf("input: ");
    print_buffer(ct, sizeof(ct));
    printf("\n");

    printf("output: ");
    print_buffer(msg, sizeof(msg));
    printf("\n");

    printf("tag: ");
    print_buffer(tag, tag_len);
    printf("\n");

    aes_done(&skey);

    return 0;
}
Exemplo n.º 10
0
int ccm_test(void)
{
#ifndef LTC_TEST
   return CRYPT_NOP;
#else
   static const struct {
       unsigned char key[16];
       unsigned char nonce[16];
       int           noncelen;
       unsigned char header[64];
       int           headerlen;
       unsigned char pt[64];
       int           ptlen;
       unsigned char ct[64];
       unsigned char tag[16];
       int           taglen;
   } tests[] = {

/* 13 byte nonce, 8 byte auth, 23 byte pt */
{
   { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 
     0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF },
   { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, 
     0xA1, 0xA2, 0xA3, 0xA4, 0xA5 },
   13,
   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
   8,
   { 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
     0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E },
   23,
   { 0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2,
     0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
     0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84 },
   { 0x17, 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0 },
   8
},

/* 13 byte nonce, 12 byte header, 19 byte pt */
{
   { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 
     0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF },
   { 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x03, 0xA0, 
     0xA1, 0xA2, 0xA3, 0xA4, 0xA5 },
   13,
   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0A, 0x0B },
   12,
   { 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 
     0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 
     0x1C, 0x1D, 0x1E },
   19,
   { 0xA2, 0x8C, 0x68, 0x65, 0x93, 0x9A, 0x9A, 0x79, 
     0xFA, 0xAA, 0x5C, 0x4C, 0x2A, 0x9D, 0x4A, 0x91, 
     0xCD, 0xAC, 0x8C },
   { 0x96, 0xC8, 0x61, 0xB9, 0xC9, 0xE6, 0x1E, 0xF1 },
   8
},

/* supplied by Brian Gladman */
{
   { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 
     0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f },
   { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16  },
   7,
   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
   8,
   { 0x20, 0x21, 0x22, 0x23 },
   4,
   { 0x71, 0x62, 0x01, 0x5b },
   { 0x4d, 0xac, 0x25, 0x5d },
   4
},

{
   { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85, 
     0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f },
   { 0x00, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xb5, 
     0x03, 0x97, 0x76, 0xe7, 0x0c },
   13,
   { 0x08, 0x40, 0x0f, 0xd2, 0xe1, 0x28, 0xa5, 0x7c, 
     0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xab, 0xae, 
     0xa5, 0xb8, 0xfc, 0xba, 0x00, 0x00 },
   22,
   { 0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae, 
     0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb, 
     0x7e, 0x78, 0xa0, 0x50 },
   20,
   { 0xf3, 0xd0, 0xa2, 0xfe, 0x9a, 0x3d, 0xbf, 0x23, 
     0x42, 0xa6, 0x43, 0xe4, 0x32, 0x46, 0xe8, 0x0c, 
     0x3c, 0x04, 0xd0, 0x19 },
   { 0x78, 0x45, 0xce, 0x0b, 0x16, 0xf9, 0x76, 0x23 },
   8
},

};
  unsigned long taglen, x;
  unsigned char buf[64], buf2[64], tag2[16], tag[16];
  int           err, idx;
  symmetric_key skey;

  idx = find_cipher("aes");
  if (idx == -1) {
     idx = find_cipher("rijndael");
     if (idx == -1) {
        return CRYPT_NOP;
     }
  }

  for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) {
      taglen = tests[x].taglen;
      if ((err = cipher_descriptor[idx].setup(tests[x].key, 16, 0, &skey)) != CRYPT_OK) {
         return err;
      }
      
      if ((err = ccm_memory(idx,
                            tests[x].key, 16,
                            &skey,
                            tests[x].nonce, tests[x].noncelen,
                            tests[x].header, tests[x].headerlen,
                            (unsigned char*)tests[x].pt, tests[x].ptlen,
                            buf,
                            tag, &taglen, 0)) != CRYPT_OK) {
         return err;
      }

      if (XMEMCMP(buf, tests[x].ct, tests[x].ptlen)) {
         return CRYPT_FAIL_TESTVECTOR;
      }
      if (XMEMCMP(tag, tests[x].tag, tests[x].taglen)) {
         return CRYPT_FAIL_TESTVECTOR;
      }

      if ((err = ccm_memory(idx,
                            tests[x].key, 16,
                            NULL,
                            tests[x].nonce, tests[x].noncelen,
                            tests[x].header, tests[x].headerlen,
                            buf2, tests[x].ptlen,
                            buf,
                            tag2, &taglen, 1   )) != CRYPT_OK) {
         return err;
      }

      if (XMEMCMP(buf2, tests[x].pt, tests[x].ptlen)) {
         return CRYPT_FAIL_TESTVECTOR;
      }
      if (XMEMCMP(tag2, tests[x].tag, tests[x].taglen)) {
         return CRYPT_FAIL_TESTVECTOR;
      }
      cipher_descriptor[idx].done(&skey);
  }
  return CRYPT_OK;
#endif
}