idea.cpp
上传用户:ets1996
上传日期:2014-09-30
资源大小:353k
文件大小:7k
源码类别:

SNMP编程

开发平台:

Visual C++

  1. /*_############################################################################
  2.   _## 
  3.   _##  idea.cpp  
  4.   _##
  5.   _##  SNMP++v3.2.22
  6.   _##  -----------------------------------------------
  7.   _##  Copyright (c) 2001-2007 Jochen Katz, Frank Fock
  8.   _##
  9.   _##  This software is based on SNMP++2.6 from Hewlett Packard:
  10.   _##  
  11.   _##    Copyright (c) 1996
  12.   _##    Hewlett-Packard Company
  13.   _##  
  14.   _##  ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  15.   _##  Permission to use, copy, modify, distribute and/or sell this software 
  16.   _##  and/or its documentation is hereby granted without fee. User agrees 
  17.   _##  to display the above copyright notice and this license notice in all 
  18.   _##  copies of the software and any documentation of the software. User 
  19.   _##  agrees to assume all liability for the use of the software; 
  20.   _##  Hewlett-Packard and Jochen Katz make no representations about the 
  21.   _##  suitability of this software for any purpose. It is provided 
  22.   _##  "AS-IS" without warranty of any kind, either express or implied. User 
  23.   _##  hereby grants a royalty-free license to any and all derivatives based
  24.   _##  upon this software code base. 
  25.   _##  
  26.   _##  Stuttgart, Germany, Wed May  2 23:22:30 CEST 2007 
  27.   _##  
  28.   _##########################################################################*/
  29. char idea_cpp_version[]="#(@) SNMP++ $Id: idea.cpp 42 2004-03-03 23:11:21Z katz $";
  30. /*
  31. idea.c
  32. Author: Tatu Ylonen <ylo@cs.hut.fi>
  33. Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  34.                    All rights reserved
  35. Created: Sun Jun 25 02:59:39 1995 ylo
  36. This code is based on Xuejia Lai: On the Design and Security of Block
  37. Ciphers, ETH Series in Information Processing, vol. 1, Hartung-Gorre
  38. Verlag, Konstanz, Switzerland, 1992.  Another source was Bruce
  39. Schneier: Applied Cryptography, John Wiley & Sons, 1994.
  40. The IDEA mathematical formula may be covered by one or more of the
  41. following patents: PCT/CH91/00117, EP 0 482 154 B1, US Pat. 5,214,703.
  42. */
  43. //#include "snmp_pp/includes.h"
  44. //#include "snmp_pp/getput.h"
  45. #include "snmp_pp/idea.h"
  46. #include <string.h>
  47. #ifdef SNMP_PP_NAMESPACE
  48. namespace Snmp_pp {
  49. #endif
  50. #ifdef _USE_IDEA
  51. /* Sets idea key for encryption. */
  52. void idea_set_key(IDEAContext *c, const unsigned char key[16])
  53. {
  54.   int i;
  55.   word16 *keys;
  56.   /* Get pointer to the keys. */
  57.   keys = c->key_schedule;
  58.   /* Keys for the first round are directly taken from the user-supplied key. */
  59.   for (i = 0; i < 8; i++)
  60.     keys[i] = (word16)GET_16BIT(key + 2 * i);
  61.   /* Each round uses the key of the previous key, rotated to the left by 25
  62.      bits.  The last four keys (output transform) are the first four keys
  63.      from what would be the ninth round. */
  64.   for (i = 8; i < 52; i++)
  65.     {
  66.       if ((i & 7) == 0)
  67. keys += 8;
  68.       keys[i & 7] = ((keys[((i + 1) & 7) - 8] << 9) |
  69.      (keys[((i + 2) & 7) - 8] >> 7)) & 0xffff;
  70.     }
  71. }
  72. /* Destroys any sensitive data in the context. */
  73. void idea_destroy_context(IDEAContext *c)
  74. {
  75.   memset(&c, 0, sizeof(c));
  76. }
  77. /* Performs the "multiplication" operation of IDEA: returns a*b mod 65537,
  78.    where a and b are first converted to 65536 if they are zero, and result
  79.    65536 is converted to zero.  Both inputs should be less than 65536.
  80.    Only the lower 16 bits of result are significant; other bits are garbage.
  81.    */
  82. static inline word32 mulop(word32 a, word32 b)
  83. {
  84.   word32 ab = a * b;
  85.   if (ab != 0)
  86.     {
  87.       word32 lo = ab & 0xffff;
  88.       word32 hi = (ab >> 16) & 0xffff;
  89.       return (lo - hi) + (lo < hi);
  90.     }
  91.   if (a == 0)
  92.     return 1 - b;
  93.   return  1 - a;
  94. }
  95. /* Performs the IDEA cipher transform on a block of data. */
  96. void idea_transform(IDEAContext *c, word32 l, word32 r, word32 *output)
  97. {
  98.   unsigned int round;
  99.   word16 *keys;
  100.   word32 t1, t2, x1, x2, x3, x4;
  101.   keys = c->key_schedule;
  102.   x1 = l >> 16;
  103.   x2 = l;
  104.   x3 = r >> 16;
  105.   x4 = r;
  106.   for (round = 0; round < 8; round++)
  107.     {
  108.       x1 = mulop(x1 & 0xffff, keys[0]);
  109.       x3 = x3 + keys[2];
  110.       x4 = mulop(x4 & 0xffff, keys[3]);
  111.       x2 = x2 + keys[1];
  112.       t1 = x1 ^ x3;
  113.       t2 = x2 ^ x4;
  114.       t1 = mulop(t1 & 0xffff, keys[4]);
  115.       t2 = t1 + t2;
  116.       t2 = mulop(t2 & 0xffff, keys[5]);
  117.       t1 = t1 + t2;
  118.       x1 = x1 ^ t2;
  119.       x4 = x4 ^ t1;
  120.       t1 = t1 ^ x2;
  121.       x2 = t2 ^ x3;
  122.       x3 = t1;
  123.       keys += 6;
  124.     }
  125.   x1 = mulop(x1 & 0xffff, keys[0]);
  126.   x3 = (x2 + keys[2]) & 0xffff;
  127.   x2 = t1 + keys[1]; /* t1 == old x3 */
  128.   x4 = mulop(x4 & 0xffff, keys[3]);
  129.   output[0] = (x1 << 16) | (x2 & 0xffff);
  130.   output[1] = (x3 << 16) | (x4 & 0xffff);
  131. }
  132. /* Encrypts len bytes from src to dest in CFB mode.  Len need not be a multiple
  133.    of 8; if it is not, iv at return will contain garbage.
  134.    Otherwise, iv will be modified at end to a value suitable for continuing
  135.    encryption. */
  136. void idea_cfb_encrypt(IDEAContext *c, unsigned char *iv, unsigned char *dest,
  137.       const unsigned char *src, unsigned int len)
  138. {
  139.   word32 iv0, iv1, out[2];
  140.   unsigned int i;
  141.   iv0 = GET_32BIT(iv);
  142.   iv1 = GET_32BIT(iv + 4);
  143.   for (i = 0; i < len; i += 8)
  144.     {
  145.       idea_transform(c, iv0, iv1, out);
  146.       iv0 = out[0] ^ GET_32BIT(src + i);
  147.       iv1 = out[1] ^ GET_32BIT(src + i + 4);
  148.       if (i + 8 <= len)
  149. {
  150.   PUT_32BIT(dest + i, iv0);
  151.   PUT_32BIT(dest + i + 4, iv1);
  152. }
  153.       else
  154. {
  155.   switch (len - i)
  156.     {
  157.     case 7:
  158.       dest[i + 6] = iv1 >> 8;
  159.       /*FALLTHROUGH*/
  160.     case 6:
  161.       dest[i + 5] = iv1 >> 16;
  162.       /*FALLTHROUGH*/
  163.     case 5:
  164.       dest[i + 4] = iv1 >> 24;
  165.       /*FALLTHROUGH*/
  166.     case 4:
  167.       dest[i + 3] = iv0;
  168.       /*FALLTHROUGH*/
  169.     case 3:
  170.       dest[i + 2] = iv0 >> 8;
  171.       /*FALLTHROUGH*/
  172.     case 2:
  173.       dest[i + 1] = iv0 >> 16;
  174.       /*FALLTHROUGH*/
  175.     case 1:
  176.       dest[i] = iv0 >> 24;
  177.       /*FALLTHROUGH*/
  178.     }
  179. }
  180.     }
  181.   PUT_32BIT(iv, iv0);
  182.   PUT_32BIT(iv + 4, iv1);
  183. }
  184. /* Decrypts len bytes from src to dest in CFB mode.  Len need not be a multiple
  185.    of 8; if it is not, iv at return will contain garbage.
  186.    Otherwise, iv will be modified at end to a value suitable for continuing
  187.    decryption. */
  188. void idea_cfb_decrypt(IDEAContext *c, unsigned char *iv, unsigned char *dest,
  189.       const unsigned char *src, unsigned int len)
  190. {
  191.   word32 iv0, iv1, out[2], plain0, plain1;
  192.   unsigned int i;
  193.   iv0 = GET_32BIT(iv);
  194.   iv1 = GET_32BIT(iv + 4);
  195.   for (i = 0; i < len; i += 8)
  196.     {
  197.       idea_transform(c, iv0, iv1, out);
  198.       iv0 = GET_32BIT(src + i);
  199.       iv1 = GET_32BIT(src + i + 4);
  200.       plain0 = out[0] ^ iv0;
  201.       plain1 = out[1] ^ iv1;
  202.       if (i + 8 <= len)
  203. {
  204.   PUT_32BIT(dest + i, plain0);
  205.   PUT_32BIT(dest + i + 4, plain1);
  206. }
  207.       else
  208. {
  209.   switch (len - i)
  210.     {
  211.     case 7:
  212.       dest[i + 6] = plain1 >> 8;
  213.       /*FALLTHROUGH*/
  214.     case 6:
  215.       dest[i + 5] = plain1 >> 16;
  216.       /*FALLTHROUGH*/
  217.     case 5:
  218.       dest[i + 4] = plain1 >> 24;
  219.       /*FALLTHROUGH*/
  220.     case 4:
  221.       dest[i + 3] = plain0;
  222.       /*FALLTHROUGH*/
  223.     case 3:
  224.       dest[i + 2] = plain0 >> 8;
  225.       /*FALLTHROUGH*/
  226.     case 2:
  227.       dest[i + 1] = plain0 >> 16;
  228.       /*FALLTHROUGH*/
  229.     case 1:
  230.       dest[i] = plain0 >> 24;
  231.       /*FALLTHROUGH*/
  232.     }
  233. }
  234.     }
  235.   PUT_32BIT(iv, iv0);
  236.   PUT_32BIT(iv + 4, iv1);
  237. }
  238. #endif
  239. #ifdef SNMP_PP_NAMESPACE
  240. }; // end of namespace Snmp_pp
  241. #endif