OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [snmp/] [lib/] [v2_0/] [src/] [scapi.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      ./lib/current/src/scapi.c
4
//
5
//
6
//==========================================================================
7
//####ECOSGPLCOPYRIGHTBEGIN####
8
// -------------------------------------------
9
// This file is part of eCos, the Embedded Configurable Operating System.
10
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
11
//
12
// eCos is free software; you can redistribute it and/or modify it under
13
// the terms of the GNU General Public License as published by the Free
14
// Software Foundation; either version 2 or (at your option) any later version.
15
//
16
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
17
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19
// for more details.
20
//
21
// You should have received a copy of the GNU General Public License along
22
// with eCos; if not, write to the Free Software Foundation, Inc.,
23
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24
//
25
// As a special exception, if other files instantiate templates or use macros
26
// or inline functions from this file, or you compile this file and link it
27
// with other works to produce a work based on this file, this file does not
28
// by itself cause the resulting work to be covered by the GNU General Public
29
// License. However the source code for this file must still be made available
30
// in accordance with section (3) of the GNU General Public License.
31
//
32
// This exception does not invalidate any other reasons why a work based on
33
// this file might be covered by the GNU General Public License.
34
//
35
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
36
// at http://sources.redhat.com/ecos/ecos-license/
37
// -------------------------------------------
38
//####ECOSGPLCOPYRIGHTEND####
39
//####UCDSNMPCOPYRIGHTBEGIN####
40
//
41
// -------------------------------------------
42
//
43
// Portions of this software may have been derived from the UCD-SNMP
44
// project,  <http://ucd-snmp.ucdavis.edu/>  from the University of
45
// California at Davis, which was originally based on the Carnegie Mellon
46
// University SNMP implementation.  Portions of this software are therefore
47
// covered by the appropriate copyright disclaimers included herein.
48
//
49
// The release used was version 4.1.2 of May 2000.  "ucd-snmp-4.1.2"
50
// -------------------------------------------
51
//
52
//####UCDSNMPCOPYRIGHTEND####
53
//==========================================================================
54
//#####DESCRIPTIONBEGIN####
55
//
56
// Author(s):    hmt
57
// Contributors: hmt
58
// Date:         2000-05-30
59
// Purpose:      Port of UCD-SNMP distribution to eCos.
60
// Description:  
61
//              
62
//
63
//####DESCRIPTIONEND####
64
//
65
//==========================================================================
66
/********************************************************************
67
       Copyright 1989, 1991, 1992 by Carnegie Mellon University
68
 
69
                          Derivative Work -
70
Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
71
 
72
                         All Rights Reserved
73
 
74
Permission to use, copy, modify and distribute this software and its
75
documentation for any purpose and without fee is hereby granted,
76
provided that the above copyright notice appears in all copies and
77
that both that copyright notice and this permission notice appear in
78
supporting documentation, and that the name of CMU and The Regents of
79
the University of California not be used in advertising or publicity
80
pertaining to distribution of the software without specific written
81
permission.
82
 
83
CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL
84
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
85
WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL CMU OR
86
THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,
87
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
88
FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
89
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
90
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
91
*********************************************************************/
92
/*
93
 * scapi.c
94
 *
95
 */
96
 
97
#include <config.h>
98
 
99
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
100
#include <sys/types.h>
101
#if HAVE_WINSOCK_H
102
#include <winsock.h>
103
#endif
104
#ifdef HAVE_STDLIB_H
105
#include <stdlib.h>
106
#endif
107
#if HAVE_STRING_H
108
#include <string.h>
109
#else
110
#include <strings.h>
111
#endif
112
#if TIME_WITH_SYS_TIME
113
# ifdef WIN32
114
#  include <sys/timeb.h>
115
# else
116
#  include <sys/time.h>
117
# endif
118
# include <time.h>
119
#else
120
# if HAVE_SYS_TIME_H
121
#  include <sys/time.h>
122
# else
123
#  include <time.h>
124
# endif
125
#endif
126
#ifdef HAVE_NETINET_IN_H
127
#include <netinet/in.h>
128
#endif
129
 
130
#ifdef USE_INTERNAL_MD5
131
#include "md5.h"
132
#endif
133
#include "asn1.h"
134
#include "tools.h"
135
#include "snmp_api.h"
136
#include "callback.h"
137
#include "snmpusm.h"
138
#include "keytools.h"
139
#include "snmp_debug.h"
140
#include "scapi.h"
141
#include "snmp_impl.h"
142
#include "system.h"
143
 
144
#include "transform_oids.h"
145
 
146
#ifdef USE_OPENSSL
147
#include <openssl/hmac.h>
148
#include <openssl/evp.h>
149
#include <openssl/rand.h>
150
#endif
151
 
152
#ifdef QUITFUN
153
#undef QUITFUN
154
#define QUITFUN(e, l)                                   \
155
        if (e != SNMPERR_SUCCESS) {                     \
156
                rval = SNMPERR_SC_GENERAL_FAILURE;      \
157
                goto l ;                                \
158
        }
159
#endif
160
 
161
 
162
/*
163
  sc_get_properlength(oid *hashtype, u_int hashtype_len):
164
 
165
  Given a hashing type ("hashtype" and its length hashtype_len), return
166
  the length of the hash result.
167
 
168
  Returns either the length or SNMPERR_GENERR for an unknown hashing type.
169
*/
170
int
171
sc_get_properlength(oid *hashtype, u_int hashtype_len)
172
{
173
  DEBUGTRACE;
174
  /*
175
   * Determine transform type hash length.
176
   */
177
  if ( ISTRANSFORM(hashtype, HMACMD5Auth)) {
178
    return BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5);
179
  }
180
  else if ( ISTRANSFORM(hashtype, HMACSHA1Auth) ) {
181
    return BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
182
  }
183
  return SNMPERR_GENERR;
184
}
185
 
186
 
187
/*******************************************************************-o-******
188
 * sc_init
189
 *
190
 * Returns:
191
 *      SNMPERR_SUCCESS                 Success.
192
 */
193
int
194
sc_init(void)
195
{
196
  int           rval = SNMPERR_SUCCESS;
197
 
198
#ifndef USE_OPENSSL
199
#ifdef USE_INTERNAL_MD5
200
  struct timeval tv;
201
 
202
  DEBUGTRACE;
203
 
204
  gettimeofday(&tv,(struct timezone *)0);
205
 
206
  srandom(tv.tv_sec ^ tv.tv_usec);
207
#else
208
  rval = SNMPERR_SC_NOT_CONFIGURED;
209
#endif
210
  /* XXX ogud: The only reason to do anything here with openssl is to
211
   * XXX ogud: seed random number generator
212
   */
213
#endif  /* ifndef USE_OPENSSL */
214
        return rval;
215
}  /* end sc_init() */
216
 
217
/*******************************************************************-o-******
218
 * sc_random
219
 *
220
 * Parameters:
221
 *      *buf            Pre-allocated buffer.
222
 *      *buflen         Size of buffer.
223
 *
224
 * Returns:
225
 *      SNMPERR_SUCCESS                 Success.
226
 */
227
int
228
sc_random(u_char *buf, size_t *buflen)
229
#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
230
{
231
  int           rval = SNMPERR_SUCCESS;
232
#ifdef USE_INTERNAL_MD5
233
  int i;
234
  int rndval;
235
  u_char *ucp = buf;
236
#endif
237
 
238
  DEBUGTRACE;
239
 
240
#ifdef USE_OPENSSL
241
  RAND_bytes(buf, *buflen); /* will never fail */
242
#else   /* USE_INTERNAL_MD5 */
243
  /* fill the buffer with random integers.  Note that random()
244
     is defined in config.h and may not be truly the random()
245
     system call if something better existed */
246
  rval = *buflen - *buflen%sizeof(rndval);
247
  for(i = 0; i < rval; i += sizeof(rndval)) {
248
    rndval = random();
249
    memcpy(ucp, &rndval, sizeof(rndval));
250
    ucp += sizeof(rndval);
251
  }
252
 
253
  rndval = random();
254
  memcpy(ucp, &rndval, *buflen%sizeof(rndval));
255
 
256
  rval = SNMPERR_SUCCESS;
257
#endif  /* USE_OPENSSL */
258
  return rval;
259
 
260
}  /* end sc_random() */
261
 
262
#else
263
_SCAPI_NOT_CONFIGURED
264
#endif                                                  /*  */
265
 
266
 
267
 
268
/*******************************************************************-o-******
269
 * sc_generate_keyed_hash
270
 *
271
 * Parameters:
272
 *       authtype       Type of authentication transform.
273
 *       authtypelen
274
 *      *key            Pointer to key (Kul) to use in keyed hash.
275
 *       keylen         Length of key in bytes.
276
 *      *message        Pointer to the message to hash.
277
 *       msglen         Length of the message.
278
 *      *MAC            Will be returned with allocated bytes containg hash.
279
 *      *maclen         Length of the hash buffer in bytes; also indicates
280
 *                              whether the MAC should be truncated.
281
 *
282
 * Returns:
283
 *      SNMPERR_SUCCESS                 Success.
284
 *      SNMPERR_GENERR                  All errs
285
 *
286
 *
287
 * A hash of the first msglen bytes of message using a keyed hash defined
288
 * by authtype is created and stored in MAC.  MAC is ASSUMED to be a buffer
289
 * of at least maclen bytes.  If the length of the hash is greater than
290
 * maclen, it is truncated to fit the buffer.  If the length of the hash is
291
 * less than maclen, maclen set to the number of hash bytes generated.
292
 *
293
 * ASSUMED that the number of hash bits is a multiple of 8.
294
 */
295
int
296
sc_generate_keyed_hash( oid     *authtype,      size_t authtypelen,
297
                        u_char  *key,           u_int  keylen,
298
                        u_char  *message,       u_int  msglen,
299
                        u_char  *MAC,           size_t *maclen)
300
#if  defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
301
{
302
  int            rval    = SNMPERR_SUCCESS;
303
  int            properlength;
304
 
305
  u_char         buf[SNMP_MAXBUF_SMALL];
306
#if  defined(USE_OPENSSL)
307
  int            buf_len = sizeof(buf);
308
  u_char        *bufp = buf;
309
#endif
310
 
311
  DEBUGTRACE;
312
 
313
#ifdef SNMP_TESTING_CODE
314
{
315
  int i;
316
  DEBUGMSG(("sc_generate_keyed_hash", "sc_generate_keyed_hash(): key=0x"));
317
  for(i=0; i< keylen; i++)
318
    DEBUGMSG(("sc_generate_keyed_hash", "%02x", key[i] & 0xff));
319
  DEBUGMSG(("sc_generate_keyed_hash"," (%d)\n", keylen));
320
}
321
#endif /* SNMP_TESTING_CODE */
322
 
323
/*
324
 * Sanity check.
325
 */
326
 if ( !authtype || !key || !message || !MAC || !maclen
327
      || (keylen<=0) || (msglen<=0) || (*maclen<=0)
328
      || (authtypelen != USM_LENGTH_OID_TRANSFORM) )
329
   {
330
     QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
331
   }
332
 
333
 properlength = sc_get_properlength(authtype, authtypelen);
334
 if (properlength == SNMPERR_GENERR)
335
   return properlength;
336
 
337
 if ( ((int)keylen < properlength) ) {
338
   QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
339
 }
340
 
341
 
342
#ifdef USE_OPENSSL
343
 /*
344
  * Determine transform type.
345
  */
346
   if (ISTRANSFORM(authtype, HMACMD5Auth))
347
     HMAC(EVP_md5(), key, keylen, message, msglen,
348
          buf, &buf_len);
349
   else if (ISTRANSFORM(authtype, HMACSHA1Auth))
350
     HMAC(EVP_sha1(), key, keylen, message, msglen,
351
          buf, &buf_len);
352
   else {
353
     QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);
354
   }
355
   if (buf_len != properlength) {
356
     QUITFUN(rval, sc_generate_keyed_hash_quit);
357
   }
358
   if (*maclen > buf_len)
359
     *maclen = buf_len;
360
   memcpy(MAC, buf, *maclen);
361
#else 
362
 if ((int)*maclen > properlength)
363
   *maclen = properlength;
364
 if (MDsign(message, msglen, MAC, *maclen, key, keylen)) {
365
   rval = SNMPERR_GENERR;
366
   goto sc_generate_keyed_hash_quit;
367
 }
368
#endif /* USE_OPENSSL */
369
 
370
#ifdef SNMP_TESTING_CODE
371
 {
372
   char    *s;
373
   int      len = binary_to_hex(MAC, *maclen, &s);
374
 
375
   DEBUGMSGTL(("scapi","Full v3 message hash: %s\n", s));
376
   SNMP_ZERO(s, len);
377
   SNMP_FREE(s);
378
 }
379
#endif
380
 
381
 sc_generate_keyed_hash_quit:
382
 SNMP_ZERO(buf, SNMP_MAXBUF_SMALL);
383
 return rval;
384
}  /* end sc_generate_keyed_hash() */
385
 
386
#else
387
_SCAPI_NOT_CONFIGURED
388
#endif                                                  /* */
389
 
390
 
391
/* sc_hash(): a generic wrapper around whatever hashing package we are using.
392
 
393
   IN:
394
     hashtype    - oid pointer to a hash type
395
     hashtypelen - length of oid pointer
396
     buf         - u_char buffer to be hashed
397
     buf_len     - integer length of buf data
398
     MAC_len     - length of the passed MAC buffer size.
399
 
400
   OUT:
401
     MAC         - pre-malloced space to store hash output.
402
     MAC_len     - length of MAC output to the MAC buffer.
403
 
404
   Returns:
405
     SNMPERR_SUCCESS            Success.
406
     SNMP_SC_GENERAL_FAILURE    Any error.
407
*/
408
 
409
int
410
sc_hash(oid *hashtype, size_t hashtypelen, u_char *buf, size_t buf_len,
411
        u_char *MAC, size_t *MAC_len)
412
#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
413
{
414
  int   rval       = SNMPERR_SUCCESS;
415
 
416
#ifdef USE_OPENSSL 
417
  EVP_MD *hash(void);
418
  HMAC_CTX *c = NULL;
419
#endif
420
 
421
  DEBUGTRACE;
422
 
423
  if (hashtype == NULL || hashtypelen < 0 || buf == NULL ||
424
      buf_len < 0 || MAC == NULL ||  MAC_len == NULL ||
425
      (int)(*MAC_len) < sc_get_properlength(hashtype, hashtypelen))
426
    return (SNMPERR_GENERR);
427
 
428
#ifdef USE_OPENSSL 
429
  /*
430
   * Determine transform type.
431
   */
432
  c = malloc(sizeof(HMAC_CTX));
433
  if (c == NULL)
434
    return (SNMPERR_GENERR);
435
 
436
  if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
437
    EVP_DigestInit(&c->md_ctx, (const EVP_MD *) EVP_md5());
438
  }
439
  else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {
440
    EVP_DigestInit(&c->md_ctx, (const EVP_MD *) EVP_sha1());
441
  }
442
  else {
443
    return(SNMPERR_GENERR);
444
  }
445
  EVP_DigestUpdate(&c->md_ctx, buf, buf_len);
446
  EVP_DigestFinal(&(c->md_ctx), MAC, MAC_len);
447
  free(c);
448
  return (rval);
449
#else /* USE_INTERNAL_MD5 */
450
 
451
  if (MDchecksum(buf, buf_len, MAC, *MAC_len)) {
452
    return SNMPERR_GENERR;
453
  }
454
  if (*MAC_len > 16)
455
    *MAC_len = 16;
456
  return (rval);
457
 
458
#endif /* USE_OPENSSL */
459
}
460
#else /* !defined(USE_OPENSSL) && !defined(USE_INTERNAL_MD5) */
461
_SCAPI_NOT_CONFIGURED
462
#endif /* !defined(USE_OPENSSL) && !defined(USE_INTERNAL_MD5) */
463
 
464
 
465
 
466
/*******************************************************************-o-******
467
 * sc_check_keyed_hash
468
 *
469
 * Parameters:
470
 *       authtype       Transform type of authentication hash.
471
 *      *key            Key bits in a string of bytes.
472
 *       keylen         Length of key in bytes.
473
 *      *message        Message for which to check the hash.
474
 *       msglen         Length of message.
475
 *      *MAC            Given hash.
476
 *       maclen         Length of given hash; indicates truncation if it is
477
 *                              shorter than the normal size of output for
478
 *                              given hash transform.
479
 * Returns:
480
 *      SNMPERR_SUCCESS         Success.
481
 *      SNMP_SC_GENERAL_FAILURE Any error
482
 *
483
 *
484
 * Check the hash given in MAC against the hash of message.  If the length
485
 * of MAC is less than the length of the transform hash output, only maclen
486
 * bytes are compared.  The length of MAC cannot be greater than the
487
 * length of the hash transform output.
488
 */
489
int
490
sc_check_keyed_hash(    oid     *authtype,      size_t authtypelen,
491
                        u_char  *key,           u_int keylen,
492
                        u_char  *message,       u_int msglen,
493
                        u_char  *MAC,           u_int maclen)
494
#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
495
{
496
        int              rval    = SNMPERR_SUCCESS;
497
        size_t           buf_len = SNMP_MAXBUF_SMALL;
498
 
499
        u_char           buf[SNMP_MAXBUF_SMALL];
500
 
501
        DEBUGTRACE;
502
 
503
#ifdef SNMP_TESTING_CODE
504
{
505
 int i;
506
 DEBUGMSG(("scapi", "sc_check_keyed_hash():    key=0x"));
507
 for(i=0; i< keylen; i++)
508
   DEBUGMSG(("scapi", "%02x", key[i] & 0xff));
509
 DEBUGMSG(("scapi"," (%d)\n", keylen));
510
}
511
#endif /* SNMP_TESTING_CODE */
512
 
513
        /*
514
         * Sanity check.
515
         */
516
        if ( !authtype || !key || !message || !MAC
517
                || (keylen<=0) || (msglen<=0) || (maclen<=0)
518
                || (authtypelen != USM_LENGTH_OID_TRANSFORM) )
519
        {
520
                QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);
521
        }
522
 
523
 
524
        /*
525
         * Generate a full hash of the message, then compare
526
         * the result with the given MAC which may shorter than
527
         * the full hash length.
528
         */
529
        rval = sc_generate_keyed_hash(  authtype, authtypelen,
530
                                        key, keylen,
531
                                        message, msglen,
532
                                        buf, &buf_len);
533
        QUITFUN(rval, sc_check_keyed_hash_quit);
534
 
535
        if (maclen > msglen) {
536
                QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);
537
 
538
        } else if ( memcmp(buf, MAC, maclen) != 0 ) {
539
                QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);
540
        }
541
 
542
 
543
sc_check_keyed_hash_quit:
544
        SNMP_ZERO(buf, SNMP_MAXBUF_SMALL);
545
 
546
        return rval;
547
 
548
}  /* end sc_check_keyed_hash() */
549
 
550
#else
551
_SCAPI_NOT_CONFIGURED
552
#endif  /* USE_INTERNAL_MD5 */
553
 
554
 
555
 
556
/*******************************************************************-o-******
557
 * sc_encrypt
558
 *
559
 * Parameters:
560
 *       privtype       Type of privacy cryptographic transform.
561
 *      *key            Key bits for crypting.
562
 *       keylen         Length of key (buffer) in bytes.
563
 *      *iv             IV bits for crypting.
564
 *       ivlen          Length of iv (buffer) in bytes.
565
 *      *plaintext      Plaintext to crypt.
566
 *       ptlen          Length of plaintext.
567
 *      *ciphertext     Ciphertext to crypt.
568
 *      *ctlen          Length of ciphertext.
569
 *
570
 * Returns:
571
 *      SNMPERR_SUCCESS                 Success.
572
 *      SNMPERR_SC_NOT_CONFIGURED       Encryption is not supported.
573
 *      SNMPERR_SC_GENERAL_FAILURE      Any other error
574
 *
575
 *
576
 * Encrypt plaintext into ciphertext using key and iv.
577
 *
578
 * ctlen contains actual number of crypted bytes in ciphertext upon
579
 * successful return.
580
 */
581
int
582
sc_encrypt(     oid    *privtype,       size_t privtypelen,
583
                u_char *key,            u_int  keylen,
584
                u_char *iv,             u_int  ivlen,
585
                u_char *plaintext,      u_int  ptlen,
586
                u_char *ciphertext,     size_t *ctlen)
587
#if defined(USE_OPENSSL) 
588
{
589
        int             rval    = SNMPERR_SUCCESS;
590
        u_int           transform,
591
                        properlength,
592
                        properlength_iv;
593
        u_char          pad_block[32];  /* bigger than anything I need */
594
        u_char          my_iv[32];      /* ditto */
595
        int             pad, plast, pad_size;
596
        des_key_schedule key_sch;
597
        des_cblock      key_struct;
598
 
599
        DEBUGTRACE;
600
 
601
        /*
602
         * Sanity check.
603
         */
604
#if     !defined(SCAPI_AUTHPRIV)
605
                return SNMPERR_SC_NOT_CONFIGURED;
606
#endif
607
 
608
        if ( !privtype || !key || !iv || !plaintext || !ciphertext || !ctlen
609
                || (keylen<=0) || (ivlen<=0) || (ptlen<=0) || (*ctlen<=0)
610
                || (privtypelen != USM_LENGTH_OID_TRANSFORM) )
611
        {
612
                QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
613
        }
614
        else if ( ptlen >= *ctlen) {
615
                QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
616
        }
617
 
618
 
619
#ifdef SNMP_TESTING_CODE
620
{
621
        char buf[SNMP_MAXBUF];
622
 
623
        sprint_hexstring(buf, iv, ivlen);
624
        DEBUGMSGTL(("scapi", "encrypt: IV: %s/ ", buf));
625
        sprint_hexstring(buf, key, keylen);
626
        DEBUGMSG(("scapi","%s\n", buf));
627
 
628
        sprint_hexstring(buf, plaintext, 16);
629
        DEBUGMSGTL(("scapi","encrypt: string: %s\n", buf));
630
}
631
#endif /* SNMP_TESTING_CODE */
632
 
633
 
634
        /*
635
         * Determine privacy transform.
636
         */
637
        if ( ISTRANSFORM(privtype, DESPriv) ) {
638
                properlength    = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
639
                properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
640
                pad_size = properlength;
641
        } else {
642
                QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
643
        }
644
 
645
        if ( (keylen<properlength) || (ivlen<properlength_iv) ) {
646
                QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
647
        }
648
 
649
        else if ( (keylen<properlength) || (ivlen<properlength_iv) ) {
650
                QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
651
        }
652
 
653
/* now calculate the padding needed */
654
        pad = pad_size - (ptlen % pad_size);
655
        if (ptlen + pad > *ctlen) {
656
                QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); /* not enough space */
657
        }
658
        memset(pad_block, 0, sizeof(pad_block));
659
        plast = (int) ptlen - (pad_size - pad);
660
        if (pad > 0)  /* copy data into pad block if needed */
661
                memcpy( pad_block, plaintext + plast, pad_size - pad);
662
        memset(&pad_block[pad_size-pad], pad, pad); /* filling in padblock */
663
 
664
        memset(my_iv, 0, sizeof(my_iv));
665
 
666
        if ( ISTRANSFORM(privtype, DESPriv) ) {
667
                memcpy(key_struct, key, sizeof(key_struct));
668
                (void) des_key_sched(&key_struct, key_sch);
669
 
670
                memcpy(my_iv, iv, ivlen);
671
                /* encrypt the data */
672
                des_ncbc_encrypt(plaintext, ciphertext, plast, key_sch,
673
                                 (des_cblock *) &my_iv, DES_ENCRYPT);
674
                /* then encrypt the pad block */
675
                des_ncbc_encrypt(pad_block, ciphertext+plast, pad_size,
676
                                 key_sch, (des_cblock *)&my_iv, DES_ENCRYPT);
677
                *ctlen = plast + pad_size;
678
        }
679
sc_encrypt_quit:
680
        /* clear memory just in case */
681
        memset(my_iv, 0, sizeof(my_iv));
682
        memset(pad_block, 0, sizeof(pad_block));
683
        memset(key_struct, 0, sizeof(key_struct));
684
        memset(key_sch, 0, sizeof(key_sch));
685
        return rval;
686
 
687
}  /* end sc_encrypt() */
688
 
689
#else
690
{
691
#       if USE_INTERNAL_MD5
692
        {
693
                DEBUGMSGTL(("scapi","Encrypt function not defined.\n"));
694
                return SNMPERR_SC_GENERAL_FAILURE;
695
        }
696
 
697
#       else
698
                _SCAPI_NOT_CONFIGURED
699
 
700
#       endif /* USE_INTERNAL_MD5 */
701
                        }
702
#endif                                                  /* */
703
 
704
 
705
 
706
/*******************************************************************-o-******
707
 * sc_decrypt
708
 *
709
 * Parameters:
710
 *       privtype
711
 *      *key
712
 *       keylen
713
 *      *iv
714
 *       ivlen
715
 *      *ciphertext
716
 *       ctlen
717
 *      *plaintext
718
 *      *ptlen
719
 *
720
 * Returns:
721
 *      SNMPERR_SUCCESS                 Success.
722
 *      SNMPERR_SC_NOT_CONFIGURED       Encryption is not supported.
723
 *      SNMPERR_SC_GENERAL_FAILURE      Any other error
724
 *
725
 *
726
 * Decrypt ciphertext into plaintext using key and iv.
727
 *
728
 * ptlen contains actual number of plaintext bytes in plaintext upon
729
 * successful return.
730
 */
731
int
732
sc_decrypt(     oid    *privtype,       size_t privtypelen,
733
                u_char *key,            u_int  keylen,
734
                u_char *iv,             u_int  ivlen,
735
                u_char *ciphertext,     u_int  ctlen,
736
                u_char *plaintext,      size_t *ptlen)
737
#ifdef USE_OPENSSL
738
{
739
 
740
        int rval = SNMPERR_SUCCESS;
741
        int i, j;
742
        u_char *my_iv[32];
743
        des_key_schedule key_sch;
744
        des_cblock  key_struct;
745
        u_int           properlength,
746
                        properlength_iv;
747
 
748
        DEBUGTRACE;
749
 
750
        if ( !privtype || !key || !iv || !plaintext || !ciphertext || !ptlen
751
                || (ctlen<=0) || (*ptlen<=0) || (*ptlen < ctlen)
752
                || (privtypelen != USM_LENGTH_OID_TRANSFORM) )
753
        {
754
                QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
755
        }
756
 
757
 
758
#ifdef SNMP_TESTING_CODE
759
{
760
        char buf[SNMP_MAXBUF];
761
 
762
        sprint_hexstring(buf, iv, ivlen);
763
        DEBUGMSGTL(("scapi", "decrypt: IV: %s/ ", buf));
764
        sprint_hexstring(buf, key, keylen);
765
        DEBUGMSG(("scapi","%s\n", buf));
766
}
767
#endif /* SNMP_TESTING_CODE */
768
 
769
        /*
770
         * Determine privacy transform.
771
         */
772
        if ( ISTRANSFORM(privtype, DESPriv) ) {
773
                properlength    = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
774
                properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
775
 
776
        } else {
777
                QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
778
        }
779
 
780
        if ( (keylen<properlength) || (ivlen<properlength_iv) ) {
781
                QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
782
        }
783
 
784
        memset(my_iv, 0, sizeof(my_iv));
785
        if (ISTRANSFORM(privtype, DESPriv)) {
786
                memcpy(key_struct, key, sizeof(key_struct));
787
                (void) des_key_sched(&key_struct, key_sch);
788
 
789
                memcpy(my_iv, iv, ivlen);
790
                des_cbc_encrypt(ciphertext, plaintext, ctlen, key_sch,
791
                                (des_cblock *) &my_iv, DES_DECRYPT);
792
        }
793
 
794
/* exit cond */
795
sc_decrypt_quit:
796
        memset(key_sch, 0, sizeof(key_sch));
797
        memset(key_struct, 0, sizeof(key_struct));
798
        memset(my_iv, 0, sizeof(my_iv));
799
        return rval;
800
}
801
#else   /* USE OPEN_SSL */
802
{
803
#if     !defined(SCAPI_AUTHPRIV)
804
                return SNMPERR_SC_NOT_CONFIGURED;
805
#else
806
#       if USE_INTERNAL_MD5
807
        {
808
                DEBUGMSGTL(("scapi","Decryption function not defined.\n"));
809
                return SNMPERR_SC_GENERAL_FAILURE;
810
        }
811
 
812
#       else
813
                _SCAPI_NOT_CONFIGURED
814
 
815
#       endif /* USE_INTERNAL_MD5 */
816
#endif                                                  /*  */
817
                        }
818
#endif /* USE_OPENSSL */
819
 
820
#endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.