00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <net-snmp/net-snmp-config.h>
00018
00019 #include <sys/types.h>
00020 #if HAVE_WINSOCK_H
00021 #include <winsock.h>
00022 #endif
00023 #ifdef HAVE_STDLIB_H
00024 #include <stdlib.h>
00025 #endif
00026 #if HAVE_STRING_H
00027 #include <string.h>
00028 #else
00029 #include <strings.h>
00030 #endif
00031 #if TIME_WITH_SYS_TIME
00032 # ifdef WIN32
00033 # include <sys/timeb.h>
00034 # else
00035 # include <sys/time.h>
00036 # endif
00037 # include <time.h>
00038 #else
00039 # if HAVE_SYS_TIME_H
00040 # include <sys/time.h>
00041 # else
00042 # include <time.h>
00043 # endif
00044 #endif
00045 #ifdef HAVE_NETINET_IN_H
00046 #include <netinet/in.h>
00047 #endif
00048
00049 #if HAVE_DMALLOC_H
00050 #include <dmalloc.h>
00051 #endif
00052
00053 #include <net-snmp/types.h>
00054 #include <net-snmp/output_api.h>
00055 #include <net-snmp/utilities.h>
00056
00057 #ifdef NETSNMP_USE_INTERNAL_MD5
00058 #include <net-snmp/library/md5.h>
00059 #endif
00060 #include <net-snmp/library/snmp_api.h>
00061 #include <net-snmp/library/callback.h>
00062 #include <net-snmp/library/snmp_secmod.h>
00063 #include <net-snmp/library/snmpusm.h>
00064 #include <net-snmp/library/keytools.h>
00065 #include <net-snmp/library/scapi.h>
00066 #include <net-snmp/library/mib.h>
00067 #include <net-snmp/library/transform_oids.h>
00068
00069 #ifdef NETSNMP_USE_OPENSSL
00070 #include <openssl/hmac.h>
00071 #include <openssl/evp.h>
00072 #include <openssl/rand.h>
00073 #include <openssl/des.h>
00074 #ifdef HAVE_AES
00075 #include <openssl/aes.h>
00076 #endif
00077
00078 #ifndef NETSNMP_DISABLE_DES
00079 #ifdef STRUCT_DES_KS_STRUCT_HAS_WEAK_KEY
00080
00081 #define DES_key_schedule des_key_schedule
00082 #define DES_cblock des_cblock
00083 #define DES_key_sched des_key_sched
00084 #define DES_ncbc_encrypt des_ncbc_encrypt
00085 #define DES_cbc_encrypt des_cbc_encrypt
00086 #define OLD_DES
00087 #endif
00088 #endif
00089
00090 #endif
00091
00092 #ifdef NETSNMP_USE_PKCS11
00093 #include <security/cryptoki.h>
00094 #endif
00095
00096 #ifdef QUITFUN
00097 #undef QUITFUN
00098 #define QUITFUN(e, l) \
00099 if (e != SNMPERR_SUCCESS) { \
00100 rval = SNMPERR_SC_GENERAL_FAILURE; \
00101 goto l ; \
00102 }
00103 #endif
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 int
00115 sc_get_properlength(const oid * hashtype, u_int hashtype_len)
00116 {
00117 DEBUGTRACE;
00118
00119
00120
00121 #ifndef NETSNMP_DISABLE_MD5
00122 if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
00123 return BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5);
00124 } else
00125 #endif
00126 if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {
00127 return BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
00128 }
00129 return SNMPERR_GENERR;
00130 }
00131
00132 int
00133 sc_get_proper_priv_length(const oid * privtype, u_int privtype_len)
00134 {
00135 int properlength = 0;
00136 #ifndef NETSNMP_DISABLE_DES
00137 if (ISTRANSFORM(privtype, DESPriv)) {
00138 properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
00139 }
00140 #endif
00141 #ifdef HAVE_AES
00142 if (ISTRANSFORM(privtype, AESPriv)) {
00143 properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_AES);
00144 }
00145 #endif
00146 return properlength;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156 int
00157 sc_init(void)
00158 {
00159 int rval = SNMPERR_SUCCESS;
00160
00161 #ifndef NETSNMP_USE_OPENSSL
00162 #ifdef NETSNMP_USE_INTERNAL_MD5
00163 struct timeval tv;
00164
00165 DEBUGTRACE;
00166
00167 gettimeofday(&tv, (struct timezone *) 0);
00168
00169 srandom(tv.tv_sec ^ tv.tv_usec);
00170 #elif NETSNMP_USE_PKCS11
00171 DEBUGTRACE;
00172 rval = pkcs_init();
00173 #else
00174 rval = SNMPERR_SC_NOT_CONFIGURED;
00175 #endif
00176
00177
00178
00179
00180 #endif
00181 return rval;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 int
00195 sc_random(u_char * buf, size_t * buflen)
00196 #if defined(NETSNMP_USE_INTERNAL_MD5) || defined(NETSNMP_USE_OPENSSL) || defined(NETSNMP_USE_PKCS11)
00197 {
00198 int rval = SNMPERR_SUCCESS;
00199 #ifdef NETSNMP_USE_INTERNAL_MD5
00200 int i;
00201 int rndval;
00202 u_char *ucp = buf;
00203 #endif
00204
00205 DEBUGTRACE;
00206
00207 #ifdef NETSNMP_USE_OPENSSL
00208 RAND_bytes(buf, *buflen);
00209 #elif NETSNMP_USE_PKCS11
00210 pkcs_random(buf, *buflen);
00211 #else
00212
00213
00214
00215
00216
00217 rval = *buflen - *buflen % sizeof(rndval);
00218 for (i = 0; i < rval; i += sizeof(rndval)) {
00219 rndval = random();
00220 memcpy(ucp, &rndval, sizeof(rndval));
00221 ucp += sizeof(rndval);
00222 }
00223
00224 rndval = random();
00225 memcpy(ucp, &rndval, *buflen % sizeof(rndval));
00226
00227 rval = SNMPERR_SUCCESS;
00228 #endif
00229 return rval;
00230
00231 }
00232
00233 #else
00234 _SCAPI_NOT_CONFIGURED
00235 #endif
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 int
00264 sc_generate_keyed_hash(const oid * authtype, size_t authtypelen,
00265 u_char * key, u_int keylen,
00266 u_char * message, u_int msglen,
00267 u_char * MAC, size_t * maclen)
00268 #if defined(NETSNMP_USE_INTERNAL_MD5) || defined(NETSNMP_USE_OPENSSL) || defined(NETSNMP_USE_PKCS11)
00269 {
00270 int rval = SNMPERR_SUCCESS;
00271 int properlength;
00272
00273 u_char buf[SNMP_MAXBUF_SMALL];
00274 #if defined(NETSNMP_USE_OPENSSL) || defined(NETSNMP_USE_PKCS11)
00275 size_t buf_len = sizeof(buf);
00276 #endif
00277
00278 DEBUGTRACE;
00279
00280 #ifdef NETSNMP_ENABLE_TESTING_CODE
00281 {
00282 int i;
00283 DEBUGMSG(("sc_generate_keyed_hash",
00284 "sc_generate_keyed_hash(): key=0x"));
00285 for (i = 0; i < keylen; i++)
00286 DEBUGMSG(("sc_generate_keyed_hash", "%02x", key[i] & 0xff));
00287 DEBUGMSG(("sc_generate_keyed_hash", " (%d)\n", keylen));
00288 }
00289 #endif
00290
00291
00292
00293
00294 if (!authtype || !key || !message || !MAC || !maclen
00295 || (keylen <= 0) || (msglen <= 0) || (*maclen <= 0)
00296 || (authtypelen != USM_LENGTH_OID_TRANSFORM)) {
00297 QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
00298 }
00299
00300 properlength = sc_get_properlength(authtype, authtypelen);
00301 if (properlength == SNMPERR_GENERR)
00302 return properlength;
00303
00304 if (((int) keylen < properlength)) {
00305 QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
00306 }
00307 #ifdef NETSNMP_USE_OPENSSL
00308
00309
00310
00311 #ifndef NETSNMP_DISABLE_MD5
00312 if (ISTRANSFORM(authtype, HMACMD5Auth))
00313 HMAC(EVP_md5(), key, keylen, message, msglen, buf, &buf_len);
00314 else
00315 #endif
00316 if (ISTRANSFORM(authtype, HMACSHA1Auth))
00317 HMAC(EVP_sha1(), key, keylen, message, msglen, buf, &buf_len);
00318 else {
00319 QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
00320 }
00321 if ((int)buf_len != properlength) {
00322 QUITFUN(rval, sc_generate_keyed_hash_quit);
00323 }
00324 if ((int)*maclen > buf_len)
00325 *maclen = buf_len;
00326 memcpy(MAC, buf, *maclen);
00327
00328 #elif NETSNMP_USE_PKCS11
00329
00330 #ifndef NETSNMP_DISABLE_MD5
00331 if (ISTRANSFORM(authtype, HMACMD5Auth)) {
00332 if (pkcs_sign(CKM_MD5_HMAC,key, keylen, message,
00333 msglen, buf, &buf_len) != SNMPERR_SUCCESS) {
00334 QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
00335 }
00336 } else
00337 #endif
00338 if (ISTRANSFORM(authtype, HMACSHA1Auth)) {
00339 if (pkcs_sign(CKM_SHA_1_HMAC,key, keylen, message,
00340 msglen, buf, &buf_len) != SNMPERR_SUCCESS) {
00341 QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
00342 }
00343 } else {
00344 QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
00345 }
00346
00347 if (buf_len != properlength) {
00348 QUITFUN(rval, sc_generate_keyed_hash_quit);
00349 }
00350 if (*maclen > buf_len)
00351 *maclen = buf_len;
00352 memcpy(MAC, buf, *maclen);
00353
00354 #else
00355 if ((int) *maclen > properlength)
00356 *maclen = properlength;
00357 if (MDsign(message, msglen, MAC, *maclen, key, keylen)) {
00358 rval = SNMPERR_GENERR;
00359 goto sc_generate_keyed_hash_quit;
00360 }
00361 #endif
00362
00363 #ifdef NETSNMP_ENABLE_TESTING_CODE
00364 {
00365 char *s;
00366 int len = binary_to_hex(MAC, *maclen, &s);
00367
00368 DEBUGMSGTL(("scapi", "Full v3 message hash: %s\n", s));
00369 SNMP_ZERO(s, len);
00370 SNMP_FREE(s);
00371 }
00372 #endif
00373
00374 sc_generate_keyed_hash_quit:
00375 SNMP_ZERO(buf, SNMP_MAXBUF_SMALL);
00376 return rval;
00377 }
00378
00379 #else
00380 _SCAPI_NOT_CONFIGURED
00381 #endif
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 int
00401 sc_hash(const oid * hashtype, size_t hashtypelen, u_char * buf,
00402 size_t buf_len, u_char * MAC, size_t * MAC_len)
00403 #if defined(NETSNMP_USE_INTERNAL_MD5) || defined(NETSNMP_USE_OPENSSL) || defined(NETSNMP_USE_PKCS11)
00404 {
00405 #if defined(NETSNMP_USE_OPENSSL) || defined(NETSNMP_USE_PKCS11)
00406 int rval = SNMPERR_SUCCESS;
00407 #endif
00408 int ret;
00409 unsigned int tmp_len;
00410
00411 #ifdef NETSNMP_USE_OPENSSL
00412 const EVP_MD *hashfn;
00413 EVP_MD_CTX ctx, *cptr;
00414 #endif
00415
00416 DEBUGTRACE;
00417
00418 if (hashtype == NULL || hashtypelen < 0 || buf == NULL ||
00419 buf_len <= 0 || MAC == NULL || MAC_len == NULL )
00420 return (SNMPERR_GENERR);
00421 ret = sc_get_properlength(hashtype, hashtypelen);
00422 if (( ret < 0 ) || (*MAC_len < ret ))
00423 return (SNMPERR_GENERR);
00424
00425 #ifdef NETSNMP_USE_OPENSSL
00426
00427
00428
00429 #ifndef NETSNMP_DISABLE_MD5
00430 if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
00431 hashfn = (const EVP_MD *) EVP_md5();
00432 } else
00433 #endif
00434 if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {
00435 hashfn = (const EVP_MD *) EVP_sha1();
00436 } else {
00437 return (SNMPERR_GENERR);
00438 }
00439
00441 memset(&ctx, 0, sizeof(ctx));
00442 cptr = &ctx;
00443 #if defined(OLD_DES)
00444 EVP_DigestInit(cptr, hashfn);
00445 #else
00446
00447
00448 if (SSLeay() < 0x907000) {
00449
00450
00451 cptr = (EVP_MD_CTX *)malloc(256);
00452 EVP_DigestInit(cptr, hashfn);
00453 } else {
00454 EVP_MD_CTX_init(cptr);
00455 EVP_DigestInit(cptr, hashfn);
00456 }
00457 #endif
00458
00460 EVP_DigestUpdate(cptr, buf, buf_len);
00461
00463 #if defined(OLD_DES)
00464 EVP_DigestFinal(cptr, MAC, &tmp_len);
00465 *MAC_len = tmp_len;
00466 #else
00467 if (SSLeay() < 0x907000) {
00468 EVP_DigestFinal(cptr, MAC, &tmp_len);
00469 *MAC_len = tmp_len;
00470 free(cptr);
00471 } else {
00472 EVP_DigestFinal_ex(cptr, MAC, &tmp_len);
00473 *MAC_len = tmp_len;
00474 EVP_MD_CTX_cleanup(cptr);
00475 }
00476 #endif
00477 return (rval);
00478 #elif NETSNMP_USE_PKCS11
00479
00480 #ifndef NETSNMP_DISABLE_MD5
00481 if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
00482 rval = pkcs_digest(CKM_MD5, buf, buf_len, MAC, MAC_len);
00483 } else
00484 #endif
00485 if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {
00486 rval = pkcs_digest(CKM_SHA_1, buf, buf_len, MAC, MAC_len);
00487 } else {
00488 return (SNMPERR_GENERR);
00489 }
00490
00491 return (rval);
00492
00493 #else
00494
00495 if (MDchecksum(buf, buf_len, MAC, *MAC_len)) {
00496 return SNMPERR_GENERR;
00497 }
00498 if (*MAC_len > 16)
00499 *MAC_len = 16;
00500 return SNMPERR_SUCCESS;
00501
00502 #endif
00503 }
00504 #else
00505 _SCAPI_NOT_CONFIGURED
00506 #endif
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 int
00531 sc_check_keyed_hash(const oid * authtype, size_t authtypelen,
00532 u_char * key, u_int keylen,
00533 u_char * message, u_int msglen,
00534 u_char * MAC, u_int maclen)
00535 #if defined(NETSNMP_USE_INTERNAL_MD5) || defined(NETSNMP_USE_OPENSSL) || defined(NETSNMP_USE_PKCS11)
00536 {
00537 int rval = SNMPERR_SUCCESS;
00538 size_t buf_len = SNMP_MAXBUF_SMALL;
00539
00540 u_char buf[SNMP_MAXBUF_SMALL];
00541
00542 DEBUGTRACE;
00543
00544 #ifdef NETSNMP_ENABLE_TESTING_CODE
00545 {
00546 int i;
00547 DEBUGMSG(("scapi", "sc_check_keyed_hash(): key=0x"));
00548 for (i = 0; i < keylen; i++)
00549 DEBUGMSG(("scapi", "%02x", key[i] & 0xff));
00550 DEBUGMSG(("scapi", " (%d)\n", keylen));
00551 }
00552 #endif
00553
00554
00555
00556
00557 if (!authtype || !key || !message || !MAC
00558 || (keylen <= 0) || (msglen <= 0) || (maclen <= 0)
00559 || (authtypelen != USM_LENGTH_OID_TRANSFORM)) {
00560 QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);
00561 }
00562
00563
00564
00565
00566
00567
00568
00569 rval = sc_generate_keyed_hash(authtype, authtypelen,
00570 key, keylen,
00571 message, msglen, buf, &buf_len);
00572 QUITFUN(rval, sc_check_keyed_hash_quit);
00573
00574 if (maclen > msglen) {
00575 QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);
00576
00577 } else if (memcmp(buf, MAC, maclen) != 0) {
00578 QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);
00579 }
00580
00581
00582 sc_check_keyed_hash_quit:
00583 SNMP_ZERO(buf, SNMP_MAXBUF_SMALL);
00584
00585 return rval;
00586
00587 }
00588
00589 #else
00590 _SCAPI_NOT_CONFIGURED
00591 #endif
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 int
00618 sc_encrypt(const oid * privtype, size_t privtypelen,
00619 u_char * key, u_int keylen,
00620 u_char * iv, u_int ivlen,
00621 u_char * plaintext, u_int ptlen,
00622 u_char * ciphertext, size_t * ctlen)
00623 #if defined(NETSNMP_USE_OPENSSL)
00624 {
00625 int rval = SNMPERR_SUCCESS;
00626 u_int properlength = 0, properlength_iv = 0;
00627 u_char pad_block[128];
00628 u_char my_iv[128];
00629 int pad, plast, pad_size = 0;
00630 int have_trans;
00631 #ifndef NETSNMP_DISABLE_DES
00632 #ifdef OLD_DES
00633 DES_key_schedule key_sch;
00634 #else
00635 DES_key_schedule key_sched_store;
00636 DES_key_schedule *key_sch = &key_sched_store;
00637 #endif
00638 DES_cblock key_struct;
00639 #endif
00640 #ifdef HAVE_AES
00641 AES_KEY aes_key;
00642 int new_ivlen = 0;
00643 #endif
00644
00645 DEBUGTRACE;
00646
00647
00648
00649
00650 #if !defined(NETSNMP_ENABLE_SCAPI_AUTHPRIV)
00651 snmp_log(LOG_ERR, "Encryption support not enabled.\n");
00652 return SNMPERR_SC_NOT_CONFIGURED;
00653 #endif
00654
00655 if (!privtype || !key || !iv || !plaintext || !ciphertext || !ctlen
00656 || (keylen <= 0) || (ivlen <= 0) || (ptlen <= 0) || (*ctlen <= 0)
00657 || (privtypelen != USM_LENGTH_OID_TRANSFORM)) {
00658 QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
00659 } else if (ptlen > *ctlen) {
00660 QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
00661 }
00662 #ifdef NETSNMP_ENABLE_TESTING_CODE
00663 {
00664 size_t buf_len = 128, out_len = 0;
00665 u_char *buf = (u_char *) malloc(buf_len);
00666
00667 if (buf != NULL) {
00668 if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1,
00669 iv, ivlen)) {
00670 DEBUGMSGTL(("scapi", "encrypt: IV: %s/", buf));
00671 } else {
00672 DEBUGMSGTL(("scapi", "encrypt: IV: %s [TRUNCATED]/", buf));
00673 }
00674 out_len = 0;
00675 if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1,
00676 key, keylen)) {
00677 DEBUGMSG(("scapi", "%s\n", buf));
00678 } else {
00679 DEBUGMSG(("scapi", "%s [TRUNCATED]\n", buf));
00680 }
00681 out_len = 0;
00682 if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1,
00683 plaintext, 16)) {
00684 DEBUGMSGTL(("scapi", "encrypt: string: %s\n", buf));
00685 } else {
00686 DEBUGMSGTL(("scapi", "encrypt: string: %s [TRUNCATED]\n",
00687 buf));
00688 }
00689 free(buf);
00690 } else {
00691 DEBUGMSGTL(("scapi",
00692 "encrypt: malloc fail for debug output\n"));
00693 }
00694 }
00695 #endif
00696
00697
00698
00699
00700
00701 have_trans = 0;
00702 #ifndef NETSNMP_DISABLE_DES
00703 if (ISTRANSFORM(privtype, DESPriv)) {
00704 properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
00705 properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
00706 pad_size = properlength;
00707 have_trans = 1;
00708 }
00709 #endif
00710 #ifdef HAVE_AES
00711 if (ISTRANSFORM(privtype, AESPriv)) {
00712 properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_AES);
00713 properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_AES_IV);
00714 have_trans = 1;
00715 }
00716 #endif
00717 if (!have_trans) {
00718 QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
00719 }
00720
00721 if ((keylen < properlength) || (ivlen < properlength_iv)) {
00722 QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
00723 }
00724
00725 memset(my_iv, 0, sizeof(my_iv));
00726
00727 #ifndef NETSNMP_DISABLE_DES
00728 if (ISTRANSFORM(privtype, DESPriv)) {
00729
00730
00731
00732
00733 pad = pad_size - (ptlen % pad_size);
00734 plast = (int) ptlen - (pad_size - pad);
00735 if (pad == pad_size)
00736 pad = 0;
00737 if (ptlen + pad > *ctlen) {
00738 QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
00739 }
00740 if (pad > 0) {
00741 memcpy(pad_block, plaintext + plast, pad_size - pad);
00742 memset(&pad_block[pad_size - pad], pad, pad);
00743 }
00744
00745 memcpy(key_struct, key, sizeof(key_struct));
00746 (void) DES_key_sched(&key_struct, key_sch);
00747
00748 memcpy(my_iv, iv, ivlen);
00749
00750
00751
00752 DES_ncbc_encrypt(plaintext, ciphertext, plast, key_sch,
00753 (DES_cblock *) my_iv, DES_ENCRYPT);
00754 if (pad > 0) {
00755
00756
00757
00758 DES_ncbc_encrypt(pad_block, ciphertext + plast, pad_size,
00759 key_sch, (DES_cblock *) my_iv, DES_ENCRYPT);
00760 *ctlen = plast + pad_size;
00761 } else {
00762 *ctlen = plast;
00763 }
00764 }
00765 #endif
00766 #ifdef HAVE_AES
00767 if (ISTRANSFORM(privtype, AESPriv)) {
00768 (void) AES_set_encrypt_key(key, properlength*8, &aes_key);
00769
00770 memcpy(my_iv, iv, ivlen);
00771
00772
00773
00774 AES_cfb128_encrypt(plaintext, ciphertext, ptlen,
00775 &aes_key, my_iv, &new_ivlen, AES_ENCRYPT);
00776 *ctlen = ptlen;
00777 }
00778 #endif
00779 sc_encrypt_quit:
00780
00781
00782
00783 memset(my_iv, 0, sizeof(my_iv));
00784 memset(pad_block, 0, sizeof(pad_block));
00785 #ifndef NETSNMP_DISABLE_DES
00786 memset(key_struct, 0, sizeof(key_struct));
00787 #ifdef OLD_DES
00788 memset(&key_sch, 0, sizeof(key_sch));
00789 #else
00790 memset(&key_sched_store, 0, sizeof(key_sched_store));
00791 #endif
00792 #endif
00793 #ifdef HAVE_AES
00794 memset(&aes_key,0,sizeof(aes_key));
00795 #endif
00796 return rval;
00797
00798 }
00799 #elif defined(NETSNMP_USE_PKCS11)
00800 {
00801 int rval = SNMPERR_SUCCESS;
00802 u_int properlength, properlength_iv;
00803 u_char pkcs_des_key[8];
00804
00805 DEBUGTRACE;
00806
00807
00808
00809
00810 #if !defined(NETSNMP_ENABLE_SCAPI_AUTHPRIV)
00811 snmp_log(LOG_ERR, "Encryption support not enabled.\n");
00812 return SNMPERR_SC_NOT_CONFIGURED;
00813 #endif
00814
00815 if (!privtype || !key || !iv || !plaintext || !ciphertext || !ctlen
00816 || (keylen <= 0) || (ivlen <= 0) || (ptlen <= 0) || (*ctlen <= 0)
00817 || (privtypelen != USM_LENGTH_OID_TRANSFORM)) {
00818 QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
00819 } else if (ptlen > *ctlen) {
00820 QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
00821 }
00822
00823
00824
00825
00826 if (ISTRANSFORM(privtype, DESPriv)) {
00827 properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
00828 properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
00829 } else {
00830 QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
00831 }
00832
00833 if ((keylen < properlength) || (ivlen < properlength_iv)) {
00834 QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
00835 }
00836
00837 if (ISTRANSFORM(privtype, DESPriv)) {
00838 memset(pkcs_des_key, 0, sizeof(pkcs_des_key));
00839 memcpy(pkcs_des_key, key, sizeof(pkcs_des_key));
00840 rval = pkcs_encrpyt(CKM_DES_CBC, pkcs_des_key,
00841 sizeof(pkcs_des_key), iv, ivlen, plaintext, ptlen,
00842 ciphertext, ctlen);
00843 }
00844
00845 sc_encrypt_quit:
00846 return rval;
00847 }
00848 #else
00849 {
00850 # if NETSNMP_USE_INTERNAL_MD5
00851 {
00852 snmp_log(LOG_ERR, "Encryption support not enabled.\n");
00853 DEBUGMSGTL(("scapi", "Encrypt function not defined.\n"));
00854 return SNMPERR_SC_GENERAL_FAILURE;
00855 }
00856
00857 # else
00858 _SCAPI_NOT_CONFIGURED
00859 # endif
00860 }
00861 #endif
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890 int
00891 sc_decrypt(const oid * privtype, size_t privtypelen,
00892 u_char * key, u_int keylen,
00893 u_char * iv, u_int ivlen,
00894 u_char * ciphertext, u_int ctlen,
00895 u_char * plaintext, size_t * ptlen)
00896 #ifdef NETSNMP_USE_OPENSSL
00897 {
00898
00899 int rval = SNMPERR_SUCCESS;
00900 u_char my_iv[128];
00901 #ifndef NETSNMP_DISABLE_DES
00902 #ifdef OLD_DES
00903 DES_key_schedule key_sch;
00904 #else
00905 DES_key_schedule key_sched_store;
00906 DES_key_schedule *key_sch = &key_sched_store;
00907 #endif
00908 DES_cblock key_struct;
00909 #endif
00910 u_int properlength = 0, properlength_iv = 0;
00911 int have_transform;
00912 #ifdef HAVE_AES
00913 int new_ivlen = 0;
00914 AES_KEY aes_key;
00915 #endif
00916
00917 DEBUGTRACE;
00918
00919 if (!privtype || !key || !iv || !plaintext || !ciphertext || !ptlen
00920 || (ctlen <= 0) || (*ptlen <= 0) || (*ptlen < ctlen)
00921 || (privtypelen != USM_LENGTH_OID_TRANSFORM)) {
00922 QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
00923 }
00924 #ifdef NETSNMP_ENABLE_TESTING_CODE
00925 {
00926 size_t buf_len = 128, out_len = 0;
00927 u_char *buf = (u_char *) malloc(buf_len);
00928
00929 if (buf != NULL) {
00930 if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1,
00931 iv, ivlen)) {
00932 DEBUGMSGTL(("scapi", "decrypt: IV: %s/", buf));
00933 } else {
00934 DEBUGMSGTL(("scapi", "decrypt: IV: %s [TRUNCATED]/", buf));
00935 }
00936 out_len = 0;
00937 if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1,
00938 key, keylen)) {
00939 DEBUGMSG(("scapi", "%s\n", buf));
00940 } else {
00941 DEBUGMSG(("scapi", "%s\n", buf));
00942 }
00943 free(buf);
00944 } else {
00945 DEBUGMSGTL(("scapi",
00946 "decrypt: malloc fail for debug output\n"));
00947 }
00948 }
00949 #endif
00950
00951
00952
00953
00954 have_transform = 0;
00955 #ifndef NETSNMP_DISABLE_DES
00956 if (ISTRANSFORM(privtype, DESPriv)) {
00957 properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
00958 properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
00959 have_transform = 1;
00960 }
00961 #endif
00962 #ifdef HAVE_AES
00963 if (ISTRANSFORM(privtype, AESPriv)) {
00964 properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_AES);
00965 properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_AES_IV);
00966 have_transform = 1;
00967 }
00968 #endif
00969 if (!have_transform) {
00970 QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
00971 }
00972
00973 if ((keylen < properlength) || (ivlen < properlength_iv)) {
00974 QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
00975 }
00976
00977 memset(my_iv, 0, sizeof(my_iv));
00978 #ifndef NETSNMP_DISABLE_DES
00979 if (ISTRANSFORM(privtype, DESPriv)) {
00980 memcpy(key_struct, key, sizeof(key_struct));
00981 (void) DES_key_sched(&key_struct, key_sch);
00982
00983 memcpy(my_iv, iv, ivlen);
00984 DES_cbc_encrypt(ciphertext, plaintext, ctlen, key_sch,
00985 (DES_cblock *) my_iv, DES_DECRYPT);
00986 *ptlen = ctlen;
00987 }
00988 #endif
00989 #ifdef HAVE_AES
00990 if (ISTRANSFORM(privtype, AESPriv)) {
00991 (void) AES_set_encrypt_key(key, properlength*8, &aes_key);
00992
00993 memcpy(my_iv, iv, ivlen);
00994
00995
00996
00997 AES_cfb128_encrypt(ciphertext, plaintext, ctlen,
00998 &aes_key, my_iv, &new_ivlen, AES_DECRYPT);
00999 *ptlen = ctlen;
01000 }
01001 #endif
01002
01003
01004
01005
01006 sc_decrypt_quit:
01007 #ifndef NETSNMP_DISABLE_DES
01008 #ifdef OLD_DES
01009 memset(&key_sch, 0, sizeof(key_sch));
01010 #else
01011 memset(&key_sched_store, 0, sizeof(key_sched_store));
01012 #endif
01013 memset(key_struct, 0, sizeof(key_struct));
01014 #endif
01015 memset(my_iv, 0, sizeof(my_iv));
01016 return rval;
01017 }
01018 #elif NETSNMP_USE_PKCS11
01019 {
01020 int rval = SNMPERR_SUCCESS;
01021 u_int properlength, properlength_iv;
01022 u_char pkcs_des_key[8];
01023
01024 DEBUGTRACE;
01025
01026 if (!privtype || !key || !iv || !plaintext || !ciphertext || !ptlen
01027 || (ctlen <= 0) || (*ptlen <= 0) || (*ptlen < ctlen)
01028 || (privtypelen != USM_LENGTH_OID_TRANSFORM)) {
01029 QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
01030 }
01031
01032
01033
01034
01035 if (ISTRANSFORM(privtype, DESPriv)) {
01036 properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
01037 properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
01038 } else {
01039 QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
01040 }
01041
01042 if ((keylen < properlength) || (ivlen < properlength_iv)) {
01043 QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
01044 }
01045
01046 if (ISTRANSFORM(privtype, DESPriv)) {
01047 memset(pkcs_des_key, 0, sizeof(pkcs_des_key));
01048 memcpy(pkcs_des_key, key, sizeof(pkcs_des_key));
01049 rval = pkcs_decrpyt(CKM_DES_CBC, pkcs_des_key,
01050 sizeof(pkcs_des_key), iv, ivlen, ciphertext,
01051 ctlen, plaintext, ptlen);
01052 *ptlen = ctlen;
01053 }
01054
01055 sc_decrypt_quit:
01056 return rval;
01057 }
01058 #else
01059 {
01060 #if !defined(NETSNMP_ENABLE_SCAPI_AUTHPRIV)
01061 snmp_log(LOG_ERR, "Encryption support not enabled.\n");
01062 return SNMPERR_SC_NOT_CONFIGURED;
01063 #else
01064 # if NETSNMP_USE_INTERNAL_MD5
01065 {
01066 DEBUGMSGTL(("scapi", "Decryption function not defined.\n"));
01067 return SNMPERR_SC_GENERAL_FAILURE;
01068 }
01069
01070 # else
01071 _SCAPI_NOT_CONFIGURED
01072 # endif
01073 #endif
01074 }
01075 #endif