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 + -
显示快捷键?