📄 scapi.c
字号:
/* * 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(const 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 properlength, properlength_iv; u_char pad_block[128]; /* bigger than anything I need */ u_char my_iv[128]; /* ditto */ int pad, plast, pad_size;#ifdef OLD_DES DES_key_schedule key_sch;#else DES_key_schedule key_sched_store; DES_key_schedule *key_sch = &key_sched_store;#endif DES_cblock key_struct;#ifdef HAVE_AES AES_KEY aes_key; int new_ivlen = 0;#endif DEBUGTRACE; /* * Sanity check. */#if !defined(SCAPI_AUTHPRIV) snmp_log(LOG_ERR, "Encryption support not enabled.\n"); 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 { size_t buf_len = 128, out_len = 0; u_char *buf = (u_char *) malloc(buf_len); if (buf != NULL) { if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1, iv, ivlen)) { DEBUGMSGTL(("scapi", "encrypt: IV: %s/", buf)); } else { DEBUGMSGTL(("scapi", "encrypt: IV: %s [TRUNCATED]/", buf)); } out_len = 0; if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1, key, keylen)) { DEBUGMSG(("scapi", "%s\n", buf)); } else { DEBUGMSG(("scapi", "%s [TRUNCATED]\n", buf)); } out_len = 0; if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1, plaintext, 16)) { DEBUGMSGTL(("scapi", "encrypt: string: %s\n", buf)); } else { DEBUGMSGTL(("scapi", "encrypt: string: %s [TRUNCATED]\n", buf)); } free(buf); } else { DEBUGMSGTL(("scapi", "encrypt: malloc fail for debug output\n")); } }#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;#ifdef HAVE_AES } else if (ISTRANSFORM(privtype, AES128Priv)) { properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_AES128); properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_AES128_IV); } else if (ISTRANSFORM(privtype, AES192Priv)) { properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_AES192); properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_AES192_IV); } else if (ISTRANSFORM(privtype, AES256Priv)) { properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_AES256); properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_AES256_IV);#endif } else { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } if ((keylen < properlength) || (ivlen < properlength_iv)) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } memset(my_iv, 0, sizeof(my_iv)); if (ISTRANSFORM(privtype, DESPriv)) { /* * now calculate the padding needed */ pad = pad_size - (ptlen % pad_size); plast = (int) ptlen - (pad_size - pad); if (pad == pad_size) pad = 0; if (ptlen + pad > *ctlen) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); /* not enough space */ } 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 */ } 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); if (pad > 0) { /* * 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; } else { *ctlen = plast; } }#ifdef HAVE_AES else if (ISTRANSFORM(privtype, AES128Priv) || ISTRANSFORM(privtype, AES192Priv) || ISTRANSFORM(privtype, AES256Priv)) { (void) AES_set_encrypt_key(key, properlength*8, &aes_key); memcpy(my_iv, iv, ivlen); /* * encrypt the data */ AES_cfb128_encrypt(plaintext, ciphertext, ptlen, &aes_key, my_iv, &new_ivlen, AES_ENCRYPT); *ctlen = ptlen; }#endif 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));#ifdef OLD_DES memset(&key_sch, 0, sizeof(key_sch));#else memset(&key_sched_store, 0, sizeof(key_sched_store));#endif#ifdef HAVE_AES memset(&aes_key,0,sizeof(aes_key));#endif return rval;} /* end sc_encrypt() */#else{# if USE_INTERNAL_MD5 { snmp_log(LOG_ERR, "Encryption support not enabled.\n"); 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(const 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; u_char my_iv[128];#ifdef OLD_DES DES_key_schedule key_sch;#else DES_key_schedule key_sched_store; DES_key_schedule *key_sch = &key_sched_store;#endif DES_cblock key_struct; u_int properlength, properlength_iv;#ifdef HAVE_AES int new_ivlen = 0; AES_KEY aes_key;#endif 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 { size_t buf_len = 128, out_len = 0; u_char *buf = (u_char *) malloc(buf_len); if (buf != NULL) { if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1, iv, ivlen)) { DEBUGMSGTL(("scapi", "decrypt: IV: %s/", buf)); } else { DEBUGMSGTL(("scapi", "decrypt: IV: %s [TRUNCATED]/", buf)); } out_len = 0; if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1, key, keylen)) { DEBUGMSG(("scapi", "%s\n", buf)); } else { DEBUGMSG(("scapi", "%s\n", buf)); } free(buf); } else { DEBUGMSGTL(("scapi", "decrypt: malloc fail for debug output\n")); } }#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);#ifdef HAVE_AES } else if (ISTRANSFORM(privtype, AES128Priv)) { properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_AES128); properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_AES128_IV); } else if (ISTRANSFORM(privtype, AES192Priv)) { properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_AES192); properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_AES192_IV); } else if (ISTRANSFORM(privtype, AES256Priv)) { properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_AES256); properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_AES256_IV);#endif } 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); *ptlen = ctlen; }#ifdef HAVE_AES else if (ISTRANSFORM(privtype, AES128Priv) || ISTRANSFORM(privtype, AES192Priv) || ISTRANSFORM(privtype, AES256Priv)) { (void) AES_set_encrypt_key(key, properlength*8, &aes_key); memcpy(my_iv, iv, ivlen); /* * encrypt the data */ AES_cfb128_encrypt(ciphertext, plaintext, ctlen, &aes_key, my_iv, &new_ivlen, AES_DECRYPT); *ptlen = ctlen; }#endif /* * exit cond */ sc_decrypt_quit:#ifdef OLD_DES memset(&key_sch, 0, sizeof(key_sch));#else memset(&key_sched_store, 0, sizeof(key_sched_store));#endif memset(key_struct, 0, sizeof(key_struct)); memset(my_iv, 0, sizeof(my_iv)); return rval;}#else /* USE OPEN_SSL */{#if !defined(SCAPI_AUTHPRIV) snmp_log(LOG_ERR, "Encryption support not enabled.\n"); 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -