6 #include <net-snmp/net-snmp-config.h>
20 #if TIME_WITH_SYS_TIME
22 # include <sys/timeb.h>
24 # include <sys/time.h>
29 # include <sys/time.h>
34 #ifdef HAVE_NETINET_IN_H
35 #include <netinet/in.h>
42 #include <net-snmp/types.h>
43 #include <net-snmp/output_api.h>
44 #include <net-snmp/utilities.h>
46 #ifdef USE_INTERNAL_MD5
47 #include <net-snmp/library/md5.h>
49 #include <net-snmp/library/snmp_api.h>
50 #include <net-snmp/library/callback.h>
51 #include <net-snmp/library/snmp_secmod.h>
52 #include <net-snmp/library/snmpusm.h>
53 #include <net-snmp/library/keytools.h>
54 #include <net-snmp/library/scapi.h>
55 #include <net-snmp/library/mib.h>
56 #include <net-snmp/library/transform_oids.h>
59 #include <openssl/hmac.h>
60 #include <openssl/evp.h>
61 #include <openssl/rand.h>
62 #include <openssl/des.h>
64 #include <openssl/aes.h>
67 #ifdef STRUCT_DES_KS_STRUCT_HAS_WEAK_KEY
68 /* these are older names for newer structures that exist in openssl .9.7 */
69 #define DES_key_schedule des_key_schedule
70 #define DES_cblock des_cblock
71 #define DES_key_sched des_key_sched
72 #define DES_ncbc_encrypt des_ncbc_encrypt
73 #define DES_cbc_encrypt des_cbc_encrypt
77 #endif /* HAVE_OPENSSL */
81 #define QUITFUN(e, l) \
82 if (e != SNMPERR_SUCCESS) { \
83 rval = SNMPERR_SC_GENERAL_FAILURE; \
90 * sc_get_properlength(oid *hashtype, u_int hashtype_len):
92 * Given a hashing type ("hashtype" and its length hashtype_len), return
93 * the length of the hash result.
95 * Returns either the length or SNMPERR_GENERR for an unknown hashing type.
98 sc_get_properlength(const oid
* hashtype
, u_int hashtype_len
)
102 * Determine transform type hash length.
104 if (ISTRANSFORM(hashtype
, HMACMD5Auth
)) {
105 return BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5
);
106 } else if (ISTRANSFORM(hashtype
, HMACSHA1Auth
)) {
107 return BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1
);
109 return SNMPERR_GENERR
;
113 /*******************************************************************-o-******
117 * SNMPERR_SUCCESS Success.
122 int rval
= SNMPERR_SUCCESS
;
125 #ifdef USE_INTERNAL_MD5
130 gettimeofday(&tv
, (struct timezone
*) 0);
132 srandom(tv
.tv_sec
^ tv
.tv_usec
);
134 rval
= SNMPERR_SC_NOT_CONFIGURED
;
137 * XXX ogud: The only reason to do anything here with openssl is to
138 * * XXX ogud: seed random number generator
140 #endif /* ifndef USE_OPENSSL */
142 } /* end sc_init() */
144 /*******************************************************************-o-******
148 * *buf Pre-allocated buffer.
149 * *buflen Size of buffer.
152 * SNMPERR_SUCCESS Success.
155 sc_random(u_char
* buf
, size_t * buflen
)
156 #if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
158 int rval
= SNMPERR_SUCCESS
;
159 #ifdef USE_INTERNAL_MD5
168 RAND_bytes(buf
, *buflen
); /* will never fail */
169 #else /* USE_INTERNAL_MD5 */
171 * fill the buffer with random integers. Note that random()
172 * is defined in config.h and may not be truly the random()
173 * system call if something better existed
175 rval
= *buflen
- *buflen
% sizeof(rndval
);
176 for (i
= 0; i
< rval
; i
+= sizeof(rndval
)) {
178 memcpy(ucp
, &rndval
, sizeof(rndval
));
179 ucp
+= sizeof(rndval
);
183 memcpy(ucp
, &rndval
, *buflen
% sizeof(rndval
));
185 rval
= SNMPERR_SUCCESS
;
186 #endif /* USE_OPENSSL */
189 } /* end sc_random() */
192 _SCAPI_NOT_CONFIGURED
194 /*******************************************************************-o-******
195 * sc_generate_keyed_hash
198 * authtype Type of authentication transform.
200 * *key Pointer to key (Kul) to use in keyed hash.
201 * keylen Length of key in bytes.
202 * *message Pointer to the message to hash.
203 * msglen Length of the message.
204 * *MAC Will be returned with allocated bytes containg hash.
205 * *maclen Length of the hash buffer in bytes; also indicates
206 * whether the MAC should be truncated.
209 * SNMPERR_SUCCESS Success.
210 * SNMPERR_GENERR All errs
213 * A hash of the first msglen bytes of message using a keyed hash defined
214 * by authtype is created and stored in MAC. MAC is ASSUMED to be a buffer
215 * of at least maclen bytes. If the length of the hash is greater than
216 * maclen, it is truncated to fit the buffer. If the length of the hash is
217 * less than maclen, maclen set to the number of hash bytes generated.
219 * ASSUMED that the number of hash bits is a multiple of 8.
222 sc_generate_keyed_hash(const oid
* authtype
, size_t authtypelen
,
223 u_char
* key
, u_int keylen
,
224 u_char
* message
, u_int msglen
,
225 u_char
* MAC
, size_t * maclen
)
226 #if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
228 int rval
= SNMPERR_SUCCESS
;
231 u_char buf
[SNMP_MAXBUF_SMALL
];
232 #if defined(USE_OPENSSL)
233 int buf_len
= sizeof(buf
);
238 #ifdef SNMP_TESTING_CODE
241 DEBUGMSG(("sc_generate_keyed_hash",
242 "sc_generate_keyed_hash(): key=0x"));
243 for (i
= 0; i
< keylen
; i
++)
244 DEBUGMSG(("sc_generate_keyed_hash", "%02x", key
[i
] & 0xff));
245 DEBUGMSG(("sc_generate_keyed_hash", " (%d)\n", keylen
));
247 #endif /* SNMP_TESTING_CODE */
252 if (!authtype
|| !key
|| !message
|| !MAC
|| !maclen
253 || (keylen
<= 0) || (msglen
<= 0) || (*maclen
<= 0)
254 || (authtypelen
!= USM_LENGTH_OID_TRANSFORM
)) {
255 QUITFUN(SNMPERR_GENERR
, sc_generate_keyed_hash_quit
);
258 properlength
= sc_get_properlength(authtype
, authtypelen
);
259 if (properlength
== SNMPERR_GENERR
)
262 if (((int) keylen
< properlength
)) {
263 QUITFUN(SNMPERR_GENERR
, sc_generate_keyed_hash_quit
);
267 * Determine transform type.
269 if (ISTRANSFORM(authtype
, HMACMD5Auth
))
270 HMAC(EVP_md5(), key
, keylen
, message
, msglen
, buf
, &buf_len
);
271 else if (ISTRANSFORM(authtype
, HMACSHA1Auth
))
272 HMAC(EVP_sha1(), key
, keylen
, message
, msglen
, buf
, &buf_len
);
274 QUITFUN(SNMPERR_GENERR
, sc_generate_keyed_hash_quit
);
276 if (buf_len
!= properlength
) {
277 QUITFUN(rval
, sc_generate_keyed_hash_quit
);
279 if (*maclen
> buf_len
)
281 memcpy(MAC
, buf
, *maclen
);
283 if ((int) *maclen
> properlength
)
284 *maclen
= properlength
;
285 if (MDsign(message
, msglen
, MAC
, *maclen
, key
, keylen
)) {
286 rval
= SNMPERR_GENERR
;
287 goto sc_generate_keyed_hash_quit
;
289 #endif /* USE_OPENSSL */
291 #ifdef SNMP_TESTING_CODE
294 int len
= binary_to_hex(MAC
, *maclen
, &s
);
296 DEBUGMSGTL(("scapi", "Full v3 message hash: %s\n", s
));
302 sc_generate_keyed_hash_quit
:
303 SNMP_ZERO(buf
, SNMP_MAXBUF_SMALL
);
305 } /* end sc_generate_keyed_hash() */
308 _SCAPI_NOT_CONFIGURED
311 * sc_hash(): a generic wrapper around whatever hashing package we are using.
314 * hashtype - oid pointer to a hash type
315 * hashtypelen - length of oid pointer
316 * buf - u_char buffer to be hashed
317 * buf_len - integer length of buf data
318 * MAC_len - length of the passed MAC buffer size.
321 * MAC - pre-malloced space to store hash output.
322 * MAC_len - length of MAC output to the MAC buffer.
325 * SNMPERR_SUCCESS Success.
326 * SNMP_SC_GENERAL_FAILURE Any error.
329 sc_hash(const oid
* hashtype
, size_t hashtypelen
, u_char
* buf
,
330 size_t buf_len
, u_char
* MAC
, size_t * MAC_len
)
331 #if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
334 int rval
= SNMPERR_SUCCESS
;
335 const EVP_MD
*hashfn
;
336 EVP_MD_CTX ctx
, *cptr
;
341 if (hashtype
== NULL
|| hashtypelen
< 0 || buf
== NULL
||
342 buf_len
< 0 || MAC
== NULL
|| MAC_len
== NULL
||
343 (int) (*MAC_len
) < sc_get_properlength(hashtype
, hashtypelen
))
344 return (SNMPERR_GENERR
);
348 * Determine transform type.
350 if (ISTRANSFORM(hashtype
, HMACMD5Auth
)) {
351 hashfn
= (const EVP_MD
*) EVP_md5();
352 } else if (ISTRANSFORM(hashtype
, HMACSHA1Auth
)) {
353 hashfn
= (const EVP_MD
*) EVP_sha1();
355 return (SNMPERR_GENERR
);
358 /** initialize the pointer */
359 memset(&ctx
, 0, sizeof(ctx
));
362 EVP_DigestInit(cptr
, hashfn
);
364 /* this is needed if the runtime library is different than the compiled
365 library since the openssl versions are very different. */
366 if (SSLeay() < 0x907000) {
367 /* the old version of the struct was bigger and thus more
368 memory is needed. should be 152, but we use 256 for safety. */
370 EVP_DigestInit(cptr
, hashfn
);
372 EVP_MD_CTX_init(cptr
);
373 EVP_DigestInit(cptr
, hashfn
);
378 EVP_DigestUpdate(cptr
, buf
, buf_len
);
380 /** do the final pass */
382 EVP_DigestFinal(cptr
, MAC
, MAC_len
);
384 if (SSLeay() < 0x907000) {
385 EVP_DigestFinal(cptr
, MAC
, MAC_len
);
388 EVP_DigestFinal_ex(cptr
, MAC
, MAC_len
);
389 EVP_MD_CTX_cleanup(cptr
);
393 #else /* USE_INTERNAL_MD5 */
395 if (MDchecksum(buf
, buf_len
, MAC
, *MAC_len
)) {
396 return SNMPERR_GENERR
;
400 return SNMPERR_SUCCESS
;
402 #endif /* USE_OPENSSL */
404 #else /* !defined(USE_OPENSSL) && !defined(USE_INTERNAL_MD5) */
405 _SCAPI_NOT_CONFIGURED
406 #endif /* !defined(USE_OPENSSL) && !defined(USE_INTERNAL_MD5) */
407 /*******************************************************************-o-******
408 * sc_check_keyed_hash
411 * authtype Transform type of authentication hash.
412 * *key Key bits in a string of bytes.
413 * keylen Length of key in bytes.
414 * *message Message for which to check the hash.
415 * msglen Length of message.
417 * maclen Length of given hash; indicates truncation if it is
418 * shorter than the normal size of output for
419 * given hash transform.
421 * SNMPERR_SUCCESS Success.
422 * SNMP_SC_GENERAL_FAILURE Any error
425 * Check the hash given in MAC against the hash of message. If the length
426 * of MAC is less than the length of the transform hash output, only maclen
427 * bytes are compared. The length of MAC cannot be greater than the
428 * length of the hash transform output.
431 sc_check_keyed_hash(const oid
* authtype
, size_t authtypelen
,
432 u_char
* key
, u_int keylen
,
433 u_char
* message
, u_int msglen
,
434 u_char
* MAC
, u_int maclen
)
435 #if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
437 int rval
= SNMPERR_SUCCESS
;
438 size_t buf_len
= SNMP_MAXBUF_SMALL
;
440 u_char buf
[SNMP_MAXBUF_SMALL
];
444 #ifdef SNMP_TESTING_CODE
447 DEBUGMSG(("scapi", "sc_check_keyed_hash(): key=0x"));
448 for (i
= 0; i
< keylen
; i
++)
449 DEBUGMSG(("scapi", "%02x", key
[i
] & 0xff));
450 DEBUGMSG(("scapi", " (%d)\n", keylen
));
452 #endif /* SNMP_TESTING_CODE */
457 if (!authtype
|| !key
|| !message
|| !MAC
458 || (keylen
<= 0) || (msglen
<= 0) || (maclen
<= 0)
459 || (authtypelen
!= USM_LENGTH_OID_TRANSFORM
)) {
460 QUITFUN(SNMPERR_GENERR
, sc_check_keyed_hash_quit
);
465 * Generate a full hash of the message, then compare
466 * the result with the given MAC which may shorter than
467 * the full hash length.
469 rval
= sc_generate_keyed_hash(authtype
, authtypelen
,
471 message
, msglen
, buf
, &buf_len
);
472 QUITFUN(rval
, sc_check_keyed_hash_quit
);
474 if (maclen
> msglen
) {
475 QUITFUN(SNMPERR_GENERR
, sc_check_keyed_hash_quit
);
477 } else if (memcmp(buf
, MAC
, maclen
) != 0) {
478 QUITFUN(SNMPERR_GENERR
, sc_check_keyed_hash_quit
);
482 sc_check_keyed_hash_quit
:
483 SNMP_ZERO(buf
, SNMP_MAXBUF_SMALL
);
487 } /* end sc_check_keyed_hash() */
490 _SCAPI_NOT_CONFIGURED
491 #endif /* USE_INTERNAL_MD5 */
492 /*******************************************************************-o-******
496 * privtype Type of privacy cryptographic transform.
497 * *key Key bits for crypting.
498 * keylen Length of key (buffer) in bytes.
499 * *iv IV bits for crypting.
500 * ivlen Length of iv (buffer) in bytes.
501 * *plaintext Plaintext to crypt.
502 * ptlen Length of plaintext.
503 * *ciphertext Ciphertext to crypt.
504 * *ctlen Length of ciphertext.
507 * SNMPERR_SUCCESS Success.
508 * SNMPERR_SC_NOT_CONFIGURED Encryption is not supported.
509 * SNMPERR_SC_GENERAL_FAILURE Any other error
512 * Encrypt plaintext into ciphertext using key and iv.
514 * ctlen contains actual number of crypted bytes in ciphertext upon
518 sc_encrypt(const oid
* privtype
, size_t privtypelen
,
519 u_char
* key
, u_int keylen
,
520 u_char
* iv
, u_int ivlen
,
521 u_char
* plaintext
, u_int ptlen
,
522 u_char
* ciphertext
, size_t * ctlen
)
523 #if defined(USE_OPENSSL)
525 int rval
= SNMPERR_SUCCESS
;
526 u_int properlength
, properlength_iv
;
527 u_char pad_block
[128]; /* bigger than anything I need */
528 u_char my_iv
[128]; /* ditto */
529 int pad
, plast
, pad_size
;
531 DES_key_schedule key_sch
;
533 DES_key_schedule key_sched_store
;
534 DES_key_schedule
*key_sch
= &key_sched_store
;
536 DES_cblock key_struct
;
547 #if !defined(SCAPI_AUTHPRIV)
548 snmp_log(LOG_ERR
, "Encryption support not enabled.\n");
549 return SNMPERR_SC_NOT_CONFIGURED
;
552 if (!privtype
|| !key
|| !iv
|| !plaintext
|| !ciphertext
|| !ctlen
553 || (keylen
<= 0) || (ivlen
<= 0) || (ptlen
<= 0) || (*ctlen
<= 0)
554 || (privtypelen
!= USM_LENGTH_OID_TRANSFORM
)) {
555 QUITFUN(SNMPERR_GENERR
, sc_encrypt_quit
);
556 } else if (ptlen
> *ctlen
) {
557 QUITFUN(SNMPERR_GENERR
, sc_encrypt_quit
);
559 #ifdef SNMP_TESTING_CODE
561 size_t buf_len
= 128, out_len
= 0;
562 u_char
*buf
= (u_char
*) malloc(buf_len
);
565 if (sprint_realloc_hexstring(&buf
, &buf_len
, &out_len
, 1,
567 DEBUGMSGTL(("scapi", "encrypt: IV: %s/", buf
));
569 DEBUGMSGTL(("scapi", "encrypt: IV: %s [TRUNCATED]/", buf
));
572 if (sprint_realloc_hexstring(&buf
, &buf_len
, &out_len
, 1,
574 DEBUGMSG(("scapi", "%s\n", buf
));
576 DEBUGMSG(("scapi", "%s [TRUNCATED]\n", buf
));
579 if (sprint_realloc_hexstring(&buf
, &buf_len
, &out_len
, 1,
581 DEBUGMSGTL(("scapi", "encrypt: string: %s\n", buf
));
583 DEBUGMSGTL(("scapi", "encrypt: string: %s [TRUNCATED]\n",
589 "encrypt: malloc fail for debug output\n"));
592 #endif /* SNMP_TESTING_CODE */
596 * Determine privacy transform.
598 if (ISTRANSFORM(privtype
, DESPriv
)) {
599 properlength
= BYTESIZE(SNMP_TRANS_PRIVLEN_1DES
);
600 properlength_iv
= BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV
);
601 pad_size
= properlength
;
603 } else if (ISTRANSFORM(privtype
, AES128Priv
)) {
604 properlength
= BYTESIZE(SNMP_TRANS_PRIVLEN_AES128
);
605 properlength_iv
= BYTESIZE(SNMP_TRANS_PRIVLEN_AES128_IV
);
606 } else if (ISTRANSFORM(privtype
, AES192Priv
)) {
607 properlength
= BYTESIZE(SNMP_TRANS_PRIVLEN_AES192
);
608 properlength_iv
= BYTESIZE(SNMP_TRANS_PRIVLEN_AES192_IV
);
609 } else if (ISTRANSFORM(privtype
, AES256Priv
)) {
610 properlength
= BYTESIZE(SNMP_TRANS_PRIVLEN_AES256
);
611 properlength_iv
= BYTESIZE(SNMP_TRANS_PRIVLEN_AES256_IV
);
614 QUITFUN(SNMPERR_GENERR
, sc_encrypt_quit
);
617 if ((keylen
< properlength
) || (ivlen
< properlength_iv
)) {
618 QUITFUN(SNMPERR_GENERR
, sc_encrypt_quit
);
621 memset(my_iv
, 0, sizeof(my_iv
));
623 if (ISTRANSFORM(privtype
, DESPriv
)) {
626 * now calculate the padding needed
628 pad
= pad_size
- (ptlen
% pad_size
);
629 plast
= (int) ptlen
- (pad_size
- pad
);
632 if (ptlen
+ pad
> *ctlen
) {
633 QUITFUN(SNMPERR_GENERR
, sc_encrypt_quit
); /* not enough space */
635 if (pad
> 0) { /* copy data into pad block if needed */
636 memcpy(pad_block
, plaintext
+ plast
, pad_size
- pad
);
637 memset(&pad_block
[pad_size
- pad
], pad
, pad
); /* filling in padblock */
640 memcpy(key_struct
, key
, sizeof(key_struct
));
641 (void) DES_key_sched(&key_struct
, key_sch
);
643 memcpy(my_iv
, iv
, ivlen
);
647 DES_ncbc_encrypt(plaintext
, ciphertext
, plast
, key_sch
,
648 (DES_cblock
*) my_iv
, DES_ENCRYPT
);
651 * then encrypt the pad block
653 DES_ncbc_encrypt(pad_block
, ciphertext
+ plast
, pad_size
,
654 key_sch
, (DES_cblock
*) my_iv
, DES_ENCRYPT
);
655 *ctlen
= plast
+ pad_size
;
661 else if (ISTRANSFORM(privtype
, AES128Priv
) ||
662 ISTRANSFORM(privtype
, AES192Priv
) ||
663 ISTRANSFORM(privtype
, AES256Priv
)) {
664 (void) AES_set_encrypt_key(key
, properlength
*8, &aes_key
);
666 memcpy(my_iv
, iv
, ivlen
);
670 AES_cfb128_encrypt(plaintext
, ciphertext
, ptlen
,
671 &aes_key
, my_iv
, &new_ivlen
, AES_ENCRYPT
);
677 * clear memory just in case
679 memset(my_iv
, 0, sizeof(my_iv
));
680 memset(pad_block
, 0, sizeof(pad_block
));
681 memset(key_struct
, 0, sizeof(key_struct
));
683 memset(&key_sch
, 0, sizeof(key_sch
));
685 memset(&key_sched_store
, 0, sizeof(key_sched_store
));
688 memset(&aes_key
,0,sizeof(aes_key
));
692 } /* end sc_encrypt() */
696 # if USE_INTERNAL_MD5
698 snmp_log(LOG_ERR
, "Encryption support not enabled.\n");
699 DEBUGMSGTL(("scapi", "Encrypt function not defined.\n"));
700 return SNMPERR_SC_GENERAL_FAILURE
;
704 _SCAPI_NOT_CONFIGURED
705 # endif /* USE_INTERNAL_MD5 */
711 /*******************************************************************-o-******
726 * SNMPERR_SUCCESS Success.
727 * SNMPERR_SC_NOT_CONFIGURED Encryption is not supported.
728 * SNMPERR_SC_GENERAL_FAILURE Any other error
731 * Decrypt ciphertext into plaintext using key and iv.
733 * ptlen contains actual number of plaintext bytes in plaintext upon
737 sc_decrypt(const oid
* privtype
, size_t privtypelen
,
738 u_char
* key
, u_int keylen
,
739 u_char
* iv
, u_int ivlen
,
740 u_char
* ciphertext
, u_int ctlen
,
741 u_char
* plaintext
, size_t * ptlen
)
745 int rval
= SNMPERR_SUCCESS
;
748 DES_key_schedule key_sch
;
750 DES_key_schedule key_sched_store
;
751 DES_key_schedule
*key_sch
= &key_sched_store
;
753 DES_cblock key_struct
;
754 u_int properlength
, properlength_iv
;
762 if (!privtype
|| !key
|| !iv
|| !plaintext
|| !ciphertext
|| !ptlen
763 || (ctlen
<= 0) || (*ptlen
<= 0) || (*ptlen
< ctlen
)
764 || (privtypelen
!= USM_LENGTH_OID_TRANSFORM
)) {
765 QUITFUN(SNMPERR_GENERR
, sc_decrypt_quit
);
767 #ifdef SNMP_TESTING_CODE
769 size_t buf_len
= 128, out_len
= 0;
770 u_char
*buf
= (u_char
*) malloc(buf_len
);
773 if (sprint_realloc_hexstring(&buf
, &buf_len
, &out_len
, 1,
775 DEBUGMSGTL(("scapi", "decrypt: IV: %s/", buf
));
777 DEBUGMSGTL(("scapi", "decrypt: IV: %s [TRUNCATED]/", buf
));
780 if (sprint_realloc_hexstring(&buf
, &buf_len
, &out_len
, 1,
782 DEBUGMSG(("scapi", "%s\n", buf
));
784 DEBUGMSG(("scapi", "%s\n", buf
));
789 "decrypt: malloc fail for debug output\n"));
792 #endif /* SNMP_TESTING_CODE */
795 * Determine privacy transform.
797 if (ISTRANSFORM(privtype
, DESPriv
)) {
798 properlength
= BYTESIZE(SNMP_TRANS_PRIVLEN_1DES
);
799 properlength_iv
= BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV
);
801 } else if (ISTRANSFORM(privtype
, AES128Priv
)) {
802 properlength
= BYTESIZE(SNMP_TRANS_PRIVLEN_AES128
);
803 properlength_iv
= BYTESIZE(SNMP_TRANS_PRIVLEN_AES128_IV
);
804 } else if (ISTRANSFORM(privtype
, AES192Priv
)) {
805 properlength
= BYTESIZE(SNMP_TRANS_PRIVLEN_AES192
);
806 properlength_iv
= BYTESIZE(SNMP_TRANS_PRIVLEN_AES192_IV
);
807 } else if (ISTRANSFORM(privtype
, AES256Priv
)) {
808 properlength
= BYTESIZE(SNMP_TRANS_PRIVLEN_AES256
);
809 properlength_iv
= BYTESIZE(SNMP_TRANS_PRIVLEN_AES256_IV
);
812 QUITFUN(SNMPERR_GENERR
, sc_decrypt_quit
);
815 if ((keylen
< properlength
) || (ivlen
< properlength_iv
)) {
816 QUITFUN(SNMPERR_GENERR
, sc_decrypt_quit
);
819 memset(my_iv
, 0, sizeof(my_iv
));
820 if (ISTRANSFORM(privtype
, DESPriv
)) {
821 memcpy(key_struct
, key
, sizeof(key_struct
));
822 (void) DES_key_sched(&key_struct
, key_sch
);
824 memcpy(my_iv
, iv
, ivlen
);
825 DES_cbc_encrypt(ciphertext
, plaintext
, ctlen
, key_sch
,
826 (DES_cblock
*) my_iv
, DES_DECRYPT
);
830 else if (ISTRANSFORM(privtype
, AES128Priv
) ||
831 ISTRANSFORM(privtype
, AES192Priv
) ||
832 ISTRANSFORM(privtype
, AES256Priv
)) {
833 (void) AES_set_encrypt_key(key
, properlength
*8, &aes_key
);
835 memcpy(my_iv
, iv
, ivlen
);
839 AES_cfb128_encrypt(ciphertext
, plaintext
, ctlen
,
840 &aes_key
, my_iv
, &new_ivlen
, AES_DECRYPT
);
850 memset(&key_sch
, 0, sizeof(key_sch
));
852 memset(&key_sched_store
, 0, sizeof(key_sched_store
));
854 memset(key_struct
, 0, sizeof(key_struct
));
855 memset(my_iv
, 0, sizeof(my_iv
));
858 #else /* USE OPEN_SSL */
860 #if !defined(SCAPI_AUTHPRIV)
861 snmp_log(LOG_ERR
, "Encryption support not enabled.\n");
862 return SNMPERR_SC_NOT_CONFIGURED
;
864 # if USE_INTERNAL_MD5
866 DEBUGMSGTL(("scapi", "Decryption function not defined.\n"));
867 return SNMPERR_SC_GENERAL_FAILURE
;
871 _SCAPI_NOT_CONFIGURED
872 # endif /* USE_INTERNAL_MD5 */
875 #endif /* USE_OPENSSL */