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

📄 scapi.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#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.
 */
int
sc_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.
 */
int
sc_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.
 */
int
sc_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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -