Advertisement
Guest User

Untitled

a guest
Dec 9th, 2019
783
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.37 KB | None | 0 0
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2009 - 2014 Xilinx, Inc.  All rights reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * Use of the Software is limited solely to applications:
  16. * (a) running on a Xilinx device, or
  17. * (b) that interact with a Xilinx device through a bus or interconnect.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  22. * XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  23. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
  24. * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  25. * SOFTWARE.
  26. *
  27. * Except as contained in this notice, the name of the Xilinx shall not be used
  28. * in advertising or otherwise to promote the sale, use or other dealings in
  29. * this Software without prior written authorization from Xilinx.
  30. *
  31. ******************************************************************************/
  32.  
  33. /*
  34.  * helloworld.c: simple test application
  35.  *
  36.  * This application configures UART 16550 to baud rate 9600.
  37.  * PS7 UART (Zynq) is not initialized by this application, since
  38.  * bootrom/bsp configures it to baud rate 115200
  39.  *
  40.  * ------------------------------------------------
  41.  * | UART TYPE   BAUD RATE                        |
  42.  * ------------------------------------------------
  43.  *   uartns550   9600
  44.  *   uartlite    Configurable only in HW design
  45.  *   ps7_uart    115200 (configured by bootrom/bsp)
  46.  */
  47.  
  48. #include "platform.h"
  49. #include "xil_printf.h"
  50.  
  51. /*
  52.  *  idea.c - C source code for IDEA block cipher.
  53.  *  IDEA (International Data Encryption Algorithm), formerly known as
  54.  *  IPES (Improved Proposed Encryption Standard).
  55.  *  Algorithm developed by Xuejia Lai and James L. Massey, of ETH Zurich.
  56.  *  This implementation modified and derived from original C code
  57.  *  developed by Xuejia Lai.
  58.  *  Zero-based indexing added, names changed from IPES to IDEA.
  59.  *  CFB functions added.  Random number routines added.
  60.  *
  61.  *  Extensively optimized and restructured by Colin Plumb.
  62.  *
  63.  *  There are two adjustments that can be made to this code to
  64.  *  speed it up.  Defaults may be used for PCs.  Only the -DIDEA32
  65.  *  pays off significantly if selectively set or not set.
  66.  *  Experiment to see what works best for your machine.
  67.  *
  68.  *  Multiplication: default is inline, -DAVOID_JUMPS uses a
  69.  *      different version that does not do any conditional
  70.  *      jumps (a few percent worse on a SPARC), while
  71.  *      -DSMALL_CACHE takes it out of line to stay
  72.  *      within a small on-chip code cache.
  73.  *  Variables: normally, 16-bit variables are used, but some
  74.  *      machines (notably RISCs) do not have 16-bit registers,
  75.  *      so they do a great deal of masking.  -DIDEA32 uses "int"
  76.  *      register variables and masks explicitly only where
  77.  *      necessary.  On a SPARC, for example, this boosts
  78.  *      performace by 30%.
  79.  *
  80.  *  The IDEA(tm) block cipher is covered by patents held by ETH and a
  81.  *  Swiss company called Ascom-Tech AG.  The Swiss patent number is
  82.  *  PCT/CH91/00117, the European patent number is EP 0 482 154 B1, and
  83.  *  the U.S. patent number is US005214703.  IDEA(tm) is a trademark of
  84.  *  Ascom-Tech AG.  There is no license fee required for noncommercial
  85.  *  use.  Commercial users may obtain licensing details from Dieter
  86.  *  Profos, Ascom Tech AG, Solothurn Lab, Postfach 151, 4502 Solothurn,
  87.  *  Switzerland, Tel +41 65 242885, Fax +41 65 235761.
  88.  *
  89.  *  The IDEA block cipher uses a 64-bit block size, and a 128-bit key
  90.  *  size.  It breaks the 64-bit cipher block into four 16-bit words
  91.  *  because all of the primitive inner operations are done with 16-bit
  92.  *  arithmetic.  It likewise breaks the 128-bit cipher key into eight
  93.  *  16-bit words.
  94.  *
  95.  *  For further information on the IDEA cipher, see the book:
  96.  *    Xuejia Lai, "On the Design and Security of Block Ciphers",
  97.  *    ETH Series on Information Processing (ed. J.L. Massey) Vol 1,
  98.  *    Hartung-Gorre Verlag, Konstanz, Switzerland, 1992.  ISBN
  99.  *    3-89191-573-X.
  100.  *
  101.  *  This code runs on arrays of bytes by taking pairs in big-endian
  102.  *  order to make the 16-bit words that IDEA uses internally.  This
  103.  *  produces the same result regardless of the byte order of the
  104.  *  native CPU.
  105.  */
  106.  
  107. #include <string.h>
  108. #ifdef _MSC_VER
  109.   #include "idea.h"
  110. #else
  111.   #include "idea.h"
  112. #endif /* _MSC_VER */
  113.  
  114.  
  115. #ifdef IDEA32   /* Use >16-bit temporaries */
  116. #define low16(x) ((x) & 0xFFFF)
  117. typedef unsigned int uint16;    /* at LEAST 16 bits, maybe more */
  118. #else
  119. #define low16(x) (x)    /* this is only ever applied to uint16's */
  120. typedef word16 uint16;
  121. #endif
  122.  
  123. #ifdef _GNUC_
  124. /* __const__ simply means there are no side effects for this function,
  125.  * which is useful info for the gcc optimizer
  126.  */
  127. #define CONST __const__
  128. #else
  129. #define CONST
  130. #endif
  131.  
  132. /*
  133.  *  Multiplication, modulo (2**16)+1
  134.  * Note that this code is structured on the assumption that
  135.  * untaken branches are cheaper than taken branches, and the
  136.  * compiler doesn't schedule branches.
  137.  */
  138. #ifdef SMALL_CACHE
  139. CONST static uint16
  140. mul(register uint16 a, register uint16 b)
  141. {
  142.     register word32 p;
  143.  
  144.     p = (word32)a * b;
  145.     if (p) {
  146.         b = low16(p);
  147.         a = p>>16;
  148.         return (b - a) + (b < a);
  149.     } else if (a) {
  150.         return 1-b;
  151.     } else {
  152.         return 1-a;
  153.     }
  154. } /* mul */
  155. #endif /* SMALL_CACHE */
  156.  
  157. /*
  158.  * Compute the multiplicative inverse of x, modulo 65537, using Euclid's
  159.  * algorithm. It is unrolled twice to avoid swapping the registers each
  160.  * iteration, and some subtracts of t have been changed to adds.
  161.  */
  162. CONST static uint16
  163. mulInv(uint16 x)
  164. {
  165.     uint16 t0, t1;
  166.     uint16 q, y;
  167.  
  168.     if (x <= 1)
  169.         return x;   /* 0 and 1 are self-inverse */
  170.     t1 = 0x10001L / x;  /* Since x >= 2, this fits into 16 bits */
  171.     y = 0x10001L % x;
  172.     if (y == 1)
  173.         return low16(1-t1);
  174.     t0 = 1;
  175.     do {
  176.         q = x / y;
  177.         x = x % y;
  178.         t0 += q * t1;
  179.         if (x == 1)
  180.             return t0;
  181.         q = y / x;
  182.         y = y % x;
  183.         t1 += q * t0;
  184.     } while (y != 1);
  185.     return low16(1-t1);
  186. } /* mukInv */
  187.  
  188. /*
  189.  * Expand a 128-bit user key to a working encryption key EK
  190.  */
  191. void
  192. ideaExpandKey(byte const *userkey, word16 *EK)
  193. {
  194.     int i,j;
  195.  
  196.     for (j=0; j<8; j++) {
  197.         EK[j] = (userkey[0]<<8) + userkey[1];
  198.         userkey += 2;
  199.     }
  200.     for (i=0; j < IDEAKEYLEN; j++) {
  201.         i++;
  202.         EK[i+7] = (EK[i & 7] << 9) | (EK[i+1 & 7] >> 7);
  203.         EK += i & 8;
  204.         i &= 7;
  205.     }
  206. } /* ideaExpandKey */
  207.  
  208. /*
  209.  * Compute IDEA decryption key DK from an expanded IDEA encryption key EK
  210.  * Note that the input and output may be the same.  Thus, the key is
  211.  * inverted into an internal buffer, and then copied to the output.
  212.  */
  213. void
  214. ideaInvertKey(word16 const *EK, word16 DK[IDEAKEYLEN])
  215. {
  216.     int i;
  217.     uint16 t1, t2, t3;
  218.     word16 temp[IDEAKEYLEN];
  219.     word16 *p = temp + IDEAKEYLEN;
  220.  
  221.     t1 = mulInv(*EK++);
  222.     t2 = -*EK++;
  223.     t3 = -*EK++;
  224.     *--p = mulInv(*EK++);
  225.     *--p = t3;
  226.     *--p = t2;
  227.     *--p = t1;
  228.  
  229.     for (i = 0; i < IDEAROUNDS-1; i++) {
  230.         t1 = *EK++;
  231.         *--p = *EK++;
  232.         *--p = t1;
  233.  
  234.         t1 = mulInv(*EK++);
  235.         t2 = -*EK++;
  236.         t3 = -*EK++;
  237.         *--p = mulInv(*EK++);
  238.         *--p = t2;
  239.         *--p = t3;
  240.         *--p = t1;
  241.     }
  242.     t1 = *EK++;
  243.     *--p = *EK++;
  244.     *--p = t1;
  245.  
  246.     t1 = mulInv(*EK++);
  247.     t2 = -*EK++;
  248.     t3 = -*EK++;
  249.     *--p = mulInv(*EK++);
  250.     *--p = t3;
  251.     *--p = t2;
  252.     *--p = t1;
  253. /* Copy and destroy temp copy */
  254.     memcpy(DK, temp, sizeof(temp));
  255.     burn(temp);
  256. } /* ideaInvertKey */
  257.  
  258. /*
  259.  * MUL(x,y) computes x = x*y, modulo 0x10001.  Requires two temps,
  260.  * t16 and t32.  x is modified, and must me a side-effect-free lvalue.
  261.  * y may be anything, but unlike x, must be strictly 16 bits even if
  262.  * low16() is #defined.
  263.  * All of these are equivalent - see which is faster on your machine
  264.  */
  265. #ifdef SMALL_CACHE
  266. #define MUL(x,y) (x = mul(low16(x),y))
  267. #else /* !SMALL_CACHE */
  268. #ifdef AVOID_JUMPS
  269. #define MUL(x,y) (x = low16(x-1), t16 = low16((y)-1), \
  270.         t32 = (word32)x*t16 + x + t16 + 1, x = low16(t32), \
  271.         t16 = t32>>16, x = (x-t16) + (x<t16) )
  272. #else /* !AVOID_JUMPS (default) */
  273. #define MUL(x,y) \
  274.     ((t16 = (y)) ? \
  275.         (x=low16(x)) ? \
  276.             t32 = (word32)x*t16, \
  277.             x = low16(t32), \
  278.             t16 = t32>>16, \
  279.             x = (x-t16)+(x<t16) \
  280.         : \
  281.             (x = 1-t16) \
  282.     : \
  283.         (x = 1-x))
  284. #endif
  285. #endif
  286.  
  287. /*  IDEA encryption/decryption algorithm */
  288. /* Note that in and out can be the same buffer */
  289. void
  290. ideaCipher(byte const (inbuf[8]), byte (outbuf[8]), word16 const *key)
  291. {
  292.     register uint16 x1, x2, x3, x4, s2, s3;
  293.     word16 *in, *out;
  294. #ifndef SMALL_CACHE
  295.     register uint16 t16;    /* Temporaries needed by MUL macro */
  296.     register word32 t32;
  297. #endif
  298.     int r = IDEAROUNDS;
  299.  
  300.     in = (word16 *)inbuf;
  301.     x1 = *in++;  x2 = *in++;
  302.     x3 = *in++;  x4 = *in;
  303. #ifndef HIGHFIRST
  304.     x1 = (x1>>8) | (x1<<8);
  305.     x2 = (x2>>8) | (x2<<8);
  306.     x3 = (x3>>8) | (x3<<8);
  307.     x4 = (x4>>8) | (x4<<8);
  308. #endif
  309.     do {
  310.         MUL(x1,*key++);
  311.         x2 += *key++;
  312.         x3 += *key++;
  313.         MUL(x4, *key++);
  314.  
  315.         s3 = x3;
  316.         x3 ^= x1;
  317.         MUL(x3, *key++);
  318.         s2 = x2;
  319.         x2 ^= x4;
  320.         x2 += x3;
  321.         MUL(x2, *key++);
  322.         x3 += x2;
  323.  
  324.         x1 ^= x2;  x4 ^= x3;
  325.  
  326.         x2 ^= s3;  x3 ^= s2;
  327.     } while (--r);
  328.     MUL(x1, *key++);
  329.     x3 += *key++;
  330.     x2 += *key++;
  331.     MUL(x4, *key);
  332.  
  333.     out = (word16 *)outbuf;
  334. #ifdef HIGHFIRST
  335.     *out++ = x1;
  336.     *out++ = x3;
  337.     *out++ = x2;
  338.     *out = x4;
  339. #else /* !HIGHFIRST */
  340.     x1 = low16(x1);
  341.     x2 = low16(x2);
  342.     x3 = low16(x3);
  343.     x4 = low16(x4);
  344.     *out++ = (x1>>8) | (x1<<8);
  345.     *out++ = (x3>>8) | (x3<<8);
  346.     *out++ = (x2>>8) | (x2<<8);
  347.     *out   = (x4>>8) | (x4<<8);
  348. #endif
  349. } /* ideaCipher */
  350.  
  351. /*-------------------------------------------------------------*/
  352. #define TEST
  353. #ifdef TEST
  354.  
  355. #include <stdio.h>
  356. //#include <time.h>
  357. /*
  358.  * This is the number of Kbytes of test data to encrypt.
  359.  * It defaults to 1 MByte.
  360.  */
  361. #ifndef BLOCKS
  362. #ifndef KBYTES
  363. #define KBYTES 1024
  364. #endif
  365. #define BLOCKS (64*KBYTES)
  366. #endif
  367.  
  368. int
  369. main(void)
  370. {   /* Test driver for IDEA cipher */
  371.     int i, j, k;
  372.     byte userkey[16] = { 0x00, 0x64, 0x00, 0xC8, 0x01, 0x2C, 0x01, 0x90,
  373.             0x01, 0xF4, 0x02, 0x58, 0x02, 0xBC, 0x03, 0x20 };
  374.     word16 EK[IDEAKEYLEN], DK[IDEAKEYLEN];
  375.     byte pt[8] = { 0x05, 0x32, 0x0A, 0x64, 0x14, 0xC8, 0x19, 0xFA };
  376.     byte ct[8] = { 0x65, 0xBE, 0x87, 0xE7, 0xA2, 0x53, 0x8A, 0xED };
  377.     byte ZZ[8];
  378.     clock_t start, end;
  379.     long l;
  380.  
  381.     init_platform();
  382.  
  383.  
  384.     /* Compute encryption subkeys from user key... */
  385.     ideaExpandKey(userkey, EK);
  386. //  xil_printf("\nEncryption key subblocks: ");
  387. //  for (j=0; j<IDEAROUNDS+1; j++) {
  388. //      xil_printf("\nround %d:   ", j+1);
  389. //      if (j < IDEAROUNDS)
  390. //          for(i=0; i<6; i++)
  391. //              xil_printf(" %6u", EK[j*6+i]);
  392. //      else
  393. //          for(i=0; i<4; i++)
  394. //              xil_printf(" %6u", EK[j*6+i]);
  395. //  }
  396.  
  397.     /* Compute decryption subkeys from encryption subkeys... */
  398.     ideaInvertKey(EK, DK);
  399. //  xil_printf("\nDecryption key subblocks: ");
  400. //  for (j=0; j<IDEAROUNDS+1; j++) {
  401. //      xil_printf("\nround %d:   ", j+1);
  402. //      if (j < IDEAROUNDS)
  403. //          for(i=0; i<6; i++)
  404. //              xil_printf(" %6u", DK[j*6+i]);
  405. //      else
  406. //          for(i=0; i<4; i++)
  407. //              xil_printf(" %6u", DK[j*6+i]);
  408. //  }
  409.  
  410.  
  411.     xil_printf("\n Encrypting %d bytes", 8);
  412. //  fflush(stdout);
  413.     memcpy(ct, pt, 8);
  414.     ideaCipher(ct, ct, EK);
  415.     memcpy(ZZ, ct, 8);
  416.     ideaCipher(ZZ, ZZ, DK);
  417.  
  418.     xil_printf("\noriginal 0x%02x  0x%02x  0x%02x  0x%02x  0x%02x  0x%02x  0x%02x 0x%02x\n",
  419.       pt[0], pt[1],  pt[2], pt[3], pt[4], pt[5],  pt[6], pt[7]);
  420.     xil_printf("\nencrypted 0x%02x  0x%02x  0x%02x  0x%02x  0x%02x  0x%02x  0x%02x 0x%02x\n",
  421.       ct[0], ct[1],  ct[2], ct[3], ct[4], ct[5],  ct[6], ct[7]);
  422.     xil_printf("\ndecrypted 0x%02x  0x%02x  0x%02x  0x%02x  0x%02x  0x%02x  0x%02x 0x%02x\n",
  423.       ZZ[0], ZZ[1],  ZZ[2], ZZ[3], ZZ[4], ZZ[5],  ZZ[6], ZZ[7]);
  424.  
  425.     /* Now decrypted ZZ should be same as original pt */
  426.     for (k=0; k<8; k++)
  427.         if (pt[k] != ZZ[k]) {
  428.             xil_printf("\n\07Error!  Noninvertable encryption.\n");
  429.             exit(-1);   /* error exit */
  430.         }
  431.     xil_printf("\nNormal exit.\n");
  432.     cleanup_platform();
  433.     return 0;   /* normal exit */
  434. } /* main */
  435.  
  436. #endif /* TEST */
  437.  
  438. /* end of idea.c */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement