⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eng_padlock.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
📖 第 1 页 / 共 3 页
字号:
			if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE ||			    EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE ||			    enc)				AES_set_encrypt_key(key, key_len, &cdata->ks);			else				AES_set_decrypt_key(key, key_len, &cdata->ks);#ifndef AES_ASM			/* OpenSSL C functions use byte-swapped extended key. */			padlock_bswapl(&cdata->ks);#endif			cdata->cword.b.keygen = 1;			break;		default:			/* ERROR */			return 0;	}	/*	 * This is done to cover for cases when user reuses the	 * context for new key. The catch is that if we don't do	 * this, padlock_eas_cipher might proceed with old key...	 */	padlock_reload_key ();	return 1;}/*  * Simplified version of padlock_aes_cipher() used when * 1) both input and output buffers are at aligned addresses. * or when * 2) running on a newer CPU that doesn't require aligned buffers. */static intpadlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,		const unsigned char *in_arg, size_t nbytes){	struct padlock_cipher_data *cdata;	void  *iv;	cdata = ALIGNED_CIPHER_DATA(ctx);	padlock_verify_context(cdata);	switch (EVP_CIPHER_CTX_mode(ctx)) {	case EVP_CIPH_ECB_MODE:		padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);		break;	case EVP_CIPH_CBC_MODE:		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);		iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);		break;	case EVP_CIPH_CFB_MODE:		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);		iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);		break;	case EVP_CIPH_OFB_MODE:		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);		padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);		memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);		break;	default:		return 0;	}	memset(cdata->iv, 0, AES_BLOCK_SIZE);	return 1;}#ifndef  PADLOCK_CHUNK# define PADLOCK_CHUNK	512	/* Must be a power of 2 larger than 16 */#endif#if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)# error "insane PADLOCK_CHUNK..."#endif/* Re-align the arguments to 16-Bytes boundaries and run the    encryption function itself. This function is not AES-specific. */static intpadlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,		   const unsigned char *in_arg, size_t nbytes){	struct padlock_cipher_data *cdata;	const  void *inp;	unsigned char  *out;	void  *iv;	int    inp_misaligned, out_misaligned, realign_in_loop;	size_t chunk, allocated=0;	/* ctx->num is maintained in byte-oriented modes,	   such as CFB and OFB... */	if ((chunk = ctx->num)) { /* borrow chunk variable */		unsigned char *ivp=ctx->iv;		switch (EVP_CIPHER_CTX_mode(ctx)) {		case EVP_CIPH_CFB_MODE:			if (chunk >= AES_BLOCK_SIZE)				return 0; /* bogus value */			if (ctx->encrypt)				while (chunk<AES_BLOCK_SIZE && nbytes!=0) {					ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];					chunk++, nbytes--;				}			else	while (chunk<AES_BLOCK_SIZE && nbytes!=0) {					unsigned char c = *(in_arg++);					*(out_arg++) = c ^ ivp[chunk];					ivp[chunk++] = c, nbytes--;				}			ctx->num = chunk%AES_BLOCK_SIZE;			break;		case EVP_CIPH_OFB_MODE:			if (chunk >= AES_BLOCK_SIZE)				return 0; /* bogus value */			while (chunk<AES_BLOCK_SIZE && nbytes!=0) {				*(out_arg++) = *(in_arg++) ^ ivp[chunk];				chunk++, nbytes--;			}			ctx->num = chunk%AES_BLOCK_SIZE;			break;		}	}	if (nbytes == 0)		return 1;#if 0	if (nbytes % AES_BLOCK_SIZE)		return 0; /* are we expected to do tail processing? */#else	/* nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC	   modes and arbitrary value in byte-oriented modes, such as	   CFB and OFB... */#endif	/* VIA promises CPUs that won't require alignment in the future.	   For now padlock_aes_align_required is initialized to 1 and	   the condition is never met... */	/* C7 core is capable to manage unaligned input in non-ECB[!]	   mode, but performance penalties appear to be approximately	   same as for software alignment below or ~3x. They promise to	   improve it in the future, but for now we can just as well	   pretend that it can only handle aligned input... */	if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0)		return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);	inp_misaligned = (((size_t)in_arg) & 0x0F);	out_misaligned = (((size_t)out_arg) & 0x0F);	/* Note that even if output is aligned and input not,	 * I still prefer to loop instead of copy the whole	 * input and then encrypt in one stroke. This is done	 * in order to improve L1 cache utilization... */	realign_in_loop = out_misaligned|inp_misaligned;	if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0)		return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);	/* this takes one "if" out of the loops */	chunk  = nbytes;	chunk %= PADLOCK_CHUNK;	if (chunk==0) chunk = PADLOCK_CHUNK;	if (out_misaligned) {		/* optmize for small input */		allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);		out = alloca(0x10 + allocated);		out = NEAREST_ALIGNED(out);	}	else		out = out_arg;	cdata = ALIGNED_CIPHER_DATA(ctx);	padlock_verify_context(cdata);	switch (EVP_CIPHER_CTX_mode(ctx)) {	case EVP_CIPH_ECB_MODE:		do	{			if (inp_misaligned)				inp = padlock_memcpy(out, in_arg, chunk);			else				inp = in_arg;			in_arg += chunk;			padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);			if (out_misaligned)				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;			else				out     = out_arg+=chunk;			nbytes -= chunk;			chunk   = PADLOCK_CHUNK;		} while (nbytes);		break;	case EVP_CIPH_CBC_MODE:		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);		goto cbc_shortcut;		do	{			if (iv != cdata->iv)				memcpy(cdata->iv, iv, AES_BLOCK_SIZE);			chunk = PADLOCK_CHUNK;		cbc_shortcut: /* optimize for small input */			if (inp_misaligned)				inp = padlock_memcpy(out, in_arg, chunk);			else				inp = in_arg;			in_arg += chunk;			iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);			if (out_misaligned)				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;			else				out     = out_arg+=chunk;		} while (nbytes -= chunk);		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);		break;	case EVP_CIPH_CFB_MODE:		memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE);		chunk &= ~(AES_BLOCK_SIZE-1);		if (chunk)	goto cfb_shortcut;		else		goto cfb_skiploop;		do	{			if (iv != cdata->iv)				memcpy(cdata->iv, iv, AES_BLOCK_SIZE);			chunk = PADLOCK_CHUNK;		cfb_shortcut: /* optimize for small input */			if (inp_misaligned)				inp = padlock_memcpy(out, in_arg, chunk);			else				inp = in_arg;			in_arg += chunk;			iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);			if (out_misaligned)				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;			else				out     = out_arg+=chunk;			nbytes -= chunk;		} while (nbytes >= AES_BLOCK_SIZE);		cfb_skiploop:		if (nbytes) {			unsigned char *ivp = cdata->iv;			if (iv != ivp) {				memcpy(ivp, iv, AES_BLOCK_SIZE);				iv = ivp;			}			ctx->num = nbytes;			if (cdata->cword.b.encdec) {				cdata->cword.b.encdec=0;				padlock_reload_key();				padlock_xcrypt_ecb(1,cdata,ivp,ivp);				cdata->cword.b.encdec=1;				padlock_reload_key();				while(nbytes) {					unsigned char c = *(in_arg++);					*(out_arg++) = c ^ *ivp;					*(ivp++) = c, nbytes--;				}			}			else {	padlock_reload_key();				padlock_xcrypt_ecb(1,cdata,ivp,ivp);				padlock_reload_key();				while (nbytes) {					*ivp = *(out_arg++) = *(in_arg++) ^ *ivp;					ivp++, nbytes--;				}			}		}		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);		break;	case EVP_CIPH_OFB_MODE:		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);		chunk &= ~(AES_BLOCK_SIZE-1);		if (chunk) do	{			if (inp_misaligned)				inp = padlock_memcpy(out, in_arg, chunk);			else				inp = in_arg;			in_arg += chunk;			padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);			if (out_misaligned)				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;			else				out     = out_arg+=chunk;			nbytes -= chunk;			chunk   = PADLOCK_CHUNK;		} while (nbytes >= AES_BLOCK_SIZE);		if (nbytes) {			unsigned char *ivp = cdata->iv;			ctx->num = nbytes;			padlock_reload_key();	/* empirically found */			padlock_xcrypt_ecb(1,cdata,ivp,ivp);			padlock_reload_key();	/* empirically found */			while (nbytes) {				*(out_arg++) = *(in_arg++) ^ *ivp;				ivp++, nbytes--;			}		}		memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);		break;	default:		return 0;	}	/* Clean the realign buffer if it was used */	if (out_misaligned) {		volatile unsigned long *p=(void *)out;		size_t   n = allocated/sizeof(*p);		while (n--) *p++=0;	}	memset(cdata->iv, 0, AES_BLOCK_SIZE);	return 1;}#endif /* OPENSSL_NO_AES *//* ===== Random Number Generator ===== *//* * This code is not engaged. The reason is that it does not comply * with recommendations for VIA RNG usage for secure applications * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it * provide meaningful error control... *//* Wrapper that provides an interface between the API and    the raw PadLock RNG */static intpadlock_rand_bytes(unsigned char *output, int count){	unsigned int eax, buf;	while (count >= 8) {		eax = padlock_xstore(output, 0);		if (!(eax&(1<<6)))	return 0; /* RNG disabled */		/* this ---vv--- covers DC bias, Raw Bits and String Filter */		if (eax&(0x1F<<10))	return 0;		if ((eax&0x1F)==0)	continue; /* no data, retry... */		if ((eax&0x1F)!=8)	return 0; /* fatal failure...  */		output += 8;		count  -= 8;	}	while (count > 0) {		eax = padlock_xstore(&buf, 3);		if (!(eax&(1<<6)))	return 0; /* RNG disabled */		/* this ---vv--- covers DC bias, Raw Bits and String Filter */		if (eax&(0x1F<<10))	return 0;		if ((eax&0x1F)==0)	continue; /* no data, retry... */		if ((eax&0x1F)!=1)	return 0; /* fatal failure...  */		*output++ = (unsigned char)buf;		count--;	}	*(volatile unsigned int *)&buf=0;	return 1;}/* Dummy but necessary function */static intpadlock_rand_status(void){	return 1;}/* Prepare structure for registration */static RAND_METHOD padlock_rand = {	NULL,			/* seed */	padlock_rand_bytes,	/* bytes */	NULL,			/* cleanup */	NULL,			/* add */	padlock_rand_bytes,	/* pseudorand */	padlock_rand_status,	/* rand status */};#endif /* COMPILE_HW_PADLOCK */#endif /* !OPENSSL_NO_HW_PADLOCK */#endif /* !OPENSSL_NO_HW */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -