Esempio n. 1
0
/* Diversifies key using random UserKey Material
 * Implements RFC 4357 p 6.5 key diversification algorithm 
 * 
 * inputKey - 32byte key to be diversified
 * ukm - 8byte user key material
 * outputKey - 32byte buffer to store diversified key 
 *
 */
void keyDiversifyCryptoPro(gost_ctx *ctx,const unsigned char *inputKey, const unsigned char *ukm, unsigned char *outputKey)
	{

	u4 k,s1,s2;
	int i,j,mask;
	unsigned char S[8];
	memcpy(outputKey,inputKey,32);
	for (i=0;i<8;i++) 
		{
		/* Make array of integers from key */
		/* Compute IV S*/
		s1=0,s2=0;
		for (j=0,mask=1;j<8;j++,mask<<=1) 
			{
			k=((u4)outputKey[4*j])|(outputKey[4*j+1]<<8)|
				(outputKey[4*j+2]<<16)|(outputKey[4*j+3]<<24);
			if (mask & ukm[i]) 
				{
				s1+=k;
				}
			else 
				{
				s2+=k;
				}
			}
		S[0]=(unsigned char)(s1&0xff);
		S[1]=(unsigned char)((s1>>8)&0xff);
		S[2]=(unsigned char)((s1>>16)&0xff);
		S[3]=(unsigned char)((s1>>24)&0xff); 
		S[4]=(unsigned char)(s2&0xff);
		S[5]=(unsigned char)((s2>>8)&0xff);
		S[6]=(unsigned char)((s2>>16)&0xff);
		S[7]=(unsigned char)((s2>>24)&0xff); 
		gost_key(ctx,outputKey);
		gost_enc_cfb(ctx,S,outputKey,outputKey,4);
		}
	}	
Esempio n. 2
0
static int dstu_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                                 const unsigned char *in, size_t inl)
{
    size_t to_use, i, blocks;
    gost_ctx *gctx = ctx->cipher_data;
    unsigned char tmpiv[DSTU_CIPHER_BLOCK_SIZE], *out_start = out;

    if ((!inl) && (!in))
        return 0;

    if ((!inl) || (!in))
        return -1;

    if (ctx->num) {
        to_use = ((size_t)(ctx->num) < inl) ? (size_t)(ctx->num) : inl;

        for (i = 0; i < to_use; i++) {
            if (ctx->encrypt) {
                *out = *in ^ ctx->buf[DSTU_CIPHER_BLOCK_SIZE - ctx->num + i];
                ctx->iv[DSTU_CIPHER_BLOCK_SIZE - ctx->num + i] = *out;
            } else {
                ctx->iv[DSTU_CIPHER_BLOCK_SIZE - ctx->num + i] = *in;
                *out = *in ^ ctx->buf[DSTU_CIPHER_BLOCK_SIZE - ctx->num + i];
            }
            in++;
            out++;
        }

        ctx->num -= to_use;
        inl -= to_use;

        if (!ctx->num)
            gostcrypt(gctx, ctx->iv, ctx->buf);
    }

    if (inl) {
        blocks = inl >> 3;

        if (blocks) {
            if (ctx->encrypt) {
                gost_enc_cfb(gctx, ctx->iv, in, out, blocks);
                memcpy(ctx->iv,
                       out + (blocks * DSTU_CIPHER_BLOCK_SIZE) -
                       DSTU_CIPHER_BLOCK_SIZE, DSTU_CIPHER_BLOCK_SIZE);
            } else {
                memcpy(tmpiv, ctx->iv, DSTU_CIPHER_BLOCK_SIZE);
                memcpy(ctx->iv,
                       in + (blocks * DSTU_CIPHER_BLOCK_SIZE) -
                       DSTU_CIPHER_BLOCK_SIZE, DSTU_CIPHER_BLOCK_SIZE);
                gost_dec_cfb(gctx, tmpiv, in, out, blocks);
            }
            gostcrypt(gctx, ctx->iv, ctx->buf);

            out += blocks * DSTU_CIPHER_BLOCK_SIZE;
            in += blocks * DSTU_CIPHER_BLOCK_SIZE;
            inl -= blocks * DSTU_CIPHER_BLOCK_SIZE;
        }
    }

    if (inl) {
        for (i = 0; i < inl; i++) {
            if (ctx->encrypt) {
                *out = *in ^ ctx->buf[i];
                ctx->iv[i] = *out;
            } else {
                ctx->iv[i] = *in;
                *out = *in ^ ctx->buf[i];
            }
            in++;
            out++;
        }

        ctx->num = DSTU_CIPHER_BLOCK_SIZE - inl;
    }

    return out - out_start;
}