Пример #1
0
krb5_error_code
krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec,
		    const krb5_data *input, krb5_data *output)
{
    aes_ctx ctx;
    char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE], tmp3[BLOCK_SIZE];
    int nblocks = 0, blockno;

/*    CHECK_SIZES; */

    if (aes_enc_key(key->contents, key->length, &ctx) != aes_good)
	abort();

    if (ivec)
	memcpy(tmp, ivec->data, BLOCK_SIZE);
    else
	memset(tmp, 0, BLOCK_SIZE);

    nblocks = (input->length + BLOCK_SIZE - 1) / BLOCK_SIZE;

    if (nblocks == 1) {
	/* Used when deriving keys. */
	if (input->length < BLOCK_SIZE)
	    return KRB5_BAD_MSIZE;
	enc(output->data, input->data, &ctx);
    } else if (nblocks > 1) {
	unsigned int nleft;

	for (blockno = 0; blockno < nblocks - 2; blockno++) {
	    xorblock(tmp, input->data + blockno * BLOCK_SIZE);
	    enc(tmp2, tmp, &ctx);
	    memcpy(output->data + blockno * BLOCK_SIZE, tmp2, BLOCK_SIZE);

	    /* Set up for next block.  */
	    memcpy(tmp, tmp2, BLOCK_SIZE);
	}
	/* Do final CTS step for last two blocks (the second of which
	   may or may not be incomplete).  */
	xorblock(tmp, input->data + (nblocks - 2) * BLOCK_SIZE);
	enc(tmp2, tmp, &ctx);
	nleft = input->length - (nblocks - 1) * BLOCK_SIZE;
	memcpy(output->data + (nblocks - 1) * BLOCK_SIZE, tmp2, nleft);
	memcpy(tmp, tmp2, BLOCK_SIZE);

	memset(tmp3, 0, sizeof(tmp3));
	memcpy(tmp3, input->data + (nblocks - 1) * BLOCK_SIZE, nleft);
	xorblock(tmp, tmp3);
	enc(tmp2, tmp, &ctx);
	memcpy(output->data + (nblocks - 2) * BLOCK_SIZE, tmp2, BLOCK_SIZE);
	if (ivec)
	    memcpy(ivec->data, tmp2, BLOCK_SIZE);
    }

    return 0;
}
Пример #2
0
//设置加密密钥
BOOL CEncrypt::SetEncryptKey(const char* szEncryKey, uint16_t nKeyLen)
{
	assert(szEncryKey);
	assert(nKeyLen >= MIN_ENCRYPT_KEY_SIZE);

	if(NULL == szEncryKey || nKeyLen < MIN_ENCRYPT_KEY_SIZE)
		return FALSE;

	rc6_set_key((unsigned long *)szEncryKey, nKeyLen*8, &m_stRc6Ctx);
	aes_enc_key((unsigned char *)szEncryKey, nKeyLen, &m_stAesEncryCtx);
	aes_dec_key((unsigned char *)szEncryKey, nKeyLen, &m_stAesDecryCtx);

	return TRUE;
}
Пример #3
0
static void init ()
{
    unsigned int i, j, r;

    srand(42);
    for (i = 0; i < 16; i++)
	key[i] = 0xff & rand();
    memset(test_case, 0, sizeof(test_case));
    for (i = 0; i < NTESTS; i++)
	for (j = 0; j < test_case_len[i]; j++) {
	    test_case[i].input[j] = 0xff & rand();
	}

    r = aes_enc_key (key, sizeof(key), &ctx);
    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
    r = aes_dec_key (key, sizeof(key), &dctx);
    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
}
Пример #4
0
static void fips_test ()
{
    static const unsigned char fipskey[16] = {
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
    };
    static const unsigned char input[16] = {
	0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
	0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
    };
    static const unsigned char expected[16] = {
	0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
	0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a,
    };
    unsigned char output[16];
    unsigned char tmp[16];
    aes_ctx fipsctx;
    int r;

    printf ("FIPS test:\nkey:");
    hexdump (fipskey, 16);
    printf ("\ninput:");
    hexdump (input, 16);
    r = aes_enc_key (fipskey, sizeof(fipskey), &fipsctx);
    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
    r = aes_enc_blk (input, output, &fipsctx);
    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
    printf ("\noutput:");
    hexdump (output, 16);
    printf ("\n");
    if (memcmp(expected, output, 16))
	fprintf(stderr, "wrong results!!!\n"), exit (1);
    r = aes_dec_key (fipskey, sizeof(fipskey), &fipsctx);
    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
    r = aes_dec_blk (output, tmp, &fipsctx);
    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
    if (memcmp(input, tmp, 16))
	fprintf(stderr, "decryption failed!!\n"), exit(1);
    printf ("ok.\n\n");
}
Пример #5
0
static krb5_error_code
krb5int_aes_encrypt_iov(const krb5_keyblock *key,
		        const krb5_data *ivec,
		        krb5_crypto_iov *data,
		        size_t num_data)
{
    aes_ctx ctx;
    char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE];
    int nblocks = 0, blockno;
    size_t input_length, i;
    struct iov_block_state input_pos, output_pos;

    if (aes_enc_key(key->contents, key->length, &ctx) != aes_good)
	abort();

    if (ivec != NULL)
	memcpy(tmp, ivec->data, BLOCK_SIZE);
    else
	memset(tmp, 0, BLOCK_SIZE);

    for (i = 0, input_length = 0; i < num_data; i++) {
	krb5_crypto_iov *iov = &data[i];

	if (ENCRYPT_IOV(iov))
	    input_length += iov->data.length;
    }

    IOV_BLOCK_STATE_INIT(&input_pos);
    IOV_BLOCK_STATE_INIT(&output_pos);

    nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
    if (nblocks == 1) {
	krb5int_c_iov_get_block((unsigned char *)tmp, BLOCK_SIZE,
				data, num_data, &input_pos);
	enc(tmp2, tmp, &ctx);
	krb5int_c_iov_put_block(data, num_data, (unsigned char *)tmp2,
				BLOCK_SIZE, &output_pos);
    } else if (nblocks > 1) {
	char blockN2[BLOCK_SIZE];   /* second last */
	char blockN1[BLOCK_SIZE];   /* last block */

	for (blockno = 0; blockno < nblocks - 2; blockno++) {
	    char blockN[BLOCK_SIZE];

	    krb5int_c_iov_get_block((unsigned char *)blockN, BLOCK_SIZE, data, num_data, &input_pos);
	    xorblock(tmp, blockN);
	    enc(tmp2, tmp, &ctx);
	    krb5int_c_iov_put_block(data, num_data, (unsigned char *)tmp2, BLOCK_SIZE, &output_pos);

	    /* Set up for next block.  */
	    memcpy(tmp, tmp2, BLOCK_SIZE);
	}

	/* Do final CTS step for last two blocks (the second of which
	   may or may not be incomplete).  */

	/* First, get the last two blocks */
	memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */
	krb5int_c_iov_get_block((unsigned char *)blockN2, BLOCK_SIZE, data, num_data, &input_pos);
	krb5int_c_iov_get_block((unsigned char *)blockN1, BLOCK_SIZE, data, num_data, &input_pos);

	/* Encrypt second last block */
	xorblock(tmp, blockN2);
	enc(tmp2, tmp, &ctx);
	memcpy(blockN2, tmp2, BLOCK_SIZE); /* blockN2 now contains first block */
	memcpy(tmp, tmp2, BLOCK_SIZE);

	/* Encrypt last block */
	xorblock(tmp, blockN1);
	enc(tmp2, tmp, &ctx);
	memcpy(blockN1, tmp2, BLOCK_SIZE);

	/* Put the last two blocks back into the iovec (reverse order) */
	krb5int_c_iov_put_block(data, num_data, (unsigned char *)blockN1, BLOCK_SIZE, &output_pos);
	krb5int_c_iov_put_block(data, num_data, (unsigned char *)blockN2, BLOCK_SIZE, &output_pos);

	if (ivec != NULL)
	    memcpy(ivec->data, blockN1, BLOCK_SIZE);
    }

    return 0;
}
Пример #6
0
int main(int argc, char *argv[])
{   FILE        *fin = 0, *fout = 0;
    char        *cp, ch, key[32];
    int         i, by, key_len, err = 0;
    aes_ctx     ctx[1];

    if(argc != 5 || toupper(*argv[3]) != 'D' && toupper(*argv[3]) != 'E')
    {
        printf("usage: aesxam in_filename out_filename [d/e] key_in_hex\n");
        err = -1; goto exit;
    }

    ctx->n_rnd = 0; // ensure all flags are initially set to zero
    ctx->n_blk = 0;
    cp = argv[4];   // this is a pointer to the hexadecimal key digits
    i = 0;          // this is a count for the input digits processed

    while(i < 64 && *cp)        // the maximum key length is 32 bytes and
    {                           // hence at most 64 hexadecimal digits
        ch = toupper(*cp++);    // process a hexadecimal digit
        if(ch >= '0' && ch <= '9')
            by = (by << 4) + ch - '0';
        else if(ch >= 'A' && ch <= 'F')
            by = (by << 4) + ch - 'A' + 10;
        else                    // error if not hexadecimal
        {
            printf("key must be in hexadecimal notation\n");
            err = -2; goto exit;
        }

        // store a key byte for each pair of hexadecimal digits
        if(i++ & 1)
            key[i / 2 - 1] = by & 0xff;
    }

    if(*cp)
    {
        printf("The key value is too long\n");
        err = -3; goto exit;
    }
    else if(i < 32 || (i & 15))
    {
        printf("The key length must be 32, 48 or 64 hexadecimal digits\n");
        err = -4; goto exit;
    }

    key_len = i / 2;

    if(!(fin = fopen(argv[1], "rb")))   // try to open the input file
    {
        printf("The input file: %s could not be opened\n", argv[1]);
        err = -5; goto exit;
    }

    if(!(fout = fopen(argv[2], "wb")))  // try to open the output file
    {
        printf("The input file: %s could not be opened\n", argv[1]);
        err = -6; goto exit;
    }

    if(toupper(*argv[3]) == 'E') // encryption in Cipher Block Chaining mode
    {
        aes_enc_key(key, key_len, ctx);

        err = encfile(fin, fout, ctx, argv[1], argv[2]);
    }
    else                         // decryption in Cipher Block Chaining mode
    {
        aes_dec_key(key, key_len, ctx);

        err = decfile(fin, fout, ctx, argv[1], argv[2]);
    }
exit:
    if(err == READ_ERROR)
        printf("Error reading from input file: %s\n", argv[1]);

    if(err == WRITE_ERROR)
        printf("Error writing to output file: %s\n", argv[2]);

    if(fout)
        fclose(fout);

    if(fin)
        fclose(fin);

    return err;
}
Пример #7
0
ret_type CCM_init(
    const unsigned char key[], const unsigned long key_len, /* the key value to be used             */
    const unsigned char nonce[],                            /* the nonce value                      */
    const unsigned char auth[], const unsigned long ad_len, /* the additional authenticated data    */
    const mlen_type msg_len,                                /* message data length                  */
    const unsigned long auth_field_len,                     /* the authentication field length      */
    CCM_ctx ctx[1])                                         /* the CCM context                      */
{   aes_32t    cnt;

    if(aes_enc_key(key, key_len, ctx->aes) == aes_bad)
        return CCM_bad_key;                 /* bad key value                        */

    if(auth_field_len < 2 || auth_field_len > 16 || (auth_field_len & 1))
        return CCM_bad_auth_field_length;   /* illegal authentication field size    */

    if(ad_len >= 65536ul - 256ul)
        return CCM_bad_auth_data_length;    /* too much added authetication data    */

    /* save length values and compile the blocks for the running CBC and CTR values */
    ctx->md_len = msg_len;
    ctx->af_len = auth_field_len;

#ifndef LONG_MESSAGES
    ctx->blk[0] = (ctx->md_len & 0xff000000 ? 3 : 
                   ctx->md_len & 0xffff0000 ? 2 : 1);
#else
    ctx->blk[0] = (ctx->md_len & 0xff00000000000000 ? 7 : 
                   ctx->md_len & 0xffff000000000000 ? 6 : 
                   ctx->md_len & 0xffffff0000000000 ? 5 : 
                   ctx->md_len & 0xffffffff00000000 ? 4 : 
                   ctx->md_len & 0xffffffffff000000 ? 3 : 
                   ctx->md_len & 0xffffffffffff0000 ? 2 : 1);
#endif

    /* move the nonce into the block    */
    for(cnt = 0; cnt < (aes_32t)BLOCK_SIZE - ctx->blk[0] - 2; ++cnt)
        ctx->blk[cnt + 1] = nonce[cnt];

    set_ctr(ctx, ctx->md_len);              /* set message length value     */
    memcpy(ctx->cbc, ctx->blk, BLOCK_SIZE); /* and copy into running CBC    */
    ctx->cbc[0] |= (ad_len ? 0x40 : 0) + ((auth_field_len - 2) << 2);
    set_ctr(ctx, 1);                        /* initial counter value = 1    */

    aes_enc_blk(ctx->cbc, ctx->cbc, ctx->aes);  /* encrypt the cbc block    */
    aes_enc_blk(ctx->blk, ctx->sii, ctx->aes);  /* encrypt counter block    */

    if(ad_len)              /* if there is additional authentication data   */
    {
        cnt = 0;            /* set the two byte length field for the data   */
        ctx->cbc[0] ^= (aes_08t)(ad_len >> 8);
        ctx->cbc[1] ^= (aes_08t) ad_len;
        
        while(cnt < ad_len) /* perform the CBC calculation on the data      */
        {   
            /* xor data into the running CBC block                          */
            ctx->cbc[(cnt + 2) & BLOCK_MASK] ^= auth[cnt];

            /* if CBC block is full or at end of the authentication data    */
            if(!((++cnt + 2) & BLOCK_MASK) || cnt == ad_len)
                aes_enc_blk(ctx->cbc, ctx->cbc, ctx->aes); 
        }
    }

    ctx->cnt = 0;
    return CCM_ok;
}