scapi.c

来自「eCos操作系统源码」· C语言 代码 · 共 821 行 · 第 1/2 页

C
821
字号
#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL){  int   rval       = SNMPERR_SUCCESS;#ifdef USE_OPENSSL   EVP_MD *hash(void);  HMAC_CTX *c = NULL; #endif  DEBUGTRACE;  if (hashtype == NULL || hashtypelen < 0 || buf == NULL ||      buf_len < 0 || MAC == NULL ||  MAC_len == NULL ||      (int)(*MAC_len) < sc_get_properlength(hashtype, hashtypelen))    return (SNMPERR_GENERR);#ifdef USE_OPENSSL   /*   * Determine transform type.   */  c = malloc(sizeof(HMAC_CTX));  if (c == NULL)    return (SNMPERR_GENERR);  if (ISTRANSFORM(hashtype, HMACMD5Auth)) {    EVP_DigestInit(&c->md_ctx, (const EVP_MD *) EVP_md5());  }  else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {    EVP_DigestInit(&c->md_ctx, (const EVP_MD *) EVP_sha1());  }  else {    return(SNMPERR_GENERR);  }  EVP_DigestUpdate(&c->md_ctx, buf, buf_len);  EVP_DigestFinal(&(c->md_ctx), MAC, MAC_len);  free(c);  return (rval);#else /* USE_INTERNAL_MD5 */  if (MDchecksum(buf, buf_len, MAC, *MAC_len)) {    return SNMPERR_GENERR;  }  if (*MAC_len > 16)    *MAC_len = 16;  return (rval);#endif /* USE_OPENSSL */}#else /* !defined(USE_OPENSSL) && !defined(USE_INTERNAL_MD5) */_SCAPI_NOT_CONFIGURED#endif /* !defined(USE_OPENSSL) && !defined(USE_INTERNAL_MD5) *//*******************************************************************-o-****** * sc_check_keyed_hash * * Parameters: *	 authtype	Transform type of authentication hash. *	*key		Key bits in a string of bytes. *	 keylen		Length of key in bytes. *	*message	Message for which to check the hash. *	 msglen		Length of message. *	*MAC		Given hash. *	 maclen		Length of given hash; indicates truncation if it is *				shorter than the normal size of output for *				given hash transform. * Returns: *	SNMPERR_SUCCESS		Success. *	SNMP_SC_GENERAL_FAILURE	Any error * * * Check the hash given in MAC against the hash of message.  If the length * of MAC is less than the length of the transform hash output, only maclen * bytes are compared.  The length of MAC cannot be greater than the * length of the hash transform output. */intsc_check_keyed_hash(	oid	*authtype,	size_t authtypelen,			u_char	*key,		u_int keylen,			u_char	*message,	u_int msglen,			u_char	*MAC,		u_int maclen)#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL){	int		 rval	 = SNMPERR_SUCCESS;	size_t		 buf_len = SNMP_MAXBUF_SMALL;	u_char		 buf[SNMP_MAXBUF_SMALL];        DEBUGTRACE;#ifdef SNMP_TESTING_CODE{ int i; DEBUGMSG(("scapi", "sc_check_keyed_hash():    key=0x")); for(i=0; i< keylen; i++)   DEBUGMSG(("scapi", "%02x", key[i] & 0xff)); DEBUGMSG(("scapi"," (%d)\n", keylen));}#endif /* SNMP_TESTING_CODE */	/*	 * Sanity check.	 */	if ( !authtype || !key || !message || !MAC 		|| (keylen<=0) || (msglen<=0) || (maclen<=0)		|| (authtypelen != USM_LENGTH_OID_TRANSFORM) )	{		QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);	}	/* 	 * Generate a full hash of the message, then compare	 * the result with the given MAC which may shorter than	 * the full hash length.	 */	rval = sc_generate_keyed_hash(	authtype, authtypelen,					key, keylen,					message, msglen,					buf, &buf_len);	QUITFUN(rval, sc_check_keyed_hash_quit);	if (maclen > msglen) {		QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);	} else if ( memcmp(buf, MAC, maclen) != 0 ) {		QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);	}sc_check_keyed_hash_quit:	SNMP_ZERO(buf, SNMP_MAXBUF_SMALL);	return rval;}  /* end sc_check_keyed_hash() */#else_SCAPI_NOT_CONFIGURED#endif	/* USE_INTERNAL_MD5 *//*******************************************************************-o-****** * sc_encrypt * * Parameters: *	 privtype	Type of privacy cryptographic transform. *	*key		Key bits for crypting. *	 keylen		Length of key (buffer) in bytes. *	*iv		IV bits for crypting. *	 ivlen		Length of iv (buffer) in bytes. *	*plaintext	Plaintext to crypt. *	 ptlen		Length of plaintext. *	*ciphertext	Ciphertext to crypt. *	*ctlen		Length of ciphertext. *       * Returns: *	SNMPERR_SUCCESS			Success. *	SNMPERR_SC_NOT_CONFIGURED	Encryption is not supported. *	SNMPERR_SC_GENERAL_FAILURE	Any other error * * * Encrypt plaintext into ciphertext using key and iv. * * ctlen contains actual number of crypted bytes in ciphertext upon * successful return. */intsc_encrypt(	oid    *privtype,	size_t privtypelen,		u_char *key,		u_int  keylen,		u_char *iv,		u_int  ivlen,		u_char *plaintext,	u_int  ptlen,		u_char *ciphertext,	size_t *ctlen)#if defined(USE_OPENSSL) {	int		rval	= SNMPERR_SUCCESS;	u_int		transform,			properlength,			properlength_iv;	u_char		pad_block[32];  /* bigger than anything I need */	u_char          my_iv[32];      /* ditto */	int		pad, plast, pad_size;	des_key_schedule key_sch;	des_cblock      key_struct;        DEBUGTRACE;	/*	 * Sanity check.	 */#if	!defined(SCAPI_AUTHPRIV)		return SNMPERR_SC_NOT_CONFIGURED;#endif	if ( !privtype || !key || !iv || !plaintext || !ciphertext || !ctlen		|| (keylen<=0) || (ivlen<=0) || (ptlen<=0) || (*ctlen<=0)		|| (privtypelen != USM_LENGTH_OID_TRANSFORM) )	{		QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);	}	else if ( ptlen >= *ctlen) { 		QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);	}#ifdef SNMP_TESTING_CODE{        char buf[SNMP_MAXBUF];	sprint_hexstring(buf, iv, ivlen);        DEBUGMSGTL(("scapi", "encrypt: IV: %s/ ", buf));	sprint_hexstring(buf, key, keylen);        DEBUGMSG(("scapi","%s\n", buf));	sprint_hexstring(buf, plaintext, 16);        DEBUGMSGTL(("scapi","encrypt: string: %s\n", buf));}#endif /* SNMP_TESTING_CODE */	/*	 * Determine privacy transform.	 */	if ( ISTRANSFORM(privtype, DESPriv) ) {		properlength	= BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);		properlength_iv	= BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);		pad_size = properlength;	} else {		QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);	}	if ( (keylen<properlength) || (ivlen<properlength_iv) ) {		QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);	}	else if ( (keylen<properlength) || (ivlen<properlength_iv) ) {		QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);	}/* now calculate the padding needed */	pad = pad_size - (ptlen % pad_size);	if (ptlen + pad > *ctlen) { 		QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); /* not enough space */	}	memset(pad_block, 0, sizeof(pad_block));	plast = (int) ptlen - (pad_size - pad);	if (pad > 0)  /* copy data into pad block if needed */		memcpy( pad_block, plaintext + plast, pad_size - pad);	memset(&pad_block[pad_size-pad], pad, pad); /* filling in padblock */	memset(my_iv, 0, sizeof(my_iv));	if ( ISTRANSFORM(privtype, DESPriv) ) {                memcpy(key_struct, key, sizeof(key_struct));		(void) des_key_sched(&key_struct, key_sch);		memcpy(my_iv, iv, ivlen);		/* encrypt the data */		des_ncbc_encrypt(plaintext, ciphertext, plast, key_sch, 				 (des_cblock *) &my_iv, DES_ENCRYPT);		/* then encrypt the pad block */		des_ncbc_encrypt(pad_block, ciphertext+plast, pad_size, 				 key_sch, (des_cblock *)&my_iv, DES_ENCRYPT);		*ctlen = plast + pad_size;	}sc_encrypt_quit:	/* clear memory just in case */	memset(my_iv, 0, sizeof(my_iv));	memset(pad_block, 0, sizeof(pad_block));	memset(key_struct, 0, sizeof(key_struct));	memset(key_sch, 0, sizeof(key_sch));	return rval;}  /* end sc_encrypt() */#else{#	if USE_INTERNAL_MD5	{		DEBUGMSGTL(("scapi","Encrypt function not defined.\n"));		return SNMPERR_SC_GENERAL_FAILURE;	}#	else		_SCAPI_NOT_CONFIGURED#	endif /* USE_INTERNAL_MD5 */			}#endif							/* *//*******************************************************************-o-****** * sc_decrypt * * Parameters: *	 privtype *	*key *	 keylen *	*iv *	 ivlen *	*ciphertext *	 ctlen *	*plaintext *	*ptlen *       * Returns: *	SNMPERR_SUCCESS			Success. *	SNMPERR_SC_NOT_CONFIGURED	Encryption is not supported. *      SNMPERR_SC_GENERAL_FAILURE      Any other error * * * Decrypt ciphertext into plaintext using key and iv. * * ptlen contains actual number of plaintext bytes in plaintext upon * successful return. */intsc_decrypt(	oid    *privtype,	size_t privtypelen,		u_char *key,		u_int  keylen,		u_char *iv,		u_int  ivlen,		u_char *ciphertext,	u_int  ctlen,		u_char *plaintext,	size_t *ptlen)#ifdef USE_OPENSSL{	int rval = SNMPERR_SUCCESS;	int i, j; 	u_char *my_iv[32];	des_key_schedule key_sch;	des_cblock  key_struct;	u_int		properlength,			properlength_iv;        DEBUGTRACE;	if ( !privtype || !key || !iv || !plaintext || !ciphertext || !ptlen		|| (ctlen<=0) || (*ptlen<=0) || (*ptlen < ctlen)		|| (privtypelen != USM_LENGTH_OID_TRANSFORM) )	{		QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);	}#ifdef SNMP_TESTING_CODE{        char buf[SNMP_MAXBUF];	sprint_hexstring(buf, iv, ivlen);        DEBUGMSGTL(("scapi", "decrypt: IV: %s/ ", buf));	sprint_hexstring(buf, key, keylen);        DEBUGMSG(("scapi","%s\n", buf));}#endif /* SNMP_TESTING_CODE */	/*	 * Determine privacy transform.	 */	if ( ISTRANSFORM(privtype, DESPriv) ) {		properlength	= BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);		properlength_iv	= BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);	} else {		QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);	}	if ( (keylen<properlength) || (ivlen<properlength_iv) ) {		QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);	}		memset(my_iv, 0, sizeof(my_iv));	if (ISTRANSFORM(privtype, DESPriv)) {                memcpy(key_struct, key, sizeof(key_struct));		(void) des_key_sched(&key_struct, key_sch);			memcpy(my_iv, iv, ivlen);		des_cbc_encrypt(ciphertext, plaintext, ctlen, key_sch, 				(des_cblock *) &my_iv, DES_DECRYPT);	}/* exit cond */sc_decrypt_quit:	memset(key_sch, 0, sizeof(key_sch));	memset(key_struct, 0, sizeof(key_struct));	memset(my_iv, 0, sizeof(my_iv));	return rval;}  #else   /* USE OPEN_SSL */{#if	!defined(SCAPI_AUTHPRIV)		return SNMPERR_SC_NOT_CONFIGURED;#else#	if USE_INTERNAL_MD5	{		DEBUGMSGTL(("scapi","Decryption function not defined.\n"));		return SNMPERR_SC_GENERAL_FAILURE;	}#	else		_SCAPI_NOT_CONFIGURED#	endif /* USE_INTERNAL_MD5 */#endif							/*  */			}#endif /* USE_OPENSSL */#endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */

⌨️ 快捷键说明

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