scapi.c
上传用户:cxs890
上传日期:2021-05-22
资源大小:347k
文件大小:18k
源码类别:

SNMP编程

开发平台:

C/C++

  1. /*
  2.  * scapi.c
  3.  *
  4.  */
  5. #include <config.h>
  6. #include <sys/types.h>
  7. #if HAVE_WINSOCK_H
  8. #include <ip/socket.h>
  9. #endif
  10. #ifdef HAVE_STDLIB_H
  11. #include <stdlib.h>
  12. #endif
  13. #if HAVE_STRING_H
  14. #include <string.h>
  15. #else
  16. #include <strings.h>
  17. #endif
  18. #if TIME_WITH_SYS_TIME
  19. # ifdef WIN32
  20. #  include <sys/timeb.h>
  21. # else
  22. #  include <time.h>
  23. # endif
  24. # include <time.h>
  25. #else
  26. # if HAVE_SYS_TIME_H
  27. #  include <sys/time.h>
  28. # else
  29. #  include <time.h>
  30. # endif
  31. #endif
  32. #ifdef OS_VXWORKS
  33. #include <sys/times.h>
  34. #endif
  35. #ifdef HAVE_NETINET_IN_H
  36. #include <netinet/in.h>
  37. #endif
  38. #include <libsys/des.h>
  39. #ifdef USE_INTERNAL_MD5
  40. #include "md5.h"
  41. #endif
  42. #include "asn1.h"
  43. #include "tools.h"
  44. #include "snmp_api.h"
  45. #include "callback.h"
  46. #include "snmpusm.h"
  47. #include "keytools.h"
  48. #include "snmp_debug.h"
  49. #include "scapi.h"
  50. #include "snmp_impl.h"
  51. #include "system.h"
  52. #include "transform_oids.h"
  53. #ifdef USE_OPENSSL
  54. #include <openssl/hmac.h>
  55. #include <openssl/evp.h>
  56. #include <openssl/rand.h>
  57. #endif
  58. #ifdef SWITCH
  59. #include <libsys/sha.h>
  60. #endif
  61. #include <libsys/md5.h>
  62. #ifdef QUITFUN
  63. #undef QUITFUN
  64. #define QUITFUN(e, l)
  65. if (e != SNMPERR_SUCCESS) {
  66. rval = SNMPERR_SC_GENERAL_FAILURE;
  67. goto l ;
  68. }
  69. #endif
  70. extern void hmac_sha ( char* d,  int  ld,  char*  k, int  lk,   char* out );
  71. /*
  72.   sc_get_properlength(oid *hashtype, u_int hashtype_len):
  73.   Given a hashing type ("hashtype" and its length hashtype_len), return
  74.   the length of the hash result.
  75.   Returns either the length or SNMPERR_GENERR for an unknown hashing type.
  76. */
  77. int
  78. sc_get_properlength(oid *hashtype, u_int hashtype_len)
  79. {
  80.   DEBUGTRACE;
  81.   /*
  82.    * Determine transform type hash length.
  83.    */
  84.   if ( ISTRANSFORM(hashtype, HMACMD5Auth)) {
  85.     return BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5);
  86.   }
  87.   else if ( ISTRANSFORM(hashtype, HMACSHA1Auth) ) {
  88.     return BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
  89.   }
  90.   return SNMPERR_GENERR;
  91. }
  92. /*******************************************************************-o-******
  93.  * sc_init
  94.  *
  95.  * Returns:
  96.  * SNMPERR_SUCCESS Success.
  97.  */
  98. int
  99. sc_init(void)
  100. {
  101.   int rval = SNMPERR_SUCCESS;
  102. #ifndef USE_OPENSSL
  103. #ifdef USE_INTERNAL_MD5
  104.   struct timeval tv;
  105.   
  106.   DEBUGTRACE;
  107.   gettimeofday(&tv,(struct timezone *)0);
  108.   
  109.   srandom(tv.tv_sec ^ tv.tv_usec);
  110. #else
  111.   rval = SNMPERR_SC_NOT_CONFIGURED;
  112. #endif
  113.   /* XXX ogud: The only reason to do anything here with openssl is to 
  114.    * XXX ogud: seed random number generator 
  115.    */
  116. #endif  /* ifndef USE_OPENSSL */
  117. return rval;
  118. }  /* end sc_init() */
  119. /*******************************************************************-o-******
  120.  * sc_random
  121.  *
  122.  * Parameters:
  123.  * *buf Pre-allocated buffer.
  124.  * *buflen  Size of buffer.
  125.  *      
  126.  * Returns:
  127.  * SNMPERR_SUCCESS Success.
  128.  */
  129. int
  130. sc_random(u_char *buf, size_t *buflen)
  131. {
  132. #ifdef INCLUDE_SNMPV3
  133.   int rval = SNMPERR_SUCCESS;
  134. #ifdef USE_INTERNAL_MD5
  135.   int i;
  136.   int rndval;
  137.   u_char *ucp = buf;
  138. #endif
  139.   DEBUGTRACE;
  140. #ifdef USE_OPENSSL
  141.   RAND_bytes(buf, *buflen); /* will never fail */
  142. #else /* USE_INTERNAL_MD5 */
  143.   /* fill the buffer with random integers.  Note that random()
  144.      is defined in config.h and may not be truly the random()
  145.      system call if something better existed */
  146.   rval = *buflen - *buflen%sizeof(rndval);
  147.   for(i = 0; i < rval; i += sizeof(rndval)) {
  148.     rndval = random();
  149.     memcpy(ucp, &rndval, sizeof(rndval));
  150.     ucp += sizeof(rndval);
  151.   }
  152.   
  153.   rndval = random();
  154.   memcpy(ucp, &rndval, *buflen%sizeof(rndval));
  155.   
  156.   rval = SNMPERR_SUCCESS;
  157. #endif  /* USE_OPENSSL */
  158.   return rval;
  159. #else
  160. return -1;
  161. #endif /*  */
  162. }  /* end sc_random() */
  163. /*******************************************************************-o-******
  164.  * sc_generate_keyed_hash
  165.  *
  166.  * Parameters:
  167.  *  authtype Type of authentication transform.
  168.  *  authtypelen
  169.  * *key Pointer to key (Kul) to use in keyed hash.
  170.  *  keylen Length of key in bytes.
  171.  * *message Pointer to the message to hash.
  172.  *  msglen Length of the message.
  173.  * *MAC Will be returned with allocated bytes containg hash.
  174.  * *maclen Length of the hash buffer in bytes; also indicates
  175.  * whether the MAC should be truncated.
  176.  *      
  177.  * Returns:
  178.  * SNMPERR_SUCCESS Success.
  179.  * SNMPERR_GENERR All errs
  180.  *
  181.  *
  182.  * A hash of the first msglen bytes of message using a keyed hash defined
  183.  * by authtype is created and stored in MAC.  MAC is ASSUMED to be a buffer
  184.  * of at least maclen bytes.  If the length of the hash is greater than
  185.  * maclen, it is truncated to fit the buffer.  If the length of the hash is
  186.  * less than maclen, maclen set to the number of hash bytes generated.
  187.  *
  188.  * ASSUMED that the number of hash bits is a multiple of 8.
  189.  */
  190. int
  191. sc_generate_keyed_hash( oid *authtype, size_t authtypelen,
  192. u_char *key, u_int  keylen,
  193. u_char *message, u_int  msglen,
  194. u_char *MAC, size_t *maclen)
  195. {
  196. #ifdef INCLUDE_SNMPV3
  197.   int  rval  = SNMPERR_SUCCESS;
  198.   int  properlength;
  199.   u_char  buf[SNMP_MAXBUF_SMALL];
  200. #if  defined(USE_OPENSSL)
  201.   int  buf_len = sizeof(buf);
  202.   u_char *bufp = buf;
  203. #endif
  204.   
  205.   DEBUGTRACE;
  206. #ifdef SNMP_TESTING_CODE
  207. {
  208.   int i;
  209.   DEBUGMSG(("sc_generate_keyed_hash", "sc_generate_keyed_hash(): key=0x"));
  210.   for(i=0; i< keylen; i++)
  211.     DEBUGMSG(("sc_generate_keyed_hash", "%02x", key[i] & 0xff));
  212.   DEBUGMSG(("sc_generate_keyed_hash"," (%d)n", keylen));
  213. }
  214. #endif /* SNMP_TESTING_CODE */
  215. /*
  216.  * Sanity check.
  217.  */
  218.  if ( !authtype || !key || !message || !MAC || !maclen
  219.       || (keylen<=0) || (msglen<=0) || (*maclen<=0)
  220.       || (authtypelen != USM_LENGTH_OID_TRANSFORM) )
  221.    {
  222.      QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
  223.    }
  224.  
  225.  properlength = sc_get_properlength(authtype, authtypelen);
  226.  if (properlength == SNMPERR_GENERR)
  227.    return properlength;
  228.  
  229.  if ( ((int)keylen < properlength) ) {
  230.    QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
  231.  }
  232.  
  233. #ifdef USE_OPENSSL
  234.  /*
  235.   * Determine transform type.
  236.   */
  237.    if (ISTRANSFORM(authtype, HMACMD5Auth))
  238.      HMAC(EVP_md5(), key, keylen, message, msglen,  
  239.   buf, &buf_len);
  240.    else if (ISTRANSFORM(authtype, HMACSHA1Auth)) 
  241.      HMAC(EVP_sha1(), key, keylen, message, msglen,  
  242.   buf, &buf_len);
  243.    else {
  244.      QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
  245.    }
  246.    if (buf_len != properlength) {
  247.      QUITFUN(rval, sc_generate_keyed_hash_quit);
  248.    }
  249.    if (*maclen > buf_len) 
  250.      *maclen = buf_len;
  251.    memcpy(MAC, buf, *maclen);
  252. #else 
  253.  if ((int)*maclen > properlength)
  254.    *maclen = properlength;
  255.    if (ISTRANSFORM(authtype, HMACMD5Auth))
  256.      hmac_md5(message, msglen, key, keylen, MAC);
  257.    else if (ISTRANSFORM(authtype, HMACSHA1Auth))
  258.      hmac_sha(message, msglen, key, keylen, MAC);
  259.    else {
  260.      QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
  261.    }
  262. #endif /* USE_OPENSSL */
  263. #ifdef SNMP_TESTING_CODE
  264.  {
  265.    char    *s;
  266.    int      len = binary_to_hex(MAC, *maclen, &s);
  267.    
  268.    DEBUGMSGTL(("scapi","Full v3 message hash: %sn", s));
  269.    SNMP_ZERO(s, len);
  270.    SNMP_FREE(s);
  271.  }
  272. #endif
  273.  
  274.  sc_generate_keyed_hash_quit:
  275.  SNMP_ZERO(buf, SNMP_MAXBUF_SMALL);
  276.  return rval;
  277. #else
  278. return -1;
  279. #endif /* */
  280. }  /* end sc_generate_keyed_hash() */
  281. /* sc_hash(): a generic wrapper around whatever hashing package we are using.
  282.    IN:
  283.      hashtype    - oid pointer to a hash type
  284.      hashtypelen - length of oid pointer
  285.      buf         - u_char buffer to be hashed
  286.      buf_len     - integer length of buf data
  287.      MAC_len     - length of the passed MAC buffer size.
  288.     
  289.    OUT:    
  290.      MAC         - pre-malloced space to store hash output.
  291.      MAC_len     - length of MAC output to the MAC buffer.
  292.    Returns:
  293.      SNMPERR_SUCCESS Success.
  294.      SNMP_SC_GENERAL_FAILURE Any error.
  295. */
  296. int
  297. sc_hash(oid *hashtype, size_t hashtypelen, u_char *buf, size_t buf_len,
  298.         u_char *MAC, size_t *MAC_len)
  299. {
  300. #ifdef INCLUDE_SNMPV3
  301. #ifdef USE_OPENSSL 
  302.   int   rval       = SNMPERR_SUCCESS;
  303.   EVP_MD *hash(void);
  304.   HMAC_CTX *c = NULL; 
  305. #endif
  306.   DEBUGTRACE;
  307.   if (hashtype == NULL || hashtypelen < 0 || buf == NULL ||
  308.       buf_len < 0 || MAC == NULL ||  MAC_len == NULL ||
  309.       (int)(*MAC_len) < sc_get_properlength(hashtype, hashtypelen))
  310.     return (SNMPERR_GENERR);
  311. #ifdef USE_OPENSSL 
  312.   /*
  313.    * Determine transform type.
  314.    */
  315.   c = malloc(sizeof(HMAC_CTX));
  316.   if (c == NULL)
  317.     return (SNMPERR_GENERR);
  318.   if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
  319.     EVP_DigestInit(&c->md_ctx, (const EVP_MD *) EVP_md5());
  320.   }
  321.   else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {
  322.     EVP_DigestInit(&c->md_ctx, (const EVP_MD *) EVP_sha1());
  323.   }
  324.   else {
  325.     return(SNMPERR_GENERR);
  326.   }
  327.   EVP_DigestUpdate(&c->md_ctx, buf, buf_len);
  328.   EVP_DigestFinal(&(c->md_ctx), MAC, MAC_len);
  329.   free(c);
  330.   return (rval);
  331. #else /* USE_INTERNAL_MD5 */
  332.   if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
  333.     md5Digest(buf, buf_len, MAC);
  334.   }
  335.   else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {
  336.     SHABlock(buf, buf_len, MAC);
  337.   }
  338.   else
  339.     return(SNMPERR_GENERR);
  340.   if (*MAC_len > 16)
  341.     *MAC_len = 16;
  342.   return SNMPERR_SUCCESS;
  343. #endif
  344. #else 
  345. return -1;
  346. #endif /* INCLUDE_SNMPV3 */
  347. }
  348. /*******************************************************************-o-******
  349.  * sc_check_keyed_hash
  350.  *
  351.  * Parameters:
  352.  *  authtype Transform type of authentication hash.
  353.  * *key Key bits in a string of bytes.
  354.  *  keylen Length of key in bytes.
  355.  * *message Message for which to check the hash.
  356.  *  msglen Length of message.
  357.  * *MAC Given hash.
  358.  *  maclen Length of given hash; indicates truncation if it is
  359.  * shorter than the normal size of output for
  360.  * given hash transform.
  361.  * Returns:
  362.  * SNMPERR_SUCCESS Success.
  363.  * SNMP_SC_GENERAL_FAILURE Any error
  364.  *
  365.  *
  366.  * Check the hash given in MAC against the hash of message.  If the length
  367.  * of MAC is less than the length of the transform hash output, only maclen
  368.  * bytes are compared.  The length of MAC cannot be greater than the
  369.  * length of the hash transform output.
  370.  */
  371. int
  372. sc_check_keyed_hash( oid *authtype, size_t authtypelen,
  373. u_char *key, u_int keylen,
  374. u_char *message, u_int msglen,
  375. u_char *MAC, u_int maclen)
  376. {
  377. #ifdef INCLUDE_SNMPV3
  378. int  rval  = SNMPERR_SUCCESS;
  379. size_t  buf_len = SNMP_MAXBUF_SMALL;
  380. u_char  buf[SNMP_MAXBUF_SMALL];
  381.         DEBUGTRACE;
  382. #ifdef SNMP_TESTING_CODE
  383. {
  384.  int i;
  385.  DEBUGMSG(("scapi", "sc_check_keyed_hash():    key=0x"));
  386.  for(i=0; i< keylen; i++)
  387.    DEBUGMSG(("scapi", "%02x", key[i] & 0xff));
  388.  DEBUGMSG(("scapi"," (%d)n", keylen));
  389. }
  390. #endif /* SNMP_TESTING_CODE */
  391. /*
  392.  * Sanity check.
  393.  */
  394. if ( !authtype || !key || !message || !MAC 
  395. || (keylen<=0) || (msglen<=0) || (maclen<=0)
  396. || (authtypelen != USM_LENGTH_OID_TRANSFORM) )
  397. {
  398. QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);
  399. }
  400. /* 
  401.  * Generate a full hash of the message, then compare
  402.  * the result with the given MAC which may shorter than
  403.  * the full hash length.
  404.  */
  405. rval = sc_generate_keyed_hash( authtype, authtypelen,
  406. key, keylen,
  407. message, msglen,
  408. buf, &buf_len);
  409. QUITFUN(rval, sc_check_keyed_hash_quit);
  410. if (maclen > msglen) {
  411. QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);
  412. } else if ( memcmp(buf, MAC, maclen) != 0 ) {
  413. QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);
  414. }
  415. sc_check_keyed_hash_quit:
  416. SNMP_ZERO(buf, SNMP_MAXBUF_SMALL);
  417. return rval;
  418. #else
  419. return -1;
  420. #endif /*INCLUDE_SNMPV3*/
  421. }  /* end sc_check_keyed_hash() */
  422. /*******************************************************************-o-******
  423.  * sc_encrypt
  424.  *
  425.  * Parameters:
  426.  *  privtype Type of privacy cryptographic transform.
  427.  * *key Key bits for crypting.
  428.  *  keylen Length of key (buffer) in bytes.
  429.  * *iv IV bits for crypting.
  430.  *  ivlen Length of iv (buffer) in bytes.
  431.  * *plaintext Plaintext to crypt.
  432.  *  ptlen Length of plaintext.
  433.  * *ciphertext Ciphertext to crypt.
  434.  * *ctlen Length of ciphertext.
  435.  *      
  436.  * Returns:
  437.  * SNMPERR_SUCCESS Success.
  438.  * SNMPERR_SC_NOT_CONFIGURED Encryption is not supported.
  439.  * SNMPERR_SC_GENERAL_FAILURE Any other error
  440.  *
  441.  *
  442.  * Encrypt plaintext into ciphertext using key and iv.
  443.  *
  444.  * ctlen contains actual number of crypted bytes in ciphertext upon
  445.  * successful return.
  446.  */
  447. int
  448. sc_encrypt( oid    *privtype, size_t privtypelen,
  449. u_char *key, u_int  keylen,
  450. u_char *iv, u_int  ivlen,
  451. u_char *plaintext, u_int  ptlen,
  452. u_char *ciphertext, size_t *ctlen)
  453. {
  454. #ifdef INCLUDE_SNMPV3
  455. int rval = SNMPERR_SUCCESS;
  456. /* u_int transform;*/
  457. u_int properlength,
  458.        properlength_iv;
  459. u_char pad_block[128];  /* bigger than anything I need */
  460. u_char          my_iv[128];      /* ditto */
  461. int pad, plast, pad_size;
  462. des_key_schedule key_sch;
  463. des_cblock      key_struct;
  464.         DEBUGTRACE;
  465. /*
  466.  * Sanity check.
  467.  */
  468. #if !defined(SCAPI_AUTHPRIV)
  469. return SNMPERR_SC_NOT_CONFIGURED;
  470. #endif
  471. if ( !privtype || !key || !iv || !plaintext || !ciphertext || !ctlen
  472. || (keylen<=0) || (ivlen<=0) || (ptlen<=0) || (*ctlen<=0)
  473. || (privtypelen != USM_LENGTH_OID_TRANSFORM) )
  474. {
  475. QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
  476. }
  477. else if ( ptlen > *ctlen) { 
  478. QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
  479. }
  480. #ifdef SNMP_TESTING_CODE
  481. {
  482.         char buf[SNMP_MAXBUF];
  483. sprint_hexstring(buf, iv, ivlen);
  484.         DEBUGMSGTL(("scapi", "encrypt: IV: %s/ ", buf));
  485. sprint_hexstring(buf, key, keylen);
  486.         DEBUGMSG(("scapi","%sn", buf));
  487. sprint_hexstring(buf, plaintext, 16);
  488.         DEBUGMSGTL(("scapi","encrypt: string: %sn", buf));
  489. }
  490. #endif /* SNMP_TESTING_CODE */
  491. /*
  492.  * Determine privacy transform.
  493.  */
  494. if ( ISTRANSFORM(privtype, DESPriv) ) {
  495. properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
  496. properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
  497. pad_size = properlength;
  498. } else {
  499. QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
  500. }
  501. if ( (keylen<properlength) || (ivlen<properlength_iv) ) {
  502. QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
  503. }
  504. else if ( (keylen<properlength) || (ivlen<properlength_iv) ) {
  505. QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
  506. }
  507. /* now calculate the padding needed */
  508. pad = pad_size - (ptlen % pad_size);
  509.     plast = (int) ptlen - (pad_size - pad);
  510.     if (pad == pad_size)
  511.         pad = 0;
  512. if (ptlen + pad > *ctlen) { 
  513. QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); /* not enough space */
  514. }
  515. /* memset(pad_block, 0, sizeof(pad_block));
  516. plast = (int) ptlen - (pad_size - pad);*/
  517. if (pad > 0)  /* copy data into pad block if needed */ {
  518. memcpy( pad_block, plaintext + plast, pad_size - pad);
  519.      memset(&pad_block[pad_size-pad], pad, pad); /* filling in padblock */
  520. }
  521. memset(my_iv, 0, sizeof(my_iv));
  522. if ( ISTRANSFORM(privtype, DESPriv) ) {
  523.                 memcpy(key_struct, key, sizeof(key_struct));
  524. (void) DES_key_sched(&key_struct, key_sch);
  525. memcpy(my_iv, iv, ivlen);
  526. /* encrypt the data */
  527. DES_ncbc_encrypt(plaintext, ciphertext, plast, key_sch, 
  528.  (des_cblock *) &my_iv, DES_ENCRYPT);
  529. /* then encrypt the pad block */
  530. if (pad > 0) {
  531.      DES_ncbc_encrypt(pad_block, ciphertext+plast, pad_size, 
  532.       key_sch, (des_cblock *)&my_iv, DES_ENCRYPT);
  533.      *ctlen = plast + pad_size;
  534. } else {
  535.     *ctlen = plast;
  536. }
  537. }
  538. sc_encrypt_quit:
  539. /* clear memory just in case */
  540. memset(my_iv, 0, sizeof(my_iv));
  541. memset(pad_block, 0, sizeof(pad_block));
  542. memset(key_struct, 0, sizeof(key_struct));
  543. memset(key_sch, 0, sizeof(key_sch));
  544. return rval;
  545. #else
  546. return -1;
  547. #endif /*INCLUDE_SNMPV3*/
  548. }  /* end sc_encrypt() */
  549. /*******************************************************************-o-******
  550.  * sc_decrypt
  551.  *
  552.  * Parameters:
  553.  *  privtype
  554.  * *key
  555.  *  keylen
  556.  * *iv
  557.  *  ivlen
  558.  * *ciphertext
  559.  *  ctlen
  560.  * *plaintext
  561.  * *ptlen
  562.  *      
  563.  * Returns:
  564.  * SNMPERR_SUCCESS Success.
  565.  * SNMPERR_SC_NOT_CONFIGURED Encryption is not supported.
  566.  *      SNMPERR_SC_GENERAL_FAILURE      Any other error
  567.  *
  568.  *
  569.  * Decrypt ciphertext into plaintext using key and iv.
  570.  *
  571.  * ptlen contains actual number of plaintext bytes in plaintext upon
  572.  * successful return.
  573.  */
  574. int
  575. sc_decrypt( oid    *privtype, size_t privtypelen,
  576. u_char *key, u_int  keylen,
  577. u_char *iv, u_int  ivlen,
  578. u_char *ciphertext, u_int  ctlen,
  579. u_char *plaintext, size_t *ptlen)
  580. {
  581. #ifdef INCLUDE_SNMPV3
  582. int rval = SNMPERR_SUCCESS;
  583. /* int i, j;*/ 
  584. u_char my_iv[128];
  585. des_key_schedule key_sch;
  586. des_cblock  key_struct;
  587. u_int properlength,
  588. properlength_iv;
  589.         DEBUGTRACE;
  590. if ( !privtype || !key || !iv || !plaintext || !ciphertext || !ptlen
  591. || (ctlen<=0) || (*ptlen<=0) || (*ptlen < ctlen)
  592. || (privtypelen != USM_LENGTH_OID_TRANSFORM) )
  593. {
  594. QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
  595. }
  596. #ifdef SNMP_TESTING_CODE
  597. {
  598.         char buf[SNMP_MAXBUF];
  599. sprint_hexstring(buf, iv, ivlen);
  600.         DEBUGMSGTL(("scapi", "decrypt: IV: %s/ ", buf));
  601. sprint_hexstring(buf, key, keylen);
  602.         DEBUGMSG(("scapi","%sn", buf));
  603. }
  604. #endif /* SNMP_TESTING_CODE */
  605. /*
  606.  * Determine privacy transform.
  607.  */
  608. if ( ISTRANSFORM(privtype, DESPriv) ) {
  609. properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
  610. properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
  611. } else {
  612. QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
  613. }
  614. if ( (keylen<properlength) || (ivlen<properlength_iv) ) {
  615. QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
  616. }
  617. memset(my_iv, 0, sizeof(my_iv));
  618. if (ISTRANSFORM(privtype, DESPriv)) {
  619.                 memcpy(key_struct, key, sizeof(key_struct));
  620. (void) /*des_key_sched*/DES_key_sched(&key_struct, key_sch);
  621. memcpy(my_iv, iv, ivlen);
  622. /*des_cbc_encrypt*/DES_cbc_encrypt(ciphertext, plaintext, ctlen, key_sch, 
  623. (des_cblock *) &my_iv, DES_DECRYPT);
  624.         *ptlen = ctlen;
  625. }
  626. /* exit cond */
  627. sc_decrypt_quit:
  628. memset(key_sch, 0, sizeof(key_sch));
  629. memset(key_struct, 0, sizeof(key_struct));
  630. memset(my_iv, 0, sizeof(my_iv));
  631. return rval;
  632. #else
  633. return -1;
  634. #endif /*INCLUDE_SNMPV3*/
  635. }