mirror of the now-defunct rocklinux.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6490 lines
205 KiB

  1. # --- ROCK-COPYRIGHT-NOTE-BEGIN ---
  2. #
  3. # This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  4. # Please add additional copyright information _after_ the line containing
  5. # the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
  6. # the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
  7. #
  8. # ROCK Linux: rock-src/package/blindcoder/loop-aes/linux24_cryptoloop.diff
  9. # ROCK Linux is Copyright (C) 1998 - 2004 Clifford Wolf
  10. #
  11. # This patch file is dual-licensed. It is available under the license the
  12. # patched project is licensed under, as long as it is an OpenSource license
  13. # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
  14. # of the GNU General Public License as published by the Free Software
  15. # Foundation; either version 2 of the License, or (at your option) any later
  16. # version.
  17. #
  18. # --- ROCK-COPYRIGHT-NOTE-END ---
  19. diff -pruN linux-2.4.27_orig/Documentation/Configure.help linux-2.4.27/Documentation/Configure.help
  20. --- linux-2.4.27_orig/Documentation/Configure.help 2004-08-08 01:26:04.000000000 +0200
  21. +++ linux-2.4.27/Documentation/Configure.help 2004-10-25 14:20:44.709005688 +0200
  22. @@ -620,6 +620,21 @@ CONFIG_BLK_STATS
  23. If unsure, say N.
  24. +AES encrypted loop device support
  25. +CONFIG_BLK_DEV_LOOP_AES
  26. + If you want to use AES encryption algorithm to encrypt loop devices,
  27. + say Y here. If you don't know what to do here, say N.
  28. +
  29. +loop encryption key scrubbing support
  30. +CONFIG_BLK_DEV_LOOP_KEYSCRUB
  31. + Loop encryption key scrubbing moves and inverts key bits in
  32. + kernel RAM so that the thin oxide which forms the storage
  33. + capacitor dielectric of DRAM cells is not permitted to develop
  34. + detectable property. For more info, see Peter Gutmann's paper:
  35. + http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html
  36. +
  37. + Paranoid tinfoil hat crowd say Y here, everyone else say N.
  38. +
  39. ATA/IDE/MFM/RLL support
  40. CONFIG_IDE
  41. If you say Y here, your kernel will be able to manage low cost mass
  42. diff -pruN linux-2.4.27_orig/drivers/block/Config.in linux-2.4.27/drivers/block/Config.in
  43. --- linux-2.4.27_orig/drivers/block/Config.in 2004-08-08 01:26:04.000000000 +0200
  44. +++ linux-2.4.27/drivers/block/Config.in 2004-10-25 14:20:44.711005384 +0200
  45. @@ -42,6 +42,10 @@ dep_tristate 'Micro Memory MM5415 Batter
  46. dep_tristate 'Promise SATA SX8 support' CONFIG_BLK_DEV_SX8 $CONFIG_PCI
  47. tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
  48. +if [ "$CONFIG_BLK_DEV_LOOP" != "n" ]; then
  49. + bool ' AES encrypted loop device support' CONFIG_BLK_DEV_LOOP_AES
  50. + bool ' loop encryption key scrubbing support' CONFIG_BLK_DEV_LOOP_KEYSCRUB
  51. +fi
  52. dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
  53. tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
  54. diff -pruN linux-2.4.27_orig/drivers/block/loop.c linux-2.4.27/drivers/block/loop.c
  55. --- linux-2.4.27_orig/drivers/block/loop.c 2003-08-25 13:44:41.000000000 +0200
  56. +++ linux-2.4.27/drivers/block/loop.c 2004-10-25 14:20:44.715004776 +0200
  57. @@ -2,7 +2,7 @@
  58. * linux/drivers/block/loop.c
  59. *
  60. * Written by Theodore Ts'o, 3/29/93
  61. - *
  62. + *
  63. * Copyright 1993 by Theodore Ts'o. Redistribution of this file is
  64. * permitted under the GNU General Public License.
  65. *
  66. @@ -21,12 +21,12 @@
  67. * Loadable modules and other fixes by AK, 1998
  68. *
  69. * Make real block number available to downstream transfer functions, enables
  70. - * CBC (and relatives) mode encryption requiring unique IVs per data block.
  71. + * CBC (and relatives) mode encryption requiring unique IVs per data block.
  72. * Reed H. Petty, rhp@draper.net
  73. *
  74. * Maximum number of loop devices now dynamic via max_loop module parameter.
  75. * Russell Kroll <rkroll@exploits.org> 19990701
  76. - *
  77. + *
  78. * Maximum number of loop devices when compiled-in now selectable by passing
  79. * max_loop=<1-255> to the kernel on boot.
  80. * Erik I. Bols�, <eriki@himolde.no>, Oct 31, 1999
  81. @@ -39,20 +39,30 @@
  82. * Support up to 256 loop devices
  83. * Heinz Mauelshagen <mge@sistina.com>, Feb 2002
  84. *
  85. - * Still To Fix:
  86. - * - Advisory locking is ignored here.
  87. - * - Should use an own CAP_* category instead of CAP_SYS_ADMIN
  88. + * AES transfer added. IV is now passed as (512 byte) sector number.
  89. + * Jari Ruusu, May 18 2001
  90. + *
  91. + * External encryption module locking bug fixed.
  92. + * Ingo Rohloff <rohloff@in.tum.de>, June 21 2001
  93. + *
  94. + * Make device backed loop work with swap (pre-allocated buffers + queue rewrite).
  95. + * Jari Ruusu, September 2 2001
  96. + *
  97. + * File backed code now uses file->f_op->read/write. Based on Andrew Morton's idea.
  98. + * Jari Ruusu, May 23 2002
  99. *
  100. - * WARNING/FIXME:
  101. - * - The block number as IV passing to low level transfer functions is broken:
  102. - * it passes the underlying device's block number instead of the
  103. - * offset. This makes it change for a given block when the file is
  104. - * moved/restored/copied and also doesn't work over NFS.
  105. - * AV, Feb 12, 2000: we pass the logical block number now. It fixes the
  106. - * problem above. Encryption modules that used to rely on the old scheme
  107. - * should just call ->i_mapping->bmap() to calculate the physical block
  108. - * number.
  109. - */
  110. + * Backported struct loop_info64 ioctls from 2.6 kernels (64 bit offsets and
  111. + * 64 bit sizelimits). Added support for removing offset from IV computations.
  112. + * Jari Ruusu, September 21 2003
  113. + *
  114. + * Added support for MD5 IV computation and multi-key operation.
  115. + * Jari Ruusu, October 8 2003
  116. + *
  117. + *
  118. + * Still To Fix:
  119. + * - Advisory locking is ignored here.
  120. + * - Should use an own CAP_* category instead of CAP_SYS_ADMIN
  121. + */
  122. #include <linux/config.h>
  123. #include <linux/module.h>
  124. @@ -71,10 +81,14 @@
  125. #include <linux/smp_lock.h>
  126. #include <linux/swap.h>
  127. #include <linux/slab.h>
  128. +#include <linux/spinlock.h>
  129. #include <asm/uaccess.h>
  130. +#include <asm/byteorder.h>
  131. #include <linux/loop.h>
  132. +#include "../misc/aes.h"
  133. +#include "../misc/md5.h"
  134. #define MAJOR_NR LOOP_MAJOR
  135. @@ -82,21 +96,31 @@ static int max_loop = 8;
  136. static struct loop_device *loop_dev;
  137. static int *loop_sizes;
  138. static int *loop_blksizes;
  139. +static int *loop_hardsizes;
  140. static devfs_handle_t devfs_handle; /* For the directory */
  141. +#if defined(__x86_64__) && defined(CONFIG_IA32_EMULATION)
  142. +# include <asm/ioctl32.h>
  143. +# define IOCTL32_COMPATIBLE_PTR ((void*)sys_ioctl)
  144. +#endif
  145. +#if (defined(__sparc__) || defined(__sparc64__)) && defined(CONFIG_SPARC32_COMPAT)
  146. + extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
  147. + extern int unregister_ioctl32_conversion(unsigned int cmd);
  148. + extern int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
  149. +# define IOCTL32_COMPATIBLE_PTR ((void*)sys_ioctl)
  150. +#endif
  151. +
  152. /*
  153. * Transfer functions
  154. */
  155. static int transfer_none(struct loop_device *lo, int cmd, char *raw_buf,
  156. char *loop_buf, int size, int real_block)
  157. {
  158. - if (raw_buf != loop_buf) {
  159. - if (cmd == READ)
  160. - memcpy(loop_buf, raw_buf, size);
  161. - else
  162. - memcpy(raw_buf, loop_buf, size);
  163. - }
  164. + /* this code is only called from file backed loop */
  165. + /* and that code expects this function to be no-op */
  166. + if (current->need_resched)
  167. + {set_current_state(TASK_RUNNING);schedule();}
  168. return 0;
  169. }
  170. @@ -118,12 +142,13 @@ static int transfer_xor(struct loop_devi
  171. keysize = lo->lo_encrypt_key_size;
  172. for (i = 0; i < size; i++)
  173. *out++ = *in++ ^ key[(i & 511) % keysize];
  174. + if (current->need_resched)
  175. + {set_current_state(TASK_RUNNING);schedule();}
  176. return 0;
  177. }
  178. static int none_status(struct loop_device *lo, struct loop_info *info)
  179. {
  180. - lo->lo_flags |= LO_FLAGS_BH_REMAP;
  181. return 0;
  182. }
  183. @@ -134,336 +159,892 @@ static int xor_status(struct loop_device
  184. return 0;
  185. }
  186. -struct loop_func_table none_funcs = {
  187. +struct loop_func_table none_funcs = {
  188. number: LO_CRYPT_NONE,
  189. transfer: transfer_none,
  190. init: none_status,
  191. };
  192. -struct loop_func_table xor_funcs = {
  193. +struct loop_func_table xor_funcs = {
  194. number: LO_CRYPT_XOR,
  195. transfer: transfer_xor,
  196. - init: xor_status
  197. + init: xor_status,
  198. };
  199. -/* xfer_funcs[0] is special - its release function is never called */
  200. -struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {
  201. - &none_funcs,
  202. - &xor_funcs
  203. -};
  204. +#if CONFIG_BLK_DEV_LOOP_AES
  205. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  206. +# define KEY_ALLOC_COUNT 128
  207. +#else
  208. +# define KEY_ALLOC_COUNT 64
  209. +#endif
  210. -#define MAX_DISK_SIZE 1024*1024*1024
  211. +typedef struct {
  212. + aes_context *keyPtr[KEY_ALLOC_COUNT];
  213. + unsigned keyMask;
  214. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  215. + rwlock_t rwlock;
  216. + unsigned reversed;
  217. + unsigned blocked;
  218. + struct timer_list timer;
  219. +#endif
  220. +} AESmultiKey;
  221. -static int compute_loop_size(struct loop_device *lo, struct dentry * lo_dentry, kdev_t lodev)
  222. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  223. +static void keyScrubWork(AESmultiKey *m)
  224. {
  225. - if (S_ISREG(lo_dentry->d_inode->i_mode))
  226. - return (lo_dentry->d_inode->i_size - lo->lo_offset) >> BLOCK_SIZE_BITS;
  227. - if (blk_size[MAJOR(lodev)])
  228. - return blk_size[MAJOR(lodev)][MINOR(lodev)] -
  229. - (lo->lo_offset >> BLOCK_SIZE_BITS);
  230. - return MAX_DISK_SIZE;
  231. + aes_context *a0, *a1;
  232. + u_int32_t *p;
  233. + int x, y, z;
  234. +
  235. + z = m->keyMask + 1;
  236. + for(x = 0; x < z; x++) {
  237. + a0 = m->keyPtr[x];
  238. + a1 = m->keyPtr[x + z];
  239. + memcpy(a1, a0, sizeof(aes_context));
  240. + m->keyPtr[x] = a1;
  241. + m->keyPtr[x + z] = a0;
  242. + p = (u_int32_t *) a0;
  243. + y = sizeof(aes_context) / sizeof(u_int32_t);
  244. + while(y > 0) {
  245. + *p ^= 0xFFFFFFFF;
  246. + p++;
  247. + y--;
  248. + }
  249. + }
  250. + m->reversed ^= 1;
  251. +
  252. + /* try to flush dirty cache data to RAM */
  253. +#if defined(CONFIG_X86_64) || (defined(CONFIG_X86) && !defined(CONFIG_M386) && !defined(CONFIG_CPU_386))
  254. + __asm__ __volatile__ ("wbinvd": : :"memory");
  255. +#else
  256. + mb();
  257. +#endif
  258. }
  259. -static void figure_loop_size(struct loop_device *lo)
  260. +/* called only from loop thread process context */
  261. +static void keyScrubThreadFn(AESmultiKey *m)
  262. {
  263. - loop_sizes[lo->lo_number] = compute_loop_size(lo,
  264. - lo->lo_backing_file->f_dentry,
  265. - lo->lo_device);
  266. + write_lock(&m->rwlock);
  267. + if(!m->blocked) keyScrubWork(m);
  268. + write_unlock(&m->rwlock);
  269. }
  270. -static int lo_send(struct loop_device *lo, struct buffer_head *bh, int bsize,
  271. - loff_t pos)
  272. +static void keyScrubTimerInit(struct loop_device *lo)
  273. {
  274. - struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */
  275. - struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
  276. - struct address_space_operations *aops = mapping->a_ops;
  277. - struct page *page;
  278. - char *kaddr, *data;
  279. - unsigned long index;
  280. - unsigned size, offset;
  281. - int len;
  282. + AESmultiKey *m;
  283. + unsigned long expire;
  284. + static void keyScrubTimerFn(unsigned long);
  285. - down(&mapping->host->i_sem);
  286. - index = pos >> PAGE_CACHE_SHIFT;
  287. - offset = pos & (PAGE_CACHE_SIZE - 1);
  288. - len = bh->b_size;
  289. - data = bh->b_data;
  290. - while (len > 0) {
  291. - int IV = index * (PAGE_CACHE_SIZE/bsize) + offset/bsize;
  292. - int transfer_result;
  293. -
  294. - size = PAGE_CACHE_SIZE - offset;
  295. - if (size > len)
  296. - size = len;
  297. + m = (AESmultiKey *)lo->key_data;
  298. + expire = jiffies + HZ;
  299. + init_timer(&m->timer);
  300. + m->timer.expires = expire;
  301. + m->timer.data = (unsigned long)lo;
  302. + m->timer.function = keyScrubTimerFn;
  303. + add_timer(&m->timer);
  304. +}
  305. - page = grab_cache_page(mapping, index);
  306. - if (!page)
  307. - goto fail;
  308. - kaddr = kmap(page);
  309. - if (aops->prepare_write(file, page, offset, offset+size))
  310. - goto unlock;
  311. - flush_dcache_page(page);
  312. - transfer_result = lo_do_transfer(lo, WRITE, kaddr + offset, data, size, IV);
  313. - if (transfer_result) {
  314. - /*
  315. - * The transfer failed, but we still write the data to
  316. - * keep prepare/commit calls balanced.
  317. - */
  318. - printk(KERN_ERR "loop: transfer error block %ld\n", index);
  319. - memset(kaddr + offset, 0, size);
  320. - }
  321. - if (aops->commit_write(file, page, offset, offset+size))
  322. - goto unlock;
  323. - if (transfer_result)
  324. - goto unlock;
  325. - kunmap(page);
  326. - data += size;
  327. - len -= size;
  328. - offset = 0;
  329. - index++;
  330. - pos += size;
  331. - UnlockPage(page);
  332. - page_cache_release(page);
  333. - }
  334. - up(&mapping->host->i_sem);
  335. - return 0;
  336. +/* called only from timer handler context */
  337. +static void keyScrubTimerFn(unsigned long d)
  338. +{
  339. + struct loop_device *lo = (struct loop_device *)d;
  340. + extern void loop_add_keyscrub_fn(struct loop_device *, void (*)(void *), void *);
  341. -unlock:
  342. - kunmap(page);
  343. - UnlockPage(page);
  344. - page_cache_release(page);
  345. -fail:
  346. - up(&mapping->host->i_sem);
  347. - return -1;
  348. + /* rw lock needs process context, so make loop thread do scrubbing */
  349. + loop_add_keyscrub_fn(lo, (void (*)(void*))keyScrubThreadFn, lo->key_data);
  350. + /* start timer again */
  351. + keyScrubTimerInit(lo);
  352. }
  353. +#endif
  354. -struct lo_read_data {
  355. - struct loop_device *lo;
  356. - char *data;
  357. - int bsize;
  358. -};
  359. -
  360. -static int lo_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
  361. +static AESmultiKey *allocMultiKey(void)
  362. {
  363. - char *kaddr;
  364. - unsigned long count = desc->count;
  365. - struct lo_read_data *p = (struct lo_read_data*)desc->buf;
  366. - struct loop_device *lo = p->lo;
  367. - int IV = page->index * (PAGE_CACHE_SIZE/p->bsize) + offset/p->bsize;
  368. + AESmultiKey *m;
  369. + aes_context *a;
  370. + int x = 0, n;
  371. +
  372. + m = (AESmultiKey *) kmalloc(sizeof(AESmultiKey), GFP_KERNEL);
  373. + if(!m) return 0;
  374. + memset(m, 0, sizeof(AESmultiKey));
  375. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  376. + rwlock_init(&m->rwlock);
  377. + init_timer(&m->timer);
  378. + again:
  379. +#endif
  380. - if (size > count)
  381. - size = count;
  382. + n = PAGE_SIZE / sizeof(aes_context);
  383. + if(!n) n = 1;
  384. - kaddr = kmap(page);
  385. - if (lo_do_transfer(lo, READ, kaddr + offset, p->data, size, IV)) {
  386. - size = 0;
  387. - printk(KERN_ERR "loop: transfer error block %ld\n",page->index);
  388. - desc->error = -EINVAL;
  389. - }
  390. - kunmap(page);
  391. -
  392. - desc->count = count - size;
  393. - desc->written += size;
  394. - p->data += size;
  395. - return size;
  396. -}
  397. -
  398. -static int lo_receive(struct loop_device *lo, struct buffer_head *bh, int bsize,
  399. - loff_t pos)
  400. -{
  401. - struct lo_read_data cookie;
  402. - read_descriptor_t desc;
  403. - struct file *file;
  404. -
  405. - cookie.lo = lo;
  406. - cookie.data = bh->b_data;
  407. - cookie.bsize = bsize;
  408. - desc.written = 0;
  409. - desc.count = bh->b_size;
  410. - desc.buf = (char*)&cookie;
  411. - desc.error = 0;
  412. - spin_lock_irq(&lo->lo_lock);
  413. - file = lo->lo_backing_file;
  414. - spin_unlock_irq(&lo->lo_lock);
  415. - do_generic_file_read(file, &pos, &desc, lo_read_actor);
  416. - return desc.error;
  417. + a = (aes_context *) kmalloc(sizeof(aes_context) * n, GFP_KERNEL);
  418. + if(!a) {
  419. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  420. + if(x) kfree(m->keyPtr[0]);
  421. +#endif
  422. + kfree(m);
  423. + return 0;
  424. + }
  425. +
  426. + while((x < KEY_ALLOC_COUNT) && n) {
  427. + m->keyPtr[x] = a;
  428. + a++;
  429. + x++;
  430. + n--;
  431. + }
  432. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  433. + if(x < 2) goto again;
  434. +#endif
  435. + return m;
  436. }
  437. -static inline int loop_get_bs(struct loop_device *lo)
  438. +static void clearAndFreeMultiKey(AESmultiKey *m)
  439. {
  440. - int bs = 0;
  441. + aes_context *a;
  442. + int x, n;
  443. - if (blksize_size[MAJOR(lo->lo_device)])
  444. - bs = blksize_size[MAJOR(lo->lo_device)][MINOR(lo->lo_device)];
  445. - if (!bs)
  446. - bs = BLOCK_SIZE;
  447. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  448. + /* stop scrub timer. loop thread was killed earlier */
  449. + del_timer_sync(&m->timer);
  450. + /* make sure allocated keys are in original order */
  451. + if(m->reversed) keyScrubWork(m);
  452. +#endif
  453. + n = PAGE_SIZE / sizeof(aes_context);
  454. + if(!n) n = 1;
  455. +
  456. + x = 0;
  457. + while(x < KEY_ALLOC_COUNT) {
  458. + a = m->keyPtr[x];
  459. + if(!a) break;
  460. + memset(a, 0, sizeof(aes_context) * n);
  461. + kfree(a);
  462. + x += n;
  463. + }
  464. +
  465. + kfree(m);
  466. +}
  467. +
  468. +static int multiKeySetup(struct loop_device *lo, unsigned char *k)
  469. +{
  470. + AESmultiKey *m;
  471. + aes_context *a;
  472. + int x, y, n, err = 0;
  473. + union {
  474. + u_int32_t w[8]; /* needed for 4 byte alignment for b[] */
  475. + unsigned char b[32];
  476. + } un;
  477. +
  478. + if(lo->lo_key_owner != current->uid && !capable(CAP_SYS_ADMIN))
  479. + return -EPERM;
  480. +
  481. + m = (AESmultiKey *)lo->key_data;
  482. + if(!m) return -ENXIO;
  483. +
  484. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  485. + /* temporarily prevent loop thread from messing with keys */
  486. + write_lock(&m->rwlock);
  487. + m->blocked = 1;
  488. + /* make sure allocated keys are in original order */
  489. + if(m->reversed) keyScrubWork(m);
  490. + write_unlock(&m->rwlock);
  491. +#endif
  492. + n = PAGE_SIZE / sizeof(aes_context);
  493. + if(!n) n = 1;
  494. - return bs;
  495. + x = 0;
  496. + while(x < KEY_ALLOC_COUNT) {
  497. + if(!m->keyPtr[x]) {
  498. + a = (aes_context *) kmalloc(sizeof(aes_context) * n, GFP_KERNEL);
  499. + if(!a) {
  500. + err = -ENOMEM;
  501. + goto error_out;
  502. + }
  503. + y = x;
  504. + while((y < (x + n)) && (y < KEY_ALLOC_COUNT)) {
  505. + m->keyPtr[y] = a;
  506. + a++;
  507. + y++;
  508. + }
  509. + }
  510. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  511. + if(x >= 64) {
  512. + x++;
  513. + continue;
  514. + }
  515. +#endif
  516. + if(copy_from_user(&un.b[0], k, 32)) {
  517. + err = -EFAULT;
  518. + goto error_out;
  519. + }
  520. + aes_set_key(m->keyPtr[x], &un.b[0], lo->lo_encrypt_key_size, 0);
  521. + k += 32;
  522. + x++;
  523. + }
  524. + m->keyMask = 0x3F; /* range 0...63 */
  525. + lo->lo_flags |= 0x100000; /* multi-key (info exported to user space) */
  526. + memset(&un.b[0], 0, 32);
  527. +error_out:
  528. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  529. + /* re-enable loop thread key scrubbing */
  530. + write_lock(&m->rwlock);
  531. + m->blocked = 0;
  532. + write_unlock(&m->rwlock);
  533. +#endif
  534. + return err;
  535. }
  536. -static inline unsigned long loop_get_iv(struct loop_device *lo,
  537. - unsigned long sector)
  538. +void loop_compute_sector_iv(int devSect, u_int32_t *ivout)
  539. {
  540. - int bs = loop_get_bs(lo);
  541. - unsigned long offset, IV;
  542. + ivout[0] = cpu_to_le32(devSect);
  543. + ivout[3] = ivout[2] = ivout[1] = 0;
  544. +}
  545. - IV = sector / (bs >> 9) + lo->lo_offset / bs;
  546. - offset = ((sector % (bs >> 9)) << 9) + lo->lo_offset % bs;
  547. - if (offset >= bs)
  548. - IV++;
  549. +void loop_compute_md5_iv(int devSect, u_int32_t *ivout, u_int32_t *data)
  550. +{
  551. + int x;
  552. +#if defined(__BIG_ENDIAN)
  553. + int y, e;
  554. +#endif
  555. + u_int32_t buf[16];
  556. - return IV;
  557. + ivout[0] = 0x67452301;
  558. + ivout[1] = 0xefcdab89;
  559. + ivout[2] = 0x98badcfe;
  560. + ivout[3] = 0x10325476;
  561. +
  562. +#if defined(__BIG_ENDIAN)
  563. + y = 7;
  564. + e = 16;
  565. + do {
  566. + if (!y) {
  567. + e = 12;
  568. + /* md5_transform_CPUbyteorder wants data in CPU byte order */
  569. + /* devSect is already in CPU byte order -- no need to convert */
  570. + /* 32 bits of sector number + 24 zero bits */
  571. + buf[12] = devSect;
  572. + buf[13] = 0x80000000;
  573. + /* 4024 bits == 31 * 128 bit plaintext blocks + 56 bits of sector number */
  574. + buf[14] = 4024;
  575. + buf[15] = 0;
  576. + }
  577. + x = 0;
  578. + do {
  579. + buf[x ] = cpu_to_le32(data[0]);
  580. + buf[x + 1] = cpu_to_le32(data[1]);
  581. + buf[x + 2] = cpu_to_le32(data[2]);
  582. + buf[x + 3] = cpu_to_le32(data[3]);
  583. + x += 4;
  584. + data += 4;
  585. + } while (x < e);
  586. + md5_transform_CPUbyteorder(&ivout[0], &buf[0]);
  587. + } while (--y >= 0);
  588. + ivout[0] = cpu_to_le32(ivout[0]);
  589. + ivout[1] = cpu_to_le32(ivout[1]);
  590. + ivout[2] = cpu_to_le32(ivout[2]);
  591. + ivout[3] = cpu_to_le32(ivout[3]);
  592. +#else
  593. + x = 6;
  594. + do {
  595. + md5_transform_CPUbyteorder(&ivout[0], data);
  596. + data += 16;
  597. + } while (--x >= 0);
  598. + memcpy(buf, data, 48);
  599. + /* md5_transform_CPUbyteorder wants data in CPU byte order */
  600. + /* devSect is already in CPU byte order -- no need to convert */
  601. + /* 32 bits of sector number + 24 zero bits */
  602. + buf[12] = devSect;
  603. + buf[13] = 0x80000000;
  604. + /* 4024 bits == 31 * 128 bit plaintext blocks + 56 bits of sector number */
  605. + buf[14] = 4024;
  606. + buf[15] = 0;
  607. + md5_transform_CPUbyteorder(&ivout[0], &buf[0]);
  608. +#endif
  609. }
  610. -static int do_bh_filebacked(struct loop_device *lo, struct buffer_head *bh, int rw)
  611. +static int transfer_aes(struct loop_device *lo, int cmd, char *raw_buf,
  612. + char *loop_buf, int size, int devSect)
  613. {
  614. - loff_t pos;
  615. - int ret;
  616. + aes_context *a;
  617. + AESmultiKey *m;
  618. + int x;
  619. + unsigned y;
  620. + u_int32_t iv[8];
  621. +
  622. + if(!size || (size & 511)) {
  623. + return -EINVAL;
  624. + }
  625. + m = (AESmultiKey *)lo->key_data;
  626. + y = m->keyMask;
  627. + if(cmd == READ) {
  628. + while(size) {
  629. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  630. + read_lock(&m->rwlock);
  631. +#endif
  632. + a = m->keyPtr[((unsigned)devSect) & y];
  633. + if(y) {
  634. + memcpy(&iv[0], raw_buf, 16);
  635. + raw_buf += 16;
  636. + loop_buf += 16;
  637. + } else {
  638. + loop_compute_sector_iv(devSect, &iv[0]);
  639. + }
  640. + x = 15;
  641. + do {
  642. + memcpy(&iv[4], raw_buf, 16);
  643. + aes_decrypt(a, raw_buf, loop_buf);
  644. + *((u_int32_t *)(&loop_buf[ 0])) ^= iv[0];
  645. + *((u_int32_t *)(&loop_buf[ 4])) ^= iv[1];
  646. + *((u_int32_t *)(&loop_buf[ 8])) ^= iv[2];
  647. + *((u_int32_t *)(&loop_buf[12])) ^= iv[3];
  648. + if(y && !x) {
  649. + raw_buf -= 496;
  650. + loop_buf -= 496;
  651. + loop_compute_md5_iv(devSect, &iv[4], (u_int32_t *)(&loop_buf[16]));
  652. + } else {
  653. + raw_buf += 16;
  654. + loop_buf += 16;
  655. + memcpy(&iv[0], raw_buf, 16);
  656. + }
  657. + aes_decrypt(a, raw_buf, loop_buf);
  658. + *((u_int32_t *)(&loop_buf[ 0])) ^= iv[4];
  659. + *((u_int32_t *)(&loop_buf[ 4])) ^= iv[5];
  660. + *((u_int32_t *)(&loop_buf[ 8])) ^= iv[6];
  661. + *((u_int32_t *)(&loop_buf[12])) ^= iv[7];
  662. + if(y && !x) {
  663. + raw_buf += 512;
  664. + loop_buf += 512;
  665. + } else {
  666. + raw_buf += 16;
  667. + loop_buf += 16;
  668. + }
  669. + } while(--x >= 0);
  670. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  671. + read_unlock(&m->rwlock);
  672. +#endif
  673. + if(current->need_resched) {set_current_state(TASK_RUNNING);schedule();}
  674. + size -= 512;
  675. + devSect++;
  676. + }
  677. + } else {
  678. + while(size) {
  679. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  680. + read_lock(&m->rwlock);
  681. +#endif
  682. + a = m->keyPtr[((unsigned)devSect) & y];
  683. + if(y) {
  684. + /* on 2.4 and later kernels, real raw_buf is not doing */
  685. + /* any writes now so it can be used as temp buffer */
  686. + memcpy(raw_buf, loop_buf, 512);
  687. + loop_compute_md5_iv(devSect, &iv[0], (u_int32_t *)(&raw_buf[16]));
  688. + x = 15;
  689. + do {
  690. + iv[0] ^= *((u_int32_t *)(&raw_buf[ 0]));
  691. + iv[1] ^= *((u_int32_t *)(&raw_buf[ 4]));
  692. + iv[2] ^= *((u_int32_t *)(&raw_buf[ 8]));
  693. + iv[3] ^= *((u_int32_t *)(&raw_buf[12]));
  694. + aes_encrypt(a, (unsigned char *)(&iv[0]), raw_buf);
  695. + memcpy(&iv[0], raw_buf, 16);
  696. + raw_buf += 16;
  697. + iv[0] ^= *((u_int32_t *)(&raw_buf[ 0]));
  698. + iv[1] ^= *((u_int32_t *)(&raw_buf[ 4]));
  699. + iv[2] ^= *((u_int32_t *)(&raw_buf[ 8]));
  700. + iv[3] ^= *((u_int32_t *)(&raw_buf[12]));
  701. + aes_encrypt(a, (unsigned char *)(&iv[0]), raw_buf);
  702. + memcpy(&iv[0], raw_buf, 16);
  703. + raw_buf += 16;
  704. + } while(--x >= 0);
  705. + loop_buf += 512;
  706. + } else {
  707. + loop_compute_sector_iv(devSect, &iv[0]);
  708. + x = 15;
  709. + do {
  710. + iv[0] ^= *((u_int32_t *)(&loop_buf[ 0]));
  711. + iv[1] ^= *((u_int32_t *)(&loop_buf[ 4]));
  712. + iv[2] ^= *((u_int32_t *)(&loop_buf[ 8]));
  713. + iv[3] ^= *((u_int32_t *)(&loop_buf[12]));
  714. + aes_encrypt(a, (unsigned char *)(&iv[0]), raw_buf);
  715. + memcpy(&iv[0], raw_buf, 16);
  716. + loop_buf += 16;
  717. + raw_buf += 16;
  718. + iv[0] ^= *((u_int32_t *)(&loop_buf[ 0]));
  719. + iv[1] ^= *((u_int32_t *)(&loop_buf[ 4]));
  720. + iv[2] ^= *((u_int32_t *)(&loop_buf[ 8]));
  721. + iv[3] ^= *((u_int32_t *)(&loop_buf[12]));
  722. + aes_encrypt(a, (unsigned char *)(&iv[0]), raw_buf);
  723. + memcpy(&iv[0], raw_buf, 16);
  724. + loop_buf += 16;
  725. + raw_buf += 16;
  726. + } while(--x >= 0);
  727. + }
  728. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  729. + read_unlock(&m->rwlock);
  730. +#endif
  731. + if(current->need_resched) {set_current_state(TASK_RUNNING);schedule();}
  732. + size -= 512;
  733. + devSect++;
  734. + }
  735. + }
  736. + return(0);
  737. +}
  738. +
  739. +static int keySetup_aes(struct loop_device *lo, struct loop_info *info)
  740. +{
  741. + AESmultiKey *m;
  742. + union {
  743. + u_int32_t w[8]; /* needed for 4 byte alignment for b[] */
  744. + unsigned char b[32];
  745. + } un;
  746. +
  747. + lo->key_data = m = allocMultiKey();
  748. + if(!m) return(-ENOMEM);
  749. + memcpy(&un.b[0], &info->lo_encrypt_key[0], 32);
  750. + aes_set_key(m->keyPtr[0], &un.b[0], info->lo_encrypt_key_size, 0);
  751. + memset(&info->lo_encrypt_key[0], 0, sizeof(info->lo_encrypt_key));
  752. + memset(&un.b[0], 0, 32);
  753. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  754. + keyScrubTimerInit(lo);
  755. +#endif
  756. + return(0);
  757. +}
  758. - pos = ((loff_t) bh->b_rsector << 9) + lo->lo_offset;
  759. +static int keyClean_aes(struct loop_device *lo)
  760. +{
  761. + if(lo->key_data) {
  762. + clearAndFreeMultiKey((AESmultiKey *)lo->key_data);
  763. + lo->key_data = 0;
  764. + }
  765. + return(0);
  766. +}
  767. - if (rw == WRITE)
  768. - ret = lo_send(lo, bh, loop_get_bs(lo), pos);
  769. - else
  770. - ret = lo_receive(lo, bh, loop_get_bs(lo), pos);
  771. +static int handleIoctl_aes(struct loop_device *lo, int cmd, unsigned long arg)
  772. +{
  773. + int err;
  774. +
  775. + switch (cmd) {
  776. + case LOOP_MULTI_KEY_SETUP:
  777. + err = multiKeySetup(lo, (unsigned char *)arg);
  778. + break;
  779. + default:
  780. + err = -EINVAL;
  781. + }
  782. + return err;
  783. +}
  784. +
  785. +static struct loop_func_table funcs_aes = {
  786. + number: 16, /* 16 == AES */
  787. + transfer: transfer_aes,
  788. + init: keySetup_aes,
  789. + release: keyClean_aes,
  790. + ioctl: handleIoctl_aes
  791. +};
  792. +
  793. +EXPORT_SYMBOL(loop_compute_sector_iv);
  794. +EXPORT_SYMBOL(loop_compute_md5_iv);
  795. +#endif /* CONFIG_BLK_DEV_LOOP_AES */
  796. +
  797. +/* xfer_funcs[0] is special - its release function is never called */
  798. +struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {
  799. + &none_funcs,
  800. + &xor_funcs,
  801. +#if CONFIG_BLK_DEV_LOOP_AES
  802. + [LO_CRYPT_AES] = &funcs_aes,
  803. +#endif
  804. +};
  805. - return ret;
  806. +/*
  807. + * First number of 'lo_prealloc' is the default number of RAM pages
  808. + * to pre-allocate for each device backed loop. Every (configured)
  809. + * device backed loop pre-allocates this amount of RAM pages unless
  810. + * later 'lo_prealloc' numbers provide an override. 'lo_prealloc'
  811. + * overrides are defined in pairs: loop_index,number_of_pages
  812. + */
  813. +static int lo_prealloc[9] = { 125, 999, 0, 999, 0, 999, 0, 999, 0 };
  814. +#define LO_PREALLOC_MIN 4 /* minimum user defined pre-allocated RAM pages */
  815. +#define LO_PREALLOC_MAX 512 /* maximum user defined pre-allocated RAM pages */
  816. +
  817. +#ifdef MODULE
  818. +MODULE_PARM(lo_prealloc, "1-9i");
  819. +MODULE_PARM_DESC(lo_prealloc, "Number of pre-allocated pages [,index,pages]...");
  820. +#else
  821. +static int __init lo_prealloc_setup(char *str)
  822. +{
  823. + int x, y, z;
  824. +
  825. + for (x = 0; x < (sizeof(lo_prealloc) / sizeof(int)); x++) {
  826. + z = get_option(&str, &y);
  827. + if (z > 0)
  828. + lo_prealloc[x] = y;
  829. + if (z < 2)
  830. + break;
  831. + }
  832. + return 1;
  833. }
  834. +__setup("lo_prealloc=", lo_prealloc_setup);
  835. +#endif
  836. -static void loop_end_io_transfer(struct buffer_head *bh, int uptodate);
  837. -static void loop_put_buffer(struct buffer_head *bh)
  838. +/*
  839. + * This is loop helper thread nice value in range
  840. + * from 0 (low priority) to -20 (high priority).
  841. + */
  842. +#if defined(DEF_NICE) && defined(DEF_COUNTER)
  843. +static int lo_nice = -20; /* old scheduler default */
  844. +#else
  845. +static int lo_nice = -1; /* O(1) scheduler default */
  846. +#endif
  847. +
  848. +#ifdef MODULE
  849. +MODULE_PARM(lo_nice, "1i");
  850. +MODULE_PARM_DESC(lo_nice, "Loop thread scheduler nice (0 ... -20)");
  851. +#else
  852. +static int __init lo_nice_setup(char *str)
  853. {
  854. - /*
  855. - * check b_end_io, may just be a remapped bh and not an allocated one
  856. - */
  857. - if (bh && bh->b_end_io == loop_end_io_transfer) {
  858. + int y;
  859. +
  860. + if (get_option(&str, &y) == 1)
  861. + lo_nice = y;
  862. + return 1;
  863. +}
  864. +__setup("lo_nice=", lo_nice_setup);
  865. +#endif
  866. +
  867. +typedef struct {
  868. + struct buffer_head **q0;
  869. + struct buffer_head **q1;
  870. + struct buffer_head **q2;
  871. + int x0;
  872. + int x1;
  873. + int x2;
  874. +} que_look_up_table;
  875. +
  876. +static void loop_prealloc_cleanup(struct loop_device *lo)
  877. +{
  878. + struct buffer_head *bh;
  879. +
  880. + while ((bh = lo->lo_bh_free)) {
  881. __free_page(bh->b_page);
  882. + lo->lo_bh_free = bh->b_reqnext;
  883. + bh->b_reqnext = NULL;
  884. kmem_cache_free(bh_cachep, bh);
  885. }
  886. }
  887. -/*
  888. - * Add buffer_head to back of pending list
  889. - */
  890. -static void loop_add_bh(struct loop_device *lo, struct buffer_head *bh)
  891. +static int loop_prealloc_init(struct loop_device *lo, int y)
  892. +{
  893. + struct buffer_head *bh;
  894. + int x;
  895. +
  896. + if(!y) {
  897. + y = lo_prealloc[0];
  898. + for (x = 1; x < (sizeof(lo_prealloc) / sizeof(int)); x += 2) {
  899. + if (lo_prealloc[x + 1] && (lo->lo_number == lo_prealloc[x])) {
  900. + y = lo_prealloc[x + 1];
  901. + break;
  902. + }
  903. + }
  904. + }
  905. + lo->lo_bh_flsh = (y * 3) / 4;
  906. +
  907. + for (x = 0; x < y; x++) {
  908. + bh = kmem_cache_alloc(bh_cachep, SLAB_KERNEL);
  909. + if (!bh) {
  910. + loop_prealloc_cleanup(lo);
  911. + return 1;
  912. + }
  913. + bh->b_page = alloc_page(GFP_KERNEL);
  914. + if (!bh->b_page) {
  915. + bh->b_reqnext = NULL;
  916. + kmem_cache_free(bh_cachep, bh);
  917. + loop_prealloc_cleanup(lo);
  918. + return 1;
  919. + }
  920. + bh->b_reqnext = lo->lo_bh_free;
  921. + lo->lo_bh_free = bh;
  922. + }
  923. + return 0;
  924. +}
  925. +
  926. +static void loop_add_queue_last(struct loop_device *lo, struct buffer_head *bh, struct buffer_head **q)
  927. {
  928. unsigned long flags;
  929. spin_lock_irqsave(&lo->lo_lock, flags);
  930. - if (lo->lo_bhtail) {
  931. - lo->lo_bhtail->b_reqnext = bh;
  932. - lo->lo_bhtail = bh;
  933. - } else
  934. - lo->lo_bh = lo->lo_bhtail = bh;
  935. + if (*q) {
  936. + bh->b_reqnext = (*q)->b_reqnext;
  937. + (*q)->b_reqnext = bh;
  938. + } else {
  939. + bh->b_reqnext = bh;
  940. + }
  941. + *q = bh;
  942. spin_unlock_irqrestore(&lo->lo_lock, flags);
  943. - up(&lo->lo_bh_mutex);
  944. + if (waitqueue_active(&lo->lo_bh_wait))
  945. + wake_up_interruptible(&lo->lo_bh_wait);
  946. }
  947. -/*
  948. - * Grab first pending buffer
  949. - */
  950. -static struct buffer_head *loop_get_bh(struct loop_device *lo)
  951. +static void loop_add_queue_first(struct loop_device *lo, struct buffer_head *bh, struct buffer_head **q)
  952. {
  953. - struct buffer_head *bh;
  954. + spin_lock_irq(&lo->lo_lock);
  955. + if (*q) {
  956. + bh->b_reqnext = (*q)->b_reqnext;
  957. + (*q)->b_reqnext = bh;
  958. + } else {
  959. + bh->b_reqnext = bh;
  960. + *q = bh;
  961. + }
  962. + spin_unlock_irq(&lo->lo_lock);
  963. +}
  964. +
  965. +static struct buffer_head *loop_get_bh(struct loop_device *lo, int *list_nr,
  966. + que_look_up_table *qt)
  967. +{
  968. + struct buffer_head *bh = NULL, *last;
  969. spin_lock_irq(&lo->lo_lock);
  970. - if ((bh = lo->lo_bh)) {
  971. - if (bh == lo->lo_bhtail)
  972. - lo->lo_bhtail = NULL;
  973. - lo->lo_bh = bh->b_reqnext;
  974. + if ((last = *qt->q0)) {
  975. + bh = last->b_reqnext;
  976. + if (bh == last)
  977. + *qt->q0 = NULL;
  978. + else
  979. + last->b_reqnext = bh->b_reqnext;
  980. + bh->b_reqnext = NULL;
  981. + *list_nr = qt->x0;
  982. + } else if ((last = *qt->q1)) {
  983. + bh = last->b_reqnext;
  984. + if (bh == last)
  985. + *qt->q1 = NULL;
  986. + else
  987. + last->b_reqnext = bh->b_reqnext;
  988. bh->b_reqnext = NULL;
  989. + *list_nr = qt->x1;
  990. + } else if ((last = *qt->q2)) {
  991. + bh = last->b_reqnext;
  992. + if (bh == last)
  993. + *qt->q2 = NULL;
  994. + else
  995. + last->b_reqnext = bh->b_reqnext;
  996. + bh->b_reqnext = NULL;
  997. + *list_nr = qt->x2;
  998. }
  999. spin_unlock_irq(&lo->lo_lock);
  1000. -
  1001. return bh;
  1002. }
  1003. -/*
  1004. - * when buffer i/o has completed. if BH_Dirty is set, this was a WRITE
  1005. - * and lo->transfer stuff has already been done. if not, it was a READ
  1006. - * so queue it for the loop thread and let it do the transfer out of
  1007. - * b_end_io context (we don't want to do decrypt of a page with irqs
  1008. - * disabled)
  1009. - */
  1010. -static void loop_end_io_transfer(struct buffer_head *bh, int uptodate)
  1011. +static void loop_put_buffer(struct loop_device *lo, struct buffer_head *b)
  1012. +{
  1013. + unsigned long flags;
  1014. + int wk;
  1015. +
  1016. + spin_lock_irqsave(&lo->lo_lock, flags);
  1017. + b->b_reqnext = lo->lo_bh_free;
  1018. + lo->lo_bh_free = b;
  1019. + wk = lo->lo_bh_need;
  1020. + spin_unlock_irqrestore(&lo->lo_lock, flags);
  1021. +
  1022. + if (wk && waitqueue_active(&lo->lo_bh_wait))
  1023. + wake_up_interruptible(&lo->lo_bh_wait);
  1024. +}
  1025. +
  1026. +static void loop_end_io_transfer_wr(struct buffer_head *bh, int uptodate)
  1027. {
  1028. struct loop_device *lo = &loop_dev[MINOR(bh->b_dev)];
  1029. + struct buffer_head *rbh = bh->b_private;
  1030. - if (!uptodate || test_bit(BH_Dirty, &bh->b_state)) {
  1031. - struct buffer_head *rbh = bh->b_private;
  1032. + rbh->b_reqnext = NULL;
  1033. + rbh->b_end_io(rbh, uptodate);
  1034. + loop_put_buffer(lo, bh);
  1035. + if (atomic_dec_and_test(&lo->lo_pending))
  1036. + wake_up_interruptible(&lo->lo_bh_wait);
  1037. +}
  1038. - rbh->b_end_io(rbh, uptodate);
  1039. - if (atomic_dec_and_test(&lo->lo_pending))
  1040. - up(&lo->lo_bh_mutex);
  1041. - loop_put_buffer(bh);
  1042. - } else
  1043. - loop_add_bh(lo, bh);
  1044. +static void loop_end_io_transfer_rd(struct buffer_head *bh, int uptodate)
  1045. +{
  1046. + struct loop_device *lo = &loop_dev[MINOR(bh->b_dev)];
  1047. +
  1048. + if (!uptodate)
  1049. + loop_end_io_transfer_wr(bh, uptodate);
  1050. + else
  1051. + loop_add_queue_last(lo, bh, &lo->lo_bh_que0);
  1052. }
  1053. static struct buffer_head *loop_get_buffer(struct loop_device *lo,
  1054. - struct buffer_head *rbh)
  1055. + struct buffer_head *rbh, int from_thread, int rw)
  1056. {
  1057. struct buffer_head *bh;
  1058. + struct page *p;
  1059. + unsigned long flags;
  1060. - /*
  1061. - * for xfer_funcs that can operate on the same bh, do that
  1062. - */
  1063. - if (lo->lo_flags & LO_FLAGS_BH_REMAP) {
  1064. - bh = rbh;
  1065. - goto out_bh;
  1066. + spin_lock_irqsave(&lo->lo_lock, flags);
  1067. + bh = lo->lo_bh_free;
  1068. + if (bh) {
  1069. + lo->lo_bh_free = bh->b_reqnext;
  1070. + if (from_thread)
  1071. + lo->lo_bh_need = 0;
  1072. + } else {
  1073. + if (from_thread)
  1074. + lo->lo_bh_need = 1;
  1075. }
  1076. + spin_unlock_irqrestore(&lo->lo_lock, flags);
  1077. + if (!bh)
  1078. + return (struct buffer_head *)0;
  1079. - do {
  1080. - bh = kmem_cache_alloc(bh_cachep, SLAB_NOIO);
  1081. - if (bh)
  1082. - break;
  1083. -
  1084. - run_task_queue(&tq_disk);
  1085. - set_current_state(TASK_INTERRUPTIBLE);
  1086. - schedule_timeout(HZ);
  1087. - } while (1);
  1088. - memset(bh, 0, sizeof(*bh));
  1089. + p = bh->b_page;
  1090. + memset(bh, 0, sizeof(struct buffer_head));
  1091. + bh->b_page = p;
  1092. + bh->b_private = rbh;
  1093. bh->b_size = rbh->b_size;
  1094. bh->b_dev = rbh->b_rdev;
  1095. + bh->b_rdev = lo->lo_device;
  1096. bh->b_state = (1 << BH_Req) | (1 << BH_Mapped) | (1 << BH_Lock);
  1097. + bh->b_data = page_address(bh->b_page);
  1098. + bh->b_end_io = (rw == WRITE) ? loop_end_io_transfer_wr : loop_end_io_transfer_rd;
  1099. + bh->b_rsector = rbh->b_rsector + lo->lo_offs_sec;
  1100. + init_waitqueue_head(&bh->b_wait);
  1101. +
  1102. + return bh;
  1103. +}
  1104. +
  1105. +static int figure_loop_size(struct loop_device *lo)
  1106. +{
  1107. + loff_t size, offs;
  1108. + unsigned int x;
  1109. + int err = 0;
  1110. + kdev_t lodev = lo->lo_device;
  1111. +
  1112. + offs = lo->lo_offset;
  1113. + if (S_ISREG(lo->lo_backing_file->f_dentry->d_inode->i_mode)) {
  1114. + size = lo->lo_backing_file->f_dentry->d_inode->i_size;
  1115. + } else {
  1116. + offs &= ~((loff_t)511);
  1117. + if (blk_size[MAJOR(lodev)])
  1118. + size = (loff_t)(blk_size[MAJOR(lodev)][MINOR(lodev)]) << BLOCK_SIZE_BITS;
  1119. + else
  1120. + size = 1024*1024*1024; /* unknown size */
  1121. + }
  1122. + if ((offs > 0) && (offs < size)) {
  1123. + size -= offs;
  1124. + } else {
  1125. + if (offs)
  1126. + err = -EINVAL;
  1127. + lo->lo_offset = 0;
  1128. + lo->lo_offs_sec = lo->lo_iv_remove = 0;
  1129. + }
  1130. + if ((lo->lo_sizelimit > 0) && (lo->lo_sizelimit <= size)) {
  1131. + size = lo->lo_sizelimit;
  1132. + } else {
  1133. + if (lo->lo_sizelimit)
  1134. + err = -EINVAL;
  1135. + lo->lo_sizelimit = 0;
  1136. + }
  1137. + size >>= BLOCK_SIZE_BITS;
  1138. /*
  1139. - * easy way out, although it does waste some memory for < PAGE_SIZE
  1140. - * blocks... if highmem bounce buffering can get away with it,
  1141. - * so can we :-)
  1142. + * Unfortunately, if we want to do I/O on the device,
  1143. + * the number of 1024-byte blocks has to fit into unsigned int
  1144. */
  1145. - do {
  1146. - bh->b_page = alloc_page(GFP_NOIO);
  1147. - if (bh->b_page)
  1148. - break;
  1149. + x = (unsigned int)size;
  1150. + if ((loff_t)x != size) {
  1151. + err = -EFBIG;
  1152. + size = 0;
  1153. + }
  1154. - run_task_queue(&tq_disk);
  1155. - set_current_state(TASK_INTERRUPTIBLE);
  1156. - schedule_timeout(HZ);
  1157. - } while (1);
  1158. + loop_sizes[lo->lo_number] = size;
  1159. + return err;
  1160. +}
  1161. - bh->b_data = page_address(bh->b_page);
  1162. - bh->b_end_io = loop_end_io_transfer;
  1163. - bh->b_private = rbh;
  1164. - init_waitqueue_head(&bh->b_wait);
  1165. +static int loop_file_io(struct file *file, char *buf, int size, loff_t *ppos, int w)
  1166. +{
  1167. + mm_segment_t fs;
  1168. + int x, y, z;
  1169. -out_bh:
  1170. - bh->b_rsector = rbh->b_rsector + (lo->lo_offset >> 9);
  1171. - spin_lock_irq(&lo->lo_lock);
  1172. - bh->b_rdev = lo->lo_device;
  1173. - spin_unlock_irq(&lo->lo_lock);
  1174. + y = 0;
  1175. + do {
  1176. + z = size - y;
  1177. + fs = get_fs();
  1178. + set_fs(get_ds());
  1179. + if (w) {
  1180. + x = file->f_op->write(file, buf + y, z, ppos);
  1181. + set_fs(fs);
  1182. + } else {
  1183. + x = file->f_op->read(file, buf + y, z, ppos);
  1184. + set_fs(fs);
  1185. + if (!x)
  1186. + return 1;
  1187. + }
  1188. + if (x < 0) {
  1189. + if ((x == -EAGAIN) || (x == -ENOMEM) || (x == -ERESTART) || (x == -EINTR)) {
  1190. + run_task_queue(&tq_disk);
  1191. + set_current_state(TASK_INTERRUPTIBLE);
  1192. + schedule_timeout(HZ / 2);
  1193. + continue;
  1194. + }
  1195. + return 1;
  1196. + }
  1197. + y += x;
  1198. + } while (y < size);
  1199. + return 0;
  1200. +}
  1201. - return bh;
  1202. +static int do_bh_filebacked(struct loop_device *lo, struct buffer_head *bh, int rw)
  1203. +{
  1204. + loff_t pos;
  1205. + struct file *file = lo->lo_backing_file;
  1206. + char *data, *buf;
  1207. + unsigned int size, len;
  1208. + unsigned long IV;
  1209. +
  1210. + pos = ((loff_t) bh->b_rsector << 9) + lo->lo_offset;
  1211. + buf = page_address(lo->lo_bh_free->b_page);
  1212. + len = bh->b_size;
  1213. + data = bh_kmap(bh);
  1214. + IV = bh->b_rsector;
  1215. + if (!lo->lo_iv_remove)
  1216. + IV += lo->lo_offs_sec;
  1217. + while (len > 0) {
  1218. + if (lo->lo_encrypt_type == LO_CRYPT_NONE) {
  1219. + /* this code relies that NONE transfer is a no-op */
  1220. + buf = data;
  1221. + }
  1222. + size = PAGE_SIZE;
  1223. + if (size > len)
  1224. + size = len;
  1225. + if (rw == WRITE) {
  1226. + if (lo_do_transfer(lo, WRITE, buf, data, size, IV)) {
  1227. + printk(KERN_ERR "loop%d: write transfer error, sector %lu\n", lo->lo_number, IV);
  1228. + goto kunmap_and_out;
  1229. + }
  1230. + if (loop_file_io(file, buf, size, &pos, 1)) {
  1231. + printk(KERN_ERR "loop%d: write i/o error, sector %lu\n", lo->lo_number, IV);
  1232. + goto kunmap_and_out;
  1233. + }
  1234. + } else {
  1235. + if (loop_file_io(file, buf, size, &pos, 0)) {
  1236. + printk(KERN_ERR "loop%d: read i/o error, sector %lu\n", lo->lo_number, IV);
  1237. + goto kunmap_and_out;
  1238. + }
  1239. + if (lo_do_transfer(lo, READ, buf, data, size, IV)) {
  1240. + printk(KERN_ERR "loop%d: read transfer error, sector %lu\n", lo->lo_number, IV);
  1241. + goto kunmap_and_out;
  1242. + }
  1243. + flush_dcache_page(bh->b_page);
  1244. + }
  1245. + data += size;
  1246. + len -= size;
  1247. + IV += size >> 9;
  1248. + }
  1249. + bh_kunmap(bh);
  1250. + return 0;
  1251. +
  1252. +kunmap_and_out:
  1253. + bh_kunmap(bh);
  1254. + return 1;
  1255. }
  1256. static int loop_make_request(request_queue_t *q, int rw, struct buffer_head *rbh)
  1257. {
  1258. - struct buffer_head *bh = NULL;
  1259. + struct buffer_head *bh;
  1260. struct loop_device *lo;
  1261. - unsigned long IV;
  1262. + char *md;
  1263. + set_current_state(TASK_RUNNING);
  1264. if (!buffer_locked(rbh))
  1265. BUG();
  1266. @@ -483,45 +1064,55 @@ static int loop_make_request(request_que
  1267. } else if (rw == READA) {
  1268. rw = READ;
  1269. } else if (rw != READ) {
  1270. - printk(KERN_ERR "loop: unknown command (%d)\n", rw);
  1271. + printk(KERN_ERR "loop%d: unknown command (%d)\n", lo->lo_number, rw);
  1272. goto err;
  1273. }
  1274. - rbh = blk_queue_bounce(q, rw, rbh);
  1275. -
  1276. /*
  1277. * file backed, queue for loop_thread to handle
  1278. */
  1279. if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
  1280. - /*
  1281. - * rbh locked at this point, noone else should clear
  1282. - * the dirty flag
  1283. - */
  1284. - if (rw == WRITE)
  1285. - set_bit(BH_Dirty, &rbh->b_state);
  1286. - loop_add_bh(lo, rbh);
  1287. + loop_add_queue_last(lo, rbh, (rw == WRITE) ? &lo->lo_bh_que1 : &lo->lo_bh_que0);
  1288. return 0;
  1289. }
  1290. /*
  1291. - * piggy old buffer on original, and submit for I/O
  1292. + * device backed, just remap rdev & rsector for NONE transfer
  1293. */
  1294. - bh = loop_get_buffer(lo, rbh);
  1295. - IV = loop_get_iv(lo, rbh->b_rsector);
  1296. + if (lo->lo_encrypt_type == LO_CRYPT_NONE) {
  1297. + rbh->b_rsector += lo->lo_offs_sec;
  1298. + rbh->b_rdev = lo->lo_device;
  1299. + generic_make_request(rw, rbh);
  1300. + if (atomic_dec_and_test(&lo->lo_pending))
  1301. + wake_up_interruptible(&lo->lo_bh_wait);
  1302. + return 0;
  1303. + }
  1304. +
  1305. + /*
  1306. + * device backed, start reads and writes now if buffer available
  1307. + */
  1308. + bh = loop_get_buffer(lo, rbh, 0, rw);
  1309. + if (!bh) {
  1310. + /* just queue request and let thread handle alloc later */
  1311. + loop_add_queue_last(lo, rbh, (rw == WRITE) ? &lo->lo_bh_que1 : &lo->lo_bh_que2);
  1312. + return 0;
  1313. + }
  1314. if (rw == WRITE) {
  1315. - set_bit(BH_Dirty, &bh->b_state);
  1316. - if (lo_do_transfer(lo, WRITE, bh->b_data, rbh->b_data,
  1317. - bh->b_size, IV))
  1318. + int trv;
  1319. + md = bh_kmap(rbh);
  1320. + trv = lo_do_transfer(lo, WRITE, bh->b_data, md, bh->b_size, bh->b_rsector - lo->lo_iv_remove);
  1321. + bh_kunmap(rbh);
  1322. + if (trv) {
  1323. + loop_put_buffer(lo, bh);
  1324. goto err;
  1325. + }
  1326. }
  1327. -
  1328. generic_make_request(rw, bh);
  1329. return 0;
  1330. err:
  1331. if (atomic_dec_and_test(&lo->lo_pending))
  1332. - up(&lo->lo_bh_mutex);
  1333. - loop_put_buffer(bh);
  1334. + wake_up_interruptible(&lo->lo_bh_wait);
  1335. out:
  1336. buffer_IO_error(rbh);
  1337. return 0;
  1338. @@ -530,30 +1121,6 @@ inactive:
  1339. goto out;
  1340. }
  1341. -static inline void loop_handle_bh(struct loop_device *lo,struct buffer_head *bh)
  1342. -{
  1343. - int ret;
  1344. -
  1345. - /*
  1346. - * For block backed loop, we know this is a READ
  1347. - */
  1348. - if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
  1349. - int rw = !!test_and_clear_bit(BH_Dirty, &bh->b_state);
  1350. -
  1351. - ret = do_bh_filebacked(lo, bh, rw);
  1352. - bh->b_end_io(bh, !ret);
  1353. - } else {
  1354. - struct buffer_head *rbh = bh->b_private;
  1355. - unsigned long IV = loop_get_iv(lo, rbh->b_rsector);
  1356. -
  1357. - ret = lo_do_transfer(lo, READ, bh->b_data, rbh->b_data,
  1358. - bh->b_size, IV);
  1359. -
  1360. - rbh->b_end_io(rbh, !ret);
  1361. - loop_put_buffer(bh);
  1362. - }
  1363. -}
  1364. -
  1365. /*
  1366. * worker thread that handles reads/writes to file backed loop devices,
  1367. * to avoid blocking in our make_request_fn. it also does loop decrypting
  1368. @@ -563,8 +1130,20 @@ static inline void loop_handle_bh(struct
  1369. static int loop_thread(void *data)
  1370. {
  1371. struct loop_device *lo = data;
  1372. - struct buffer_head *bh;
  1373. + struct buffer_head *bh, *xbh;
  1374. + int x, rw, qi = 0, flushcnt = 0;
  1375. + wait_queue_t waitq;
  1376. + que_look_up_table qt[4] = {
  1377. + { &lo->lo_bh_que0, &lo->lo_bh_que1, &lo->lo_bh_que2, 0, 1, 2 },
  1378. + { &lo->lo_bh_que2, &lo->lo_bh_que0, &lo->lo_bh_que1, 2, 0, 1 },
  1379. + { &lo->lo_bh_que0, &lo->lo_bh_que2, &lo->lo_bh_que1, 0, 2, 1 },
  1380. + { &lo->lo_bh_que1, &lo->lo_bh_que0, &lo->lo_bh_que2, 1, 0, 2 }
  1381. + };
  1382. + char *md;
  1383. + static const struct rlimit loop_rlim_defaults[RLIM_NLIMITS] = INIT_RLIMITS;
  1384. + init_waitqueue_entry(&waitq, current);
  1385. + memcpy(&current->rlim[0], &loop_rlim_defaults[0], sizeof(current->rlim));
  1386. daemonize();
  1387. exit_files(current);
  1388. reparent_to_init();
  1389. @@ -576,12 +1155,30 @@ static int loop_thread(void *data)
  1390. flush_signals(current);
  1391. spin_unlock_irq(&current->sigmask_lock);
  1392. + if (lo_nice > 0)
  1393. + lo_nice = 0;
  1394. + if (lo_nice < -20)
  1395. + lo_nice = -20;
  1396. +#if defined(DEF_NICE) && defined(DEF_COUNTER)
  1397. + /* old scheduler syntax */
  1398. + current->policy = SCHED_OTHER;
  1399. + current->nice = lo_nice;
  1400. +#else
  1401. + /* O(1) scheduler syntax */
  1402. + set_user_nice(current, lo_nice);
  1403. +#endif
  1404. +
  1405. spin_lock_irq(&lo->lo_lock);
  1406. lo->lo_state = Lo_bound;
  1407. atomic_inc(&lo->lo_pending);
  1408. spin_unlock_irq(&lo->lo_lock);
  1409. current->flags |= PF_NOIO;
  1410. +#if defined(PF_NOFREEZE)
  1411. + current->flags |= PF_NOFREEZE;
  1412. +#elif defined(PF_IOTHREAD)
  1413. + current->flags |= PF_IOTHREAD;
  1414. +#endif
  1415. /*
  1416. * up sem, we are running
  1417. @@ -589,23 +1186,120 @@ static int loop_thread(void *data)
  1418. up(&lo->lo_sem);
  1419. for (;;) {
  1420. - down_interruptible(&lo->lo_bh_mutex);
  1421. + add_wait_queue(&lo->lo_bh_wait, &waitq);
  1422. + for (;;) {
  1423. + set_current_state(TASK_INTERRUPTIBLE);
  1424. + if (!atomic_read(&lo->lo_pending))
  1425. + break;
  1426. +
  1427. + x = 0;
  1428. + spin_lock_irq(&lo->lo_lock);
  1429. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  1430. + if(lo->lo_keyscrub_fn) x = 1;
  1431. +#endif
  1432. + if (lo->lo_bh_que0) {
  1433. + x = 1;
  1434. + } else if (lo->lo_bh_que1 || lo->lo_bh_que2) {
  1435. + /* file backed works too because lo->lo_bh_need == 0 */
  1436. + if (lo->lo_bh_free || !lo->lo_bh_need)
  1437. + x = 1;
  1438. + }
  1439. + spin_unlock_irq(&lo->lo_lock);
  1440. + if (x)
  1441. + break;
  1442. +
  1443. + schedule();
  1444. + }
  1445. + set_current_state(TASK_RUNNING);
  1446. + remove_wait_queue(&lo->lo_bh_wait, &waitq);
  1447. +
  1448. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  1449. + if(lo->lo_keyscrub_fn) {
  1450. + (*lo->lo_keyscrub_fn)(lo->lo_keyscrub_ptr);
  1451. + lo->lo_keyscrub_fn = 0;
  1452. + }
  1453. +#endif
  1454. /*
  1455. - * could be upped because of tear-down, not because of
  1456. + * could be woken because of tear-down, not because of
  1457. * pending work
  1458. */
  1459. if (!atomic_read(&lo->lo_pending))
  1460. break;
  1461. - bh = loop_get_bh(lo);
  1462. - if (!bh) {
  1463. - printk("loop: missing bh\n");
  1464. + /*
  1465. + * read queues using alternating order to prevent starvation
  1466. + */
  1467. + bh = loop_get_bh(lo, &x, &qt[++qi & 3]);
  1468. + if (!bh)
  1469. continue;
  1470. +
  1471. + /*
  1472. + * x list tag usage(buffer-allocated)
  1473. + * --- -------------- -----------------------
  1474. + * 0 lo->lo_bh_que0 dev-read(y) / file-read
  1475. + * 1 lo->lo_bh_que1 dev-write(n) / file-write
  1476. + * 2 lo->lo_bh_que2 dev-read(n)
  1477. + */
  1478. + rw = (x == 1) ? WRITE : READ;
  1479. + if ((x >= 1) && !(lo->lo_flags & LO_FLAGS_DO_BMAP)) {
  1480. + /* loop_make_request didn't allocate a buffer, do that now */
  1481. + xbh = loop_get_buffer(lo, bh, 1, rw);
  1482. + if (!xbh) {
  1483. + run_task_queue(&tq_disk);
  1484. + flushcnt = 0;
  1485. + loop_add_queue_first(lo, bh, (rw == WRITE) ? &lo->lo_bh_que1 : &lo->lo_bh_que2);
  1486. + /* lo->lo_bh_need should be 1 now, go back to sleep */
  1487. + continue;
  1488. + }
  1489. + if (rw == WRITE) {
  1490. + int trv;
  1491. + md = bh_kmap(bh);
  1492. + trv = lo_do_transfer(lo, WRITE, xbh->b_data, md, xbh->b_size, xbh->b_rsector - lo->lo_iv_remove);
  1493. + bh_kunmap(bh);
  1494. + if (trv) {
  1495. + loop_put_buffer(lo, xbh);
  1496. + buffer_IO_error(bh);
  1497. + atomic_dec(&lo->lo_pending);
  1498. + continue;
  1499. + }
  1500. + }
  1501. + generic_make_request(rw, xbh);
  1502. +
  1503. + /* start I/O if there are no more requests lacking buffers */
  1504. + x = 0;
  1505. + spin_lock_irq(&lo->lo_lock);
  1506. + if (!lo->lo_bh_que1 && !lo->lo_bh_que2)
  1507. + x = 1;
  1508. + spin_unlock_irq(&lo->lo_lock);
  1509. + if (x || (++flushcnt >= lo->lo_bh_flsh)) {
  1510. + run_task_queue(&tq_disk);
  1511. + flushcnt = 0;
  1512. + }
  1513. +
  1514. + /* request not completely processed yet */
  1515. + continue;
  1516. + }
  1517. + if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
  1518. + /* request is for file backed device */
  1519. + x = do_bh_filebacked(lo, bh, rw);
  1520. + bh->b_reqnext = NULL;
  1521. + bh->b_end_io(bh, !x);
  1522. + } else {
  1523. + /* device backed read has completed, do decrypt now */
  1524. + xbh = bh->b_private;
  1525. + /* must not use bh->b_rsector as IV, as it may be modified by LVM at this point */
  1526. + /* instead, recompute IV from original request */
  1527. + md = bh_kmap(xbh);
  1528. + x = lo_do_transfer(lo, READ, bh->b_data, md, bh->b_size, xbh->b_rsector + lo->lo_offs_sec - lo->lo_iv_remove);
  1529. + flush_dcache_page(xbh->b_page);
  1530. + bh_kunmap(xbh);
  1531. + xbh->b_reqnext = NULL;
  1532. + xbh->b_end_io(xbh, !x);
  1533. + loop_put_buffer(lo, bh);
  1534. }
  1535. - loop_handle_bh(lo, bh);
  1536. /*
  1537. - * upped both for pending work and tear-down, lo_pending
  1538. + * woken both for pending work and tear-down, lo_pending
  1539. * will hit zero then
  1540. */
  1541. if (atomic_dec_and_test(&lo->lo_pending))
  1542. @@ -616,15 +1310,34 @@ static int loop_thread(void *data)
  1543. return 0;
  1544. }
  1545. +static void loop_set_softblksz(struct loop_device *lo, kdev_t dev)
  1546. +{
  1547. + int bs = 0, x;
  1548. +
  1549. + if (blksize_size[MAJOR(lo->lo_device)])
  1550. + bs = blksize_size[MAJOR(lo->lo_device)][MINOR(lo->lo_device)];
  1551. + if (!bs)
  1552. + bs = BLOCK_SIZE;
  1553. + if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
  1554. + x = loop_sizes[lo->lo_number];
  1555. + if ((bs == 8192) && (x & 7))
  1556. + bs = 4096;
  1557. + if ((bs == 4096) && (x & 3))
  1558. + bs = 2048;
  1559. + if ((bs == 2048) && (x & 1))
  1560. + bs = 1024;
  1561. + }
  1562. + set_blocksize(dev, bs);
  1563. +}
  1564. +
  1565. static int loop_set_fd(struct loop_device *lo, struct file *lo_file, kdev_t dev,
  1566. unsigned int arg)
  1567. {
  1568. struct file *file;
  1569. struct inode *inode;
  1570. kdev_t lo_device;
  1571. - int lo_flags = 0;
  1572. + int lo_flags = 0, hardsz = 512;
  1573. int error;
  1574. - int bs;
  1575. MOD_INC_USE_COUNT;
  1576. @@ -643,33 +1356,49 @@ static int loop_set_fd(struct loop_devic
  1577. if (!(file->f_mode & FMODE_WRITE))
  1578. lo_flags |= LO_FLAGS_READ_ONLY;
  1579. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  1580. + lo->lo_keyscrub_fn = 0;
  1581. +#endif
  1582. + lo->lo_offset = lo->lo_sizelimit = 0;
  1583. + lo->lo_offs_sec = lo->lo_iv_remove = 0;
  1584. + lo->lo_bh_free = lo->lo_bh_que2 = lo->lo_bh_que1 = lo->lo_bh_que0 = NULL;
  1585. + lo->lo_bh_need = lo->lo_bh_flsh = 0;
  1586. + init_waitqueue_head(&lo->lo_bh_wait);
  1587. if (S_ISBLK(inode->i_mode)) {
  1588. lo_device = inode->i_rdev;
  1589. if (lo_device == dev) {
  1590. error = -EBUSY;
  1591. goto out_putf;
  1592. }
  1593. + if (loop_prealloc_init(lo, 0)) {
  1594. + error = -ENOMEM;
  1595. + goto out_putf;
  1596. + }
  1597. + hardsz = get_hardsect_size(lo_device);
  1598. } else if (S_ISREG(inode->i_mode)) {
  1599. - struct address_space_operations *aops = inode->i_mapping->a_ops;
  1600. /*
  1601. * If we can't read - sorry. If we only can't write - well,
  1602. * it's going to be read-only.
  1603. */
  1604. - if (!aops->readpage)
  1605. + if (!file->f_op || !file->f_op->read)
  1606. goto out_putf;
  1607. - if (!aops->prepare_write || !aops->commit_write)
  1608. + if (!file->f_op->write)
  1609. lo_flags |= LO_FLAGS_READ_ONLY;
  1610. lo_device = inode->i_dev;
  1611. lo_flags |= LO_FLAGS_DO_BMAP;
  1612. + if (loop_prealloc_init(lo, 1)) {
  1613. + error = -ENOMEM;
  1614. + goto out_putf;
  1615. + }
  1616. error = 0;
  1617. } else
  1618. goto out_putf;
  1619. get_file(file);
  1620. - if (IS_RDONLY (inode) || is_read_only(lo_device)
  1621. + if ((S_ISREG(inode->i_mode) && IS_RDONLY(inode)) || is_read_only(lo_device)
  1622. || !(lo_file->f_mode & FMODE_WRITE))
  1623. lo_flags |= LO_FLAGS_READ_ONLY;
  1624. @@ -677,28 +1406,40 @@ static int loop_set_fd(struct loop_devic
  1625. lo->lo_device = lo_device;
  1626. lo->lo_flags = lo_flags;
  1627. + if(lo_flags & LO_FLAGS_READ_ONLY)
  1628. + lo->lo_flags |= 0x200000; /* export to user space */
  1629. lo->lo_backing_file = file;
  1630. lo->transfer = NULL;
  1631. lo->ioctl = NULL;
  1632. - figure_loop_size(lo);
  1633. - lo->old_gfp_mask = inode->i_mapping->gfp_mask;
  1634. - inode->i_mapping->gfp_mask &= ~(__GFP_IO|__GFP_FS);
  1635. -
  1636. - bs = 0;
  1637. - if (blksize_size[MAJOR(lo_device)])
  1638. - bs = blksize_size[MAJOR(lo_device)][MINOR(lo_device)];
  1639. - if (!bs)
  1640. - bs = BLOCK_SIZE;
  1641. + if (figure_loop_size(lo)) {
  1642. + error = -EFBIG;
  1643. + goto out_cleanup;
  1644. + }
  1645. - set_blocksize(dev, bs);
  1646. + if (lo_flags & LO_FLAGS_DO_BMAP) {
  1647. + lo->old_gfp_mask = inode->i_mapping->gfp_mask;
  1648. + inode->i_mapping->gfp_mask &= ~(__GFP_IO|__GFP_FS);
  1649. + inode->i_mapping->gfp_mask |= __GFP_HIGH;
  1650. + } else {
  1651. + lo->old_gfp_mask = -1;
  1652. + }
  1653. - lo->lo_bh = lo->lo_bhtail = NULL;
  1654. - kernel_thread(loop_thread, lo, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
  1655. - down(&lo->lo_sem);
  1656. + loop_hardsizes[MINOR(dev)] = hardsz;
  1657. + loop_set_softblksz(lo, dev);
  1658. + error = kernel_thread(loop_thread, lo, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
  1659. + if(error < 0)
  1660. + goto out_mapping;
  1661. + down(&lo->lo_sem);
  1662. fput(file);
  1663. return 0;
  1664. + out_mapping:
  1665. + if(lo->old_gfp_mask != -1)
  1666. + inode->i_mapping->gfp_mask = lo->old_gfp_mask;
  1667. + out_cleanup:
  1668. + loop_prealloc_cleanup(lo);
  1669. + fput(file);
  1670. out_putf:
  1671. fput(file);
  1672. out:
  1673. @@ -708,13 +1449,14 @@ static int loop_set_fd(struct loop_devic
  1674. static int loop_release_xfer(struct loop_device *lo)
  1675. {
  1676. - int err = 0;
  1677. + int err = 0;
  1678. if (lo->lo_encrypt_type) {
  1679. - struct loop_func_table *xfer= xfer_funcs[lo->lo_encrypt_type];
  1680. + struct loop_func_table *xfer= xfer_funcs[lo->lo_encrypt_type];
  1681. + lo->transfer = NULL;
  1682. if (xfer && xfer->release)
  1683. - err = xfer->release(lo);
  1684. + err = xfer->release(lo);
  1685. if (xfer && xfer->unlock)
  1686. - xfer->unlock(lo);
  1687. + xfer->unlock(lo);
  1688. lo->lo_encrypt_type = 0;
  1689. }
  1690. return err;
  1691. @@ -722,19 +1464,19 @@ static int loop_release_xfer(struct loop
  1692. static int loop_init_xfer(struct loop_device *lo, int type,struct loop_info *i)
  1693. {
  1694. - int err = 0;
  1695. + int err = 0;
  1696. if (type) {
  1697. - struct loop_func_table *xfer = xfer_funcs[type];
  1698. + struct loop_func_table *xfer = xfer_funcs[type];
  1699. if (xfer->init)
  1700. err = xfer->init(lo, i);
  1701. - if (!err) {
  1702. + if (!err) {
  1703. lo->lo_encrypt_type = type;
  1704. if (xfer->lock)
  1705. xfer->lock(lo);
  1706. }
  1707. }
  1708. return err;
  1709. -}
  1710. +}
  1711. static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
  1712. {
  1713. @@ -751,11 +1493,12 @@ static int loop_clr_fd(struct loop_devic
  1714. spin_lock_irq(&lo->lo_lock);
  1715. lo->lo_state = Lo_rundown;
  1716. if (atomic_dec_and_test(&lo->lo_pending))
  1717. - up(&lo->lo_bh_mutex);
  1718. + wake_up_interruptible(&lo->lo_bh_wait);
  1719. spin_unlock_irq(&lo->lo_lock);
  1720. down(&lo->lo_sem);
  1721. + loop_prealloc_cleanup(lo);
  1722. lo->lo_backing_file = NULL;
  1723. loop_release_xfer(lo);
  1724. @@ -763,87 +1506,219 @@ static int loop_clr_fd(struct loop_devic
  1725. lo->ioctl = NULL;
  1726. lo->lo_device = 0;
  1727. lo->lo_encrypt_type = 0;
  1728. - lo->lo_offset = 0;
  1729. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  1730. + lo->lo_keyscrub_fn = 0;
  1731. +#endif
  1732. + lo->lo_offset = lo->lo_sizelimit = 0;
  1733. + lo->lo_offs_sec = lo->lo_iv_remove = 0;
  1734. lo->lo_encrypt_key_size = 0;
  1735. lo->lo_flags = 0;
  1736. memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
  1737. memset(lo->lo_name, 0, LO_NAME_SIZE);
  1738. + memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
  1739. loop_sizes[lo->lo_number] = 0;
  1740. invalidate_bdev(bdev, 0);
  1741. - filp->f_dentry->d_inode->i_mapping->gfp_mask = gfp;
  1742. + if (gfp != -1)
  1743. + filp->f_dentry->d_inode->i_mapping->gfp_mask = gfp;
  1744. lo->lo_state = Lo_unbound;
  1745. fput(filp);
  1746. MOD_DEC_USE_COUNT;
  1747. return 0;
  1748. }
  1749. -static int loop_set_status(struct loop_device *lo, struct loop_info *arg)
  1750. +static void
  1751. +loop_info64_from_old(const struct loop_info *info, struct loop_info64 *info64)
  1752. +{
  1753. + memset(info64, 0, sizeof(*info64));
  1754. + info64->lo_number = info->lo_number;
  1755. + info64->lo_device = info->lo_device;
  1756. + info64->lo_inode = info->lo_inode;
  1757. + info64->lo_rdevice = info->lo_rdevice;
  1758. + info64->lo_offset = info->lo_offset;
  1759. + info64->lo_encrypt_type = info->lo_encrypt_type;
  1760. + info64->lo_encrypt_key_size = info->lo_encrypt_key_size;
  1761. + info64->lo_flags = info->lo_flags;
  1762. + info64->lo_init[0] = info->lo_init[0];
  1763. + info64->lo_init[1] = info->lo_init[1];
  1764. + if (info->lo_encrypt_type == 18) /* LO_CRYPT_CRYPTOAPI */
  1765. + memcpy(info64->lo_crypt_name, info->lo_name, LO_NAME_SIZE);
  1766. + else
  1767. + memcpy(info64->lo_file_name, info->lo_name, LO_NAME_SIZE);
  1768. + memcpy(info64->lo_encrypt_key, info->lo_encrypt_key, LO_KEY_SIZE);
  1769. +}
  1770. +
  1771. +static int
  1772. +loop_info64_to_old(struct loop_info64 *info64, struct loop_info *info)
  1773. +{
  1774. + memset(info, 0, sizeof(*info));
  1775. + info->lo_number = info64->lo_number;
  1776. + info->lo_device = info64->lo_device;
  1777. + info->lo_inode = info64->lo_inode;
  1778. + info->lo_rdevice = info64->lo_rdevice;
  1779. + info->lo_offset = info64->lo_offset;
  1780. + info->lo_encrypt_type = info64->lo_encrypt_type;
  1781. + info->lo_encrypt_key_size = info64->lo_encrypt_key_size;
  1782. + info->lo_flags = info64->lo_flags;
  1783. + info->lo_init[0] = info64->lo_init[0];
  1784. + info->lo_init[1] = info64->lo_init[1];
  1785. + if (info->lo_encrypt_type == 18) /* LO_CRYPT_CRYPTOAPI */
  1786. + memcpy(info->lo_name, info64->lo_crypt_name, LO_NAME_SIZE);
  1787. + else
  1788. + memcpy(info->lo_name, info64->lo_file_name, LO_NAME_SIZE);
  1789. + memcpy(info->lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE);
  1790. +
  1791. + /* error in case values were truncated */
  1792. + if (info->lo_device != info64->lo_device ||
  1793. + info->lo_rdevice != info64->lo_rdevice ||
  1794. + info->lo_inode != info64->lo_inode ||
  1795. + info->lo_offset != info64->lo_offset ||
  1796. + info64->lo_sizelimit)
  1797. + return -EOVERFLOW;
  1798. +
  1799. + return 0;
  1800. +}
  1801. +
  1802. +static int loop_set_status(struct loop_device *lo, kdev_t dev, struct loop_info64 *info, struct loop_info *oldinfo)
  1803. {
  1804. - struct loop_info info;
  1805. int err;
  1806. unsigned int type;
  1807. - if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
  1808. + if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
  1809. !capable(CAP_SYS_ADMIN))
  1810. return -EPERM;
  1811. if (lo->lo_state != Lo_bound)
  1812. return -ENXIO;
  1813. - if (copy_from_user(&info, arg, sizeof (struct loop_info)))
  1814. - return -EFAULT;
  1815. - if ((unsigned int) info.lo_encrypt_key_size > LO_KEY_SIZE)
  1816. + if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
  1817. return -EINVAL;
  1818. - type = info.lo_encrypt_type;
  1819. + type = info->lo_encrypt_type;
  1820. if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL)
  1821. return -EINVAL;
  1822. - if (type == LO_CRYPT_XOR && info.lo_encrypt_key_size == 0)
  1823. + if (type == LO_CRYPT_XOR && info->lo_encrypt_key_size == 0)
  1824. return -EINVAL;
  1825. err = loop_release_xfer(lo);
  1826. - if (!err)
  1827. - err = loop_init_xfer(lo, type, &info);
  1828. if (err)
  1829. return err;
  1830. - lo->lo_offset = info.lo_offset;
  1831. - strncpy(lo->lo_name, info.lo_name, LO_NAME_SIZE);
  1832. + if ((loff_t)info->lo_offset < 0) {
  1833. + /* negative offset == remove offset from IV computations */
  1834. + lo->lo_offset = -(info->lo_offset);
  1835. + lo->lo_iv_remove = lo->lo_offset >> 9;
  1836. + } else {
  1837. + /* positive offset == include offset in IV computations */
  1838. + lo->lo_offset = info->lo_offset;
  1839. + lo->lo_iv_remove = 0;
  1840. + }
  1841. + lo->lo_offs_sec = lo->lo_offset >> 9;
  1842. + lo->lo_sizelimit = info->lo_sizelimit;
  1843. + err = figure_loop_size(lo);
  1844. + if (err)
  1845. + return err;
  1846. + loop_set_softblksz(lo, dev);
  1847. +
  1848. + /* transfer init function for 2.4 kernels takes old style struct */
  1849. + err = loop_init_xfer(lo, type, oldinfo);
  1850. + /* copy key -- just in case transfer init func modified it */
  1851. + memcpy(info->lo_encrypt_key, oldinfo->lo_encrypt_key, sizeof(info->lo_encrypt_key));
  1852. + if (err)
  1853. + return err;
  1854. + strncpy(lo->lo_name, info->lo_file_name, LO_NAME_SIZE);
  1855. + strncpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE);
  1856. lo->transfer = xfer_funcs[type]->transfer;
  1857. lo->ioctl = xfer_funcs[type]->ioctl;
  1858. - lo->lo_encrypt_key_size = info.lo_encrypt_key_size;
  1859. - lo->lo_init[0] = info.lo_init[0];
  1860. - lo->lo_init[1] = info.lo_init[1];
  1861. - if (info.lo_encrypt_key_size) {
  1862. - memcpy(lo->lo_encrypt_key, info.lo_encrypt_key,
  1863. - info.lo_encrypt_key_size);
  1864. - lo->lo_key_owner = current->uid;
  1865. - }
  1866. - figure_loop_size(lo);
  1867. + lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
  1868. + lo->lo_init[0] = info->lo_init[0];
  1869. + lo->lo_init[1] = info->lo_init[1];
  1870. + if (info->lo_encrypt_key_size) {
  1871. + memcpy(lo->lo_encrypt_key, info->lo_encrypt_key,
  1872. + info->lo_encrypt_key_size);
  1873. + lo->lo_key_owner = current->uid;
  1874. + }
  1875. +
  1876. return 0;
  1877. }
  1878. -static int loop_get_status(struct loop_device *lo, struct loop_info *arg)
  1879. +static int loop_get_status(struct loop_device *lo, struct loop_info64 *info)
  1880. {
  1881. - struct loop_info info;
  1882. struct file *file = lo->lo_backing_file;
  1883. if (lo->lo_state != Lo_bound)
  1884. return -ENXIO;
  1885. - if (!arg)
  1886. - return -EINVAL;
  1887. - memset(&info, 0, sizeof(info));
  1888. - info.lo_number = lo->lo_number;
  1889. - info.lo_device = kdev_t_to_nr(file->f_dentry->d_inode->i_dev);
  1890. - info.lo_inode = file->f_dentry->d_inode->i_ino;
  1891. - info.lo_rdevice = kdev_t_to_nr(lo->lo_device);
  1892. - info.lo_offset = lo->lo_offset;
  1893. - info.lo_flags = lo->lo_flags;
  1894. - strncpy(info.lo_name, lo->lo_name, LO_NAME_SIZE);
  1895. - info.lo_encrypt_type = lo->lo_encrypt_type;
  1896. + memset(info, 0, sizeof(*info));
  1897. + info->lo_number = lo->lo_number;
  1898. + info->lo_device = kdev_t_to_nr(file->f_dentry->d_inode->i_dev);
  1899. + info->lo_inode = file->f_dentry->d_inode->i_ino;
  1900. + info->lo_rdevice = kdev_t_to_nr(lo->lo_device);
  1901. + info->lo_offset = lo->lo_iv_remove ? -(lo->lo_offset) : lo->lo_offset;
  1902. + info->lo_sizelimit = lo->lo_sizelimit;
  1903. + info->lo_flags = lo->lo_flags;
  1904. + strncpy(info->lo_file_name, lo->lo_name, LO_NAME_SIZE);
  1905. + strncpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
  1906. + info->lo_encrypt_type = lo->lo_encrypt_type;
  1907. if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
  1908. - info.lo_encrypt_key_size = lo->lo_encrypt_key_size;
  1909. - memcpy(info.lo_encrypt_key, lo->lo_encrypt_key,
  1910. + info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
  1911. + memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
  1912. lo->lo_encrypt_key_size);
  1913. + info->lo_init[0] = lo->lo_init[0];
  1914. + info->lo_init[1] = lo->lo_init[1];
  1915. }
  1916. - return copy_to_user(arg, &info, sizeof(info)) ? -EFAULT : 0;
  1917. + return 0;
  1918. +}
  1919. +
  1920. +static int
  1921. +loop_set_status_n(struct loop_device *lo, kdev_t dev, void *arg, int n)
  1922. +{
  1923. + struct loop_info info;
  1924. + struct loop_info64 info64;
  1925. + int err;
  1926. +
  1927. + if (n) {
  1928. + if (copy_from_user(&info64, arg, sizeof (struct loop_info64)))
  1929. + return -EFAULT;
  1930. + /* truncation errors can be ignored here as transfer init func only wants key bits */
  1931. + loop_info64_to_old(&info64, &info);
  1932. + } else {
  1933. + if (copy_from_user(&info, arg, sizeof (struct loop_info)))
  1934. + return -EFAULT;
  1935. + loop_info64_from_old(&info, &info64);
  1936. + }
  1937. + err = loop_set_status(lo, dev, &info64, &info);
  1938. + memset(&info.lo_encrypt_key[0], 0, sizeof(info.lo_encrypt_key));
  1939. + memset(&info64.lo_encrypt_key[0], 0, sizeof(info64.lo_encrypt_key));
  1940. + return err;
  1941. +}
  1942. +
  1943. +static int
  1944. +loop_get_status_old(struct loop_device *lo, struct loop_info *arg) {
  1945. + struct loop_info info;
  1946. + struct loop_info64 info64;
  1947. + int err = 0;
  1948. +
  1949. + if (!arg)
  1950. + err = -EINVAL;
  1951. + if (!err)
  1952. + err = loop_get_status(lo, &info64);
  1953. + if (!err)
  1954. + err = loop_info64_to_old(&info64, &info);
  1955. + if (!err && copy_to_user(arg, &info, sizeof(info)))
  1956. + err = -EFAULT;
  1957. +
  1958. + return err;
  1959. +}
  1960. +
  1961. +static int
  1962. +loop_get_status64(struct loop_device *lo, struct loop_info64 *arg) {
  1963. + struct loop_info64 info64;
  1964. + int err = 0;
  1965. +
  1966. + if (!arg)
  1967. + err = -EINVAL;
  1968. + if (!err)
  1969. + err = loop_get_status(lo, &info64);
  1970. + if (!err && copy_to_user(arg, &info64, sizeof(info64)))
  1971. + err = -EFAULT;
  1972. +
  1973. + return err;
  1974. }
  1975. static int lo_ioctl(struct inode * inode, struct file * file,
  1976. @@ -872,10 +1747,16 @@ static int lo_ioctl(struct inode * inode
  1977. err = loop_clr_fd(lo, inode->i_bdev);
  1978. break;
  1979. case LOOP_SET_STATUS:
  1980. - err = loop_set_status(lo, (struct loop_info *) arg);
  1981. + err = loop_set_status_n(lo, inode->i_rdev, (void *) arg, 0);
  1982. break;
  1983. case LOOP_GET_STATUS:
  1984. - err = loop_get_status(lo, (struct loop_info *) arg);
  1985. + err = loop_get_status_old(lo, (struct loop_info *) arg);
  1986. + break;
  1987. + case LOOP_SET_STATUS64:
  1988. + err = loop_set_status_n(lo, inode->i_rdev, (void *) arg, 1);
  1989. + break;
  1990. + case LOOP_GET_STATUS64:
  1991. + err = loop_get_status64(lo, (struct loop_info64 *) arg);
  1992. break;
  1993. case BLKGETSIZE:
  1994. if (lo->lo_state != Lo_bound) {
  1995. @@ -894,6 +1775,8 @@ static int lo_ioctl(struct inode * inode
  1996. case BLKBSZGET:
  1997. case BLKBSZSET:
  1998. case BLKSSZGET:
  1999. + case BLKROGET:
  2000. + case BLKROSET:
  2001. err = blk_ioctl(inode->i_rdev, cmd, arg);
  2002. break;
  2003. default:
  2004. @@ -906,7 +1789,7 @@ static int lo_ioctl(struct inode * inode
  2005. static int lo_open(struct inode *inode, struct file *file)
  2006. {
  2007. struct loop_device *lo;
  2008. - int dev, type;
  2009. + int dev;
  2010. if (!inode)
  2011. return -EINVAL;
  2012. @@ -921,10 +1804,6 @@ static int lo_open(struct inode *inode,
  2013. lo = &loop_dev[dev];
  2014. MOD_INC_USE_COUNT;
  2015. down(&lo->lo_ctl_mutex);
  2016. -
  2017. - type = lo->lo_encrypt_type;
  2018. - if (type && xfer_funcs[type] && xfer_funcs[type]->lock)
  2019. - xfer_funcs[type]->lock(lo);
  2020. lo->lo_refcnt++;
  2021. up(&lo->lo_ctl_mutex);
  2022. return 0;
  2023. @@ -933,7 +1812,7 @@ static int lo_open(struct inode *inode,
  2024. static int lo_release(struct inode *inode, struct file *file)
  2025. {
  2026. struct loop_device *lo;
  2027. - int dev, type;
  2028. + int dev;
  2029. if (!inode)
  2030. return 0;
  2031. @@ -948,11 +1827,7 @@ static int lo_release(struct inode *inod
  2032. lo = &loop_dev[dev];
  2033. down(&lo->lo_ctl_mutex);
  2034. - type = lo->lo_encrypt_type;
  2035. --lo->lo_refcnt;
  2036. - if (xfer_funcs[type] && xfer_funcs[type]->unlock)
  2037. - xfer_funcs[type]->unlock(lo);
  2038. -
  2039. up(&lo->lo_ctl_mutex);
  2040. MOD_DEC_USE_COUNT;
  2041. return 0;
  2042. @@ -974,34 +1849,32 @@ MODULE_LICENSE("GPL");
  2043. int loop_register_transfer(struct loop_func_table *funcs)
  2044. {
  2045. - if ((unsigned)funcs->number > MAX_LO_CRYPT || xfer_funcs[funcs->number])
  2046. + if ((unsigned)funcs->number >= MAX_LO_CRYPT || xfer_funcs[funcs->number])
  2047. return -EINVAL;
  2048. xfer_funcs[funcs->number] = funcs;
  2049. - return 0;
  2050. + return 0;
  2051. }
  2052. int loop_unregister_transfer(int number)
  2053. {
  2054. - struct loop_device *lo;
  2055. + struct loop_device *lo;
  2056. if ((unsigned)number >= MAX_LO_CRYPT)
  2057. - return -EINVAL;
  2058. - for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
  2059. + return -EINVAL;
  2060. + for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
  2061. int type = lo->lo_encrypt_type;
  2062. - if (type == number) {
  2063. - xfer_funcs[type]->release(lo);
  2064. - lo->transfer = NULL;
  2065. - lo->lo_encrypt_type = 0;
  2066. + if (type == number) {
  2067. + loop_release_xfer(lo);
  2068. }
  2069. }
  2070. - xfer_funcs[number] = NULL;
  2071. - return 0;
  2072. + xfer_funcs[number] = NULL;
  2073. + return 0;
  2074. }
  2075. EXPORT_SYMBOL(loop_register_transfer);
  2076. EXPORT_SYMBOL(loop_unregister_transfer);
  2077. -int __init loop_init(void)
  2078. +int __init loop_init(void)
  2079. {
  2080. int i;
  2081. @@ -1017,10 +1890,9 @@ int __init loop_init(void)
  2082. return -EIO;
  2083. }
  2084. -
  2085. loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL);
  2086. if (!loop_dev)
  2087. - return -ENOMEM;
  2088. + goto out_dev;
  2089. loop_sizes = kmalloc(max_loop * sizeof(int), GFP_KERNEL);
  2090. if (!loop_sizes)
  2091. @@ -1030,6 +1902,10 @@ int __init loop_init(void)
  2092. if (!loop_blksizes)
  2093. goto out_blksizes;
  2094. + loop_hardsizes = kmalloc(max_loop * sizeof(int), GFP_KERNEL);
  2095. + if (!loop_hardsizes)
  2096. + goto out_hardsizes;
  2097. +
  2098. blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), loop_make_request);
  2099. for (i = 0; i < max_loop; i++) {
  2100. @@ -1037,45 +1913,84 @@ int __init loop_init(void)
  2101. memset(lo, 0, sizeof(struct loop_device));
  2102. init_MUTEX(&lo->lo_ctl_mutex);
  2103. init_MUTEX_LOCKED(&lo->lo_sem);
  2104. - init_MUTEX_LOCKED(&lo->lo_bh_mutex);
  2105. lo->lo_number = i;
  2106. spin_lock_init(&lo->lo_lock);
  2107. }
  2108. memset(loop_sizes, 0, max_loop * sizeof(int));
  2109. memset(loop_blksizes, 0, max_loop * sizeof(int));
  2110. + memset(loop_hardsizes, 0, max_loop * sizeof(int));
  2111. blk_size[MAJOR_NR] = loop_sizes;
  2112. blksize_size[MAJOR_NR] = loop_blksizes;
  2113. + hardsect_size[MAJOR_NR] = loop_hardsizes;
  2114. for (i = 0; i < max_loop; i++)
  2115. register_disk(NULL, MKDEV(MAJOR_NR, i), 1, &lo_fops, 0);
  2116. + for (i = 0; i < (sizeof(lo_prealloc) / sizeof(int)); i += 2) {
  2117. + if (!lo_prealloc[i])
  2118. + continue;
  2119. + if (lo_prealloc[i] < LO_PREALLOC_MIN)
  2120. + lo_prealloc[i] = LO_PREALLOC_MIN;
  2121. + if (lo_prealloc[i] > LO_PREALLOC_MAX)
  2122. + lo_prealloc[i] = LO_PREALLOC_MAX;
  2123. + }
  2124. +
  2125. +#if defined(IOCTL32_COMPATIBLE_PTR)
  2126. + lock_kernel();
  2127. + register_ioctl32_conversion(LOOP_SET_STATUS64, IOCTL32_COMPATIBLE_PTR);
  2128. + register_ioctl32_conversion(LOOP_GET_STATUS64, IOCTL32_COMPATIBLE_PTR);
  2129. + register_ioctl32_conversion(LOOP_MULTI_KEY_SETUP, IOCTL32_COMPATIBLE_PTR);
  2130. + unlock_kernel();
  2131. +#endif
  2132. +
  2133. devfs_handle = devfs_mk_dir(NULL, "loop", NULL);
  2134. devfs_register_series(devfs_handle, "%u", max_loop, DEVFS_FL_DEFAULT,
  2135. MAJOR_NR, 0,
  2136. S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
  2137. &lo_fops, NULL);
  2138. +#if CONFIG_BLK_DEV_LOOP_AES
  2139. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  2140. + printk(KERN_INFO "loop: AES key scrubbing enabled\n");
  2141. +#endif
  2142. +#endif
  2143. printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop);
  2144. return 0;
  2145. +out_hardsizes:
  2146. + kfree(loop_blksizes);
  2147. out_blksizes:
  2148. kfree(loop_sizes);
  2149. out_sizes:
  2150. kfree(loop_dev);
  2151. +out_dev:
  2152. if (devfs_unregister_blkdev(MAJOR_NR, "loop"))
  2153. printk(KERN_WARNING "loop: cannot unregister blkdev\n");
  2154. printk(KERN_ERR "loop: ran out of memory\n");
  2155. return -ENOMEM;
  2156. }
  2157. -void loop_exit(void)
  2158. +void loop_exit(void)
  2159. {
  2160. devfs_unregister(devfs_handle);
  2161. if (devfs_unregister_blkdev(MAJOR_NR, "loop"))
  2162. printk(KERN_WARNING "loop: cannot unregister blkdev\n");
  2163. +
  2164. + blk_size[MAJOR_NR] = 0;
  2165. + blksize_size[MAJOR_NR] = 0;
  2166. + hardsect_size[MAJOR_NR] = 0;
  2167. kfree(loop_dev);
  2168. kfree(loop_sizes);
  2169. kfree(loop_blksizes);
  2170. + kfree(loop_hardsizes);
  2171. +
  2172. +#if defined(IOCTL32_COMPATIBLE_PTR)
  2173. + lock_kernel();
  2174. + unregister_ioctl32_conversion(LOOP_SET_STATUS64);
  2175. + unregister_ioctl32_conversion(LOOP_GET_STATUS64);
  2176. + unregister_ioctl32_conversion(LOOP_MULTI_KEY_SETUP);
  2177. + unlock_kernel();
  2178. +#endif
  2179. }
  2180. module_init(loop_init);
  2181. @@ -1090,3 +2005,14 @@ static int __init max_loop_setup(char *s
  2182. __setup("max_loop=", max_loop_setup);
  2183. #endif
  2184. +
  2185. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  2186. +void loop_add_keyscrub_fn(struct loop_device *lo, void (*fn)(void *), void *ptr)
  2187. +{
  2188. + lo->lo_keyscrub_ptr = ptr;
  2189. + wmb();
  2190. + lo->lo_keyscrub_fn = fn;
  2191. + wake_up_interruptible(&lo->lo_bh_wait);
  2192. +}
  2193. +EXPORT_SYMBOL(loop_add_keyscrub_fn);
  2194. +#endif
  2195. diff -pruN linux-2.4.27_orig/drivers/misc/Makefile linux-2.4.27/drivers/misc/Makefile
  2196. --- linux-2.4.27_orig/drivers/misc/Makefile 2000-12-29 23:07:22.000000000 +0100
  2197. +++ linux-2.4.27/drivers/misc/Makefile 2004-10-25 14:20:44.716004624 +0200
  2198. @@ -9,8 +9,35 @@
  2199. # parent makes..
  2200. #
  2201. +.S.o:
  2202. + $(CC) $(AFLAGS) $(AFLAGS_$@) -c $< -o $*.o
  2203. +
  2204. O_TARGET := misc.o
  2205. +ifeq ($(CONFIG_BLK_DEV_LOOP_AES),y)
  2206. +AES_X86_ASM=n
  2207. +ifeq ($(CONFIG_X86),y)
  2208. +ifneq ($(CONFIG_X86_64),y)
  2209. + AES_X86_ASM=y
  2210. +endif
  2211. +endif
  2212. +ifeq ($(AES_X86_ASM),y)
  2213. + export-objs += crypto-ksym.o
  2214. + obj-y += aes-x86.o md5-x86.o crypto-ksym.o
  2215. + AFLAGS_aes-x86.o := -DUSE_UNDERLINE=1
  2216. +else
  2217. +ifeq ($(CONFIG_X86_64),y)
  2218. + export-objs += crypto-ksym.o
  2219. + obj-y += aes-amd64.o md5-amd64.o crypto-ksym.o
  2220. + AFLAGS_aes-amd64.o := -DUSE_UNDERLINE=1
  2221. +else
  2222. + export-objs += crypto-ksym.o
  2223. + obj-y += aes.o md5.o crypto-ksym.o
  2224. + CFLAGS_aes.o := -DDATA_ALWAYS_ALIGNED=1
  2225. +endif
  2226. +endif
  2227. +endif
  2228. +
  2229. include $(TOPDIR)/Rules.make
  2230. fastdep:
  2231. diff -pruN linux-2.4.27_orig/drivers/misc/aes-amd64.S linux-2.4.27/drivers/misc/aes-amd64.S
  2232. --- linux-2.4.27_orig/drivers/misc/aes-amd64.S 1970-01-01 01:00:00.000000000 +0100
  2233. +++ linux-2.4.27/drivers/misc/aes-amd64.S 2004-10-25 14:20:44.718004320 +0200
  2234. @@ -0,0 +1,893 @@
  2235. +//
  2236. +// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
  2237. +// All rights reserved.
  2238. +//
  2239. +// TERMS
  2240. +//
  2241. +// Redistribution and use in source and binary forms, with or without
  2242. +// modification, are permitted subject to the following conditions:
  2243. +//
  2244. +// 1. Redistributions of source code must retain the above copyright
  2245. +// notice, this list of conditions and the following disclaimer.
  2246. +//
  2247. +// 2. Redistributions in binary form must reproduce the above copyright
  2248. +// notice, this list of conditions and the following disclaimer in the
  2249. +// documentation and/or other materials provided with the distribution.
  2250. +//
  2251. +// 3. The copyright holder's name must not be used to endorse or promote
  2252. +// any products derived from this software without his specific prior
  2253. +// written permission.
  2254. +//
  2255. +// This software is provided 'as is' with no express or implied warranties
  2256. +// of correctness or fitness for purpose.
  2257. +
  2258. +// Modified by Jari Ruusu, December 24 2001
  2259. +// - Converted syntax to GNU CPP/assembler syntax
  2260. +// - C programming interface converted back to "old" API
  2261. +// - Minor portability cleanups and speed optimizations
  2262. +
  2263. +// Modified by Jari Ruusu, April 11 2002
  2264. +// - Added above copyright and terms to resulting object code so that
  2265. +// binary distributions can avoid legal trouble
  2266. +
  2267. +// Modified by Jari Ruusu, June 12 2004
  2268. +// - Converted 32 bit x86 code to 64 bit AMD64 code
  2269. +// - Re-wrote encrypt and decrypt code from scratch
  2270. +
  2271. +// An AES (Rijndael) implementation for the AMD64. This version only
  2272. +// implements the standard AES block length (128 bits, 16 bytes). This code
  2273. +// does not preserve the rax, rcx, rdx, rsi, rdi or r8-r11 registers or the
  2274. +// artihmetic status flags. However, the rbx, rbp and r12-r15 registers are
  2275. +// preserved across calls.
  2276. +
  2277. +// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f)
  2278. +// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
  2279. +// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
  2280. +
  2281. +#if defined(USE_UNDERLINE)
  2282. +# define aes_set_key _aes_set_key
  2283. +# define aes_encrypt _aes_encrypt
  2284. +# define aes_decrypt _aes_decrypt
  2285. +#endif
  2286. +#if !defined(ALIGN64BYTES)
  2287. +# define ALIGN64BYTES 64
  2288. +#endif
  2289. +
  2290. + .file "aes-amd64.S"
  2291. + .globl aes_set_key
  2292. + .globl aes_encrypt
  2293. + .globl aes_decrypt
  2294. +
  2295. + .section .rodata
  2296. +copyright:
  2297. + .ascii " \000"
  2298. + .ascii "Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.\000"
  2299. + .ascii "All rights reserved.\000"
  2300. + .ascii " \000"
  2301. + .ascii "TERMS\000"
  2302. + .ascii " \000"
  2303. + .ascii " Redistribution and use in source and binary forms, with or without\000"
  2304. + .ascii " modification, are permitted subject to the following conditions:\000"
  2305. + .ascii " \000"
  2306. + .ascii " 1. Redistributions of source code must retain the above copyright\000"
  2307. + .ascii " notice, this list of conditions and the following disclaimer.\000"
  2308. + .ascii " \000"
  2309. + .ascii " 2. Redistributions in binary form must reproduce the above copyright\000"
  2310. + .ascii " notice, this list of conditions and the following disclaimer in the\000"
  2311. + .ascii " documentation and/or other materials provided with the distribution.\000"
  2312. + .ascii " \000"
  2313. + .ascii " 3. The copyright holder's name must not be used to endorse or promote\000"
  2314. + .ascii " any products derived from this software without his specific prior\000"
  2315. + .ascii " written permission.\000"
  2316. + .ascii " \000"
  2317. + .ascii " This software is provided 'as is' with no express or implied warranties\000"
  2318. + .ascii " of correctness or fitness for purpose.\000"
  2319. + .ascii " \000"
  2320. +
  2321. +#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
  2322. +
  2323. +// offsets in context structure
  2324. +
  2325. +#define nkey 0 // key length, size 4
  2326. +#define nrnd 4 // number of rounds, size 4
  2327. +#define ekey 8 // encryption key schedule base address, size 256
  2328. +#define dkey 264 // decryption key schedule base address, size 256
  2329. +
  2330. +// This macro performs a forward encryption cycle. It is entered with
  2331. +// the first previous round column values in I1E, I2E, I3E and I4E and
  2332. +// exits with the final values OU1, OU2, OU3 and OU4 registers.
  2333. +
  2334. +#define fwd_rnd(p1,p2,I1E,I1B,I1H,I2E,I2B,I2H,I3E,I3B,I3R,I4E,I4B,I4R,OU1,OU2,OU3,OU4) \
  2335. + movl p2(%rbp),OU1 ;\
  2336. + movl p2+4(%rbp),OU2 ;\
  2337. + movl p2+8(%rbp),OU3 ;\
  2338. + movl p2+12(%rbp),OU4 ;\
  2339. + movzbl I1B,%edi ;\
  2340. + movzbl I2B,%esi ;\
  2341. + movzbl I3B,%r8d ;\
  2342. + movzbl I4B,%r13d ;\
  2343. + shrl $8,I3E ;\
  2344. + shrl $8,I4E ;\
  2345. + xorl p1(,%rdi,4),OU1 ;\
  2346. + xorl p1(,%rsi,4),OU2 ;\
  2347. + xorl p1(,%r8,4),OU3 ;\
  2348. + xorl p1(,%r13,4),OU4 ;\
  2349. + movzbl I2H,%esi ;\
  2350. + movzbl I3B,%r8d ;\
  2351. + movzbl I4B,%r13d ;\
  2352. + movzbl I1H,%edi ;\
  2353. + shrl $8,I3E ;\
  2354. + shrl $8,I4E ;\
  2355. + xorl p1+tlen(,%rsi,4),OU1 ;\
  2356. + xorl p1+tlen(,%r8,4),OU2 ;\
  2357. + xorl p1+tlen(,%r13,4),OU3 ;\
  2358. + xorl p1+tlen(,%rdi,4),OU4 ;\
  2359. + shrl $16,I1E ;\
  2360. + shrl $16,I2E ;\
  2361. + movzbl I3B,%r8d ;\
  2362. + movzbl I4B,%r13d ;\
  2363. + movzbl I1B,%edi ;\
  2364. + movzbl I2B,%esi ;\
  2365. + xorl p1+2*tlen(,%r8,4),OU1 ;\
  2366. + xorl p1+2*tlen(,%r13,4),OU2 ;\
  2367. + xorl p1+2*tlen(,%rdi,4),OU3 ;\
  2368. + xorl p1+2*tlen(,%rsi,4),OU4 ;\
  2369. + shrl $8,I4E ;\
  2370. + movzbl I1H,%edi ;\
  2371. + movzbl I2H,%esi ;\
  2372. + shrl $8,I3E ;\
  2373. + xorl p1+3*tlen(,I4R,4),OU1 ;\
  2374. + xorl p1+3*tlen(,%rdi,4),OU2 ;\
  2375. + xorl p1+3*tlen(,%rsi,4),OU3 ;\
  2376. + xorl p1+3*tlen(,I3R,4),OU4
  2377. +
  2378. +// This macro performs an inverse encryption cycle. It is entered with
  2379. +// the first previous round column values in I1E, I2E, I3E and I4E and
  2380. +// exits with the final values OU1, OU2, OU3 and OU4 registers.
  2381. +
  2382. +#define inv_rnd(p1,p2,I1E,I1B,I1R,I2E,I2B,I2R,I3E,I3B,I3H,I4E,I4B,I4H,OU1,OU2,OU3,OU4) \
  2383. + movl p2+12(%rbp),OU4 ;\
  2384. + movl p2+8(%rbp),OU3 ;\
  2385. + movl p2+4(%rbp),OU2 ;\
  2386. + movl p2(%rbp),OU1 ;\
  2387. + movzbl I4B,%edi ;\
  2388. + movzbl I3B,%esi ;\
  2389. + movzbl I2B,%r8d ;\
  2390. + movzbl I1B,%r13d ;\
  2391. + shrl $8,I2E ;\
  2392. + shrl $8,I1E ;\
  2393. + xorl p1(,%rdi,4),OU4 ;\
  2394. + xorl p1(,%rsi,4),OU3 ;\
  2395. + xorl p1(,%r8,4),OU2 ;\
  2396. + xorl p1(,%r13,4),OU1 ;\
  2397. + movzbl I3H,%esi ;\
  2398. + movzbl I2B,%r8d ;\
  2399. + movzbl I1B,%r13d ;\
  2400. + movzbl I4H,%edi ;\
  2401. + shrl $8,I2E ;\
  2402. + shrl $8,I1E ;\
  2403. + xorl p1+tlen(,%rsi,4),OU4 ;\
  2404. + xorl p1+tlen(,%r8,4),OU3 ;\
  2405. + xorl p1+tlen(,%r13,4),OU2 ;\
  2406. + xorl p1+tlen(,%rdi,4),OU1 ;\
  2407. + shrl $16,I4E ;\
  2408. + shrl $16,I3E ;\
  2409. + movzbl I2B,%r8d ;\
  2410. + movzbl I1B,%r13d ;\
  2411. + movzbl I4B,%edi ;\
  2412. + movzbl I3B,%esi ;\
  2413. + xorl p1+2*tlen(,%r8,4),OU4 ;\
  2414. + xorl p1+2*tlen(,%r13,4),OU3 ;\
  2415. + xorl p1+2*tlen(,%rdi,4),OU2 ;\
  2416. + xorl p1+2*tlen(,%rsi,4),OU1 ;\
  2417. + shrl $8,I1E ;\
  2418. + movzbl I4H,%edi ;\
  2419. + movzbl I3H,%esi ;\
  2420. + shrl $8,I2E ;\
  2421. + xorl p1+3*tlen(,I1R,4),OU4 ;\
  2422. + xorl p1+3*tlen(,%rdi,4),OU3 ;\
  2423. + xorl p1+3*tlen(,%rsi,4),OU2 ;\
  2424. + xorl p1+3*tlen(,I2R,4),OU1
  2425. +
  2426. +// AES (Rijndael) Encryption Subroutine
  2427. +
  2428. +// rdi = pointer to AES context
  2429. +// rsi = pointer to input plaintext bytes
  2430. +// rdx = pointer to output ciphertext bytes
  2431. +
  2432. + .text
  2433. + .align ALIGN64BYTES
  2434. +aes_encrypt:
  2435. + movl (%rsi),%eax // read in plaintext
  2436. + movl 4(%rsi),%ecx
  2437. + movl 8(%rsi),%r10d
  2438. + movl 12(%rsi),%r11d
  2439. +
  2440. + pushq %rbp
  2441. + leaq ekey+16(%rdi),%rbp // encryption key pointer
  2442. + movq %rdx,%r9 // pointer to out block
  2443. + movl nrnd(%rdi),%edx // number of rounds
  2444. + pushq %rbx
  2445. + pushq %r13
  2446. + pushq %r14
  2447. + pushq %r15
  2448. +
  2449. + xorl -16(%rbp),%eax // xor in first round key
  2450. + xorl -12(%rbp),%ecx
  2451. + xorl -8(%rbp),%r10d
  2452. + xorl -4(%rbp),%r11d
  2453. +
  2454. + subl $10,%edx
  2455. + je aes_15
  2456. + addq $32,%rbp
  2457. + subl $2,%edx
  2458. + je aes_13
  2459. + addq $32,%rbp
  2460. +
  2461. + fwd_rnd(aes_ft_tab,-64,%eax,%al,%ah,%ecx,%cl,%ch,%r10d,%r10b,%r10,%r11d,%r11b,%r11,%ebx,%edx,%r14d,%r15d)
  2462. + fwd_rnd(aes_ft_tab,-48,%ebx,%bl,%bh,%edx,%dl,%dh,%r14d,%r14b,%r14,%r15d,%r15b,%r15,%eax,%ecx,%r10d,%r11d)
  2463. + jmp aes_13
  2464. + .align ALIGN64BYTES
  2465. +aes_13: fwd_rnd(aes_ft_tab,-32,%eax,%al,%ah,%ecx,%cl,%ch,%r10d,%r10b,%r10,%r11d,%r11b,%r11,%ebx,%edx,%r14d,%r15d)
  2466. + fwd_rnd(aes_ft_tab,-16,%ebx,%bl,%bh,%edx,%dl,%dh,%r14d,%r14b,%r14,%r15d,%r15b,%r15,%eax,%ecx,%r10d,%r11d)
  2467. + jmp aes_15
  2468. + .align ALIGN64BYTES
  2469. +aes_15: fwd_rnd(aes_ft_tab,0, %eax,%al,%ah,%ecx,%cl,%ch,%r10d,%r10b,%r10,%r11d,%r11b,%r11,%ebx,%edx,%r14d,%r15d)
  2470. + fwd_rnd(aes_ft_tab,16, %ebx,%bl,%bh,%edx,%dl,%dh,%r14d,%r14b,%r14,%r15d,%r15b,%r15,%eax,%ecx,%r10d,%r11d)
  2471. + fwd_rnd(aes_ft_tab,32, %eax,%al,%ah,%ecx,%cl,%ch,%r10d,%r10b,%r10,%r11d,%r11b,%r11,%ebx,%edx,%r14d,%r15d)
  2472. + fwd_rnd(aes_ft_tab,48, %ebx,%bl,%bh,%edx,%dl,%dh,%r14d,%r14b,%r14,%r15d,%r15b,%r15,%eax,%ecx,%r10d,%r11d)
  2473. + fwd_rnd(aes_ft_tab,64, %eax,%al,%ah,%ecx,%cl,%ch,%r10d,%r10b,%r10,%r11d,%r11b,%r11,%ebx,%edx,%r14d,%r15d)
  2474. + fwd_rnd(aes_ft_tab,80, %ebx,%bl,%bh,%edx,%dl,%dh,%r14d,%r14b,%r14,%r15d,%r15b,%r15,%eax,%ecx,%r10d,%r11d)
  2475. + fwd_rnd(aes_ft_tab,96, %eax,%al,%ah,%ecx,%cl,%ch,%r10d,%r10b,%r10,%r11d,%r11b,%r11,%ebx,%edx,%r14d,%r15d)
  2476. + fwd_rnd(aes_ft_tab,112,%ebx,%bl,%bh,%edx,%dl,%dh,%r14d,%r14b,%r14,%r15d,%r15b,%r15,%eax,%ecx,%r10d,%r11d)
  2477. + fwd_rnd(aes_ft_tab,128,%eax,%al,%ah,%ecx,%cl,%ch,%r10d,%r10b,%r10,%r11d,%r11b,%r11,%ebx,%edx,%r14d,%r15d)
  2478. + fwd_rnd(aes_fl_tab,144,%ebx,%bl,%bh,%edx,%dl,%dh,%r14d,%r14b,%r14,%r15d,%r15b,%r15,%eax,%ecx,%r10d,%r11d)
  2479. +
  2480. + popq %r15
  2481. + popq %r14
  2482. + popq %r13
  2483. + popq %rbx
  2484. + popq %rbp
  2485. +
  2486. + movl %eax,(%r9) // move final values to the output array.
  2487. + movl %ecx,4(%r9)
  2488. + movl %r10d,8(%r9)
  2489. + movl %r11d,12(%r9)
  2490. + ret
  2491. +
  2492. +// AES (Rijndael) Decryption Subroutine
  2493. +
  2494. +// rdi = pointer to AES context
  2495. +// rsi = pointer to input ciphertext bytes
  2496. +// rdx = pointer to output plaintext bytes
  2497. +
  2498. + .align ALIGN64BYTES
  2499. +aes_decrypt:
  2500. + movl 12(%rsi),%eax // read in ciphertext
  2501. + movl 8(%rsi),%ecx
  2502. + movl 4(%rsi),%r10d
  2503. + movl (%rsi),%r11d
  2504. +
  2505. + pushq %rbp
  2506. + leaq dkey+16(%rdi),%rbp // decryption key pointer
  2507. + movq %rdx,%r9 // pointer to out block
  2508. + movl nrnd(%rdi),%edx // number of rounds
  2509. + pushq %rbx
  2510. + pushq %r13
  2511. + pushq %r14
  2512. + pushq %r15
  2513. +
  2514. + xorl -4(%rbp),%eax // xor in first round key
  2515. + xorl -8(%rbp),%ecx
  2516. + xorl -12(%rbp),%r10d
  2517. + xorl -16(%rbp),%r11d
  2518. +
  2519. + subl $10,%edx
  2520. + je aes_25
  2521. + addq $32,%rbp
  2522. + subl $2,%edx
  2523. + je aes_23
  2524. + addq $32,%rbp
  2525. +
  2526. + inv_rnd(aes_it_tab,-64,%r11d,%r11b,%r11,%r10d,%r10b,%r10,%ecx,%cl,%ch,%eax,%al,%ah,%r15d,%r14d,%edx,%ebx)
  2527. + inv_rnd(aes_it_tab,-48,%r15d,%r15b,%r15,%r14d,%r14b,%r14,%edx,%dl,%dh,%ebx,%bl,%bh,%r11d,%r10d,%ecx,%eax)
  2528. + jmp aes_23
  2529. + .align ALIGN64BYTES
  2530. +aes_23: inv_rnd(aes_it_tab,-32,%r11d,%r11b,%r11,%r10d,%r10b,%r10,%ecx,%cl,%ch,%eax,%al,%ah,%r15d,%r14d,%edx,%ebx)
  2531. + inv_rnd(aes_it_tab,-16,%r15d,%r15b,%r15,%r14d,%r14b,%r14,%edx,%dl,%dh,%ebx,%bl,%bh,%r11d,%r10d,%ecx,%eax)
  2532. + jmp aes_25
  2533. + .align ALIGN64BYTES
  2534. +aes_25: inv_rnd(aes_it_tab,0, %r11d,%r11b,%r11,%r10d,%r10b,%r10,%ecx,%cl,%ch,%eax,%al,%ah,%r15d,%r14d,%edx,%ebx)
  2535. + inv_rnd(aes_it_tab,16, %r15d,%r15b,%r15,%r14d,%r14b,%r14,%edx,%dl,%dh,%ebx,%bl,%bh,%r11d,%r10d,%ecx,%eax)
  2536. + inv_rnd(aes_it_tab,32, %r11d,%r11b,%r11,%r10d,%r10b,%r10,%ecx,%cl,%ch,%eax,%al,%ah,%r15d,%r14d,%edx,%ebx)
  2537. + inv_rnd(aes_it_tab,48, %r15d,%r15b,%r15,%r14d,%r14b,%r14,%edx,%dl,%dh,%ebx,%bl,%bh,%r11d,%r10d,%ecx,%eax)
  2538. + inv_rnd(aes_it_tab,64, %r11d,%r11b,%r11,%r10d,%r10b,%r10,%ecx,%cl,%ch,%eax,%al,%ah,%r15d,%r14d,%edx,%ebx)
  2539. + inv_rnd(aes_it_tab,80, %r15d,%r15b,%r15,%r14d,%r14b,%r14,%edx,%dl,%dh,%ebx,%bl,%bh,%r11d,%r10d,%ecx,%eax)
  2540. + inv_rnd(aes_it_tab,96, %r11d,%r11b,%r11,%r10d,%r10b,%r10,%ecx,%cl,%ch,%eax,%al,%ah,%r15d,%r14d,%edx,%ebx)
  2541. + inv_rnd(aes_it_tab,112,%r15d,%r15b,%r15,%r14d,%r14b,%r14,%edx,%dl,%dh,%ebx,%bl,%bh,%r11d,%r10d,%ecx,%eax)
  2542. + inv_rnd(aes_it_tab,128,%r11d,%r11b,%r11,%r10d,%r10b,%r10,%ecx,%cl,%ch,%eax,%al,%ah,%r15d,%r14d,%edx,%ebx)
  2543. + inv_rnd(aes_il_tab,144,%r15d,%r15b,%r15,%r14d,%r14b,%r14,%edx,%dl,%dh,%ebx,%bl,%bh,%r11d,%r10d,%ecx,%eax)
  2544. +
  2545. + popq %r15
  2546. + popq %r14
  2547. + popq %r13
  2548. + popq %rbx
  2549. + popq %rbp
  2550. +
  2551. + movl %eax,12(%r9) // move final values to the output array.
  2552. + movl %ecx,8(%r9)
  2553. + movl %r10d,4(%r9)
  2554. + movl %r11d,(%r9)
  2555. + ret
  2556. +
  2557. +// AES (Rijndael) Key Schedule Subroutine
  2558. +
  2559. +// This macro performs a column mixing operation on an input 32-bit
  2560. +// word to give a 32-bit result. It uses each of the 4 bytes in the
  2561. +// the input column to index 4 different tables of 256 32-bit words
  2562. +// that are xored together to form the output value.
  2563. +
  2564. +#define mix_col(p1) \
  2565. + movzbl %bl,%ecx ;\
  2566. + movl p1(,%rcx,4),%eax ;\
  2567. + movzbl %bh,%ecx ;\
  2568. + ror $16,%ebx ;\
  2569. + xorl p1+tlen(,%rcx,4),%eax ;\
  2570. + movzbl %bl,%ecx ;\
  2571. + xorl p1+2*tlen(,%rcx,4),%eax ;\
  2572. + movzbl %bh,%ecx ;\
  2573. + xorl p1+3*tlen(,%rcx,4),%eax
  2574. +
  2575. +// Key Schedule Macros
  2576. +
  2577. +#define ksc4(p1) \
  2578. + rol $24,%ebx ;\
  2579. + mix_col(aes_fl_tab) ;\
  2580. + ror $8,%ebx ;\
  2581. + xorl 4*p1+aes_rcon_tab,%eax ;\
  2582. + xorl %eax,%esi ;\
  2583. + xorl %esi,%ebp ;\
  2584. + movl %esi,16*p1(%rdi) ;\
  2585. + movl %ebp,16*p1+4(%rdi) ;\
  2586. + xorl %ebp,%edx ;\
  2587. + xorl %edx,%ebx ;\
  2588. + movl %edx,16*p1+8(%rdi) ;\
  2589. + movl %ebx,16*p1+12(%rdi)
  2590. +
  2591. +#define ksc6(p1) \
  2592. + rol $24,%ebx ;\
  2593. + mix_col(aes_fl_tab) ;\
  2594. + ror $8,%ebx ;\
  2595. + xorl 4*p1+aes_rcon_tab,%eax ;\
  2596. + xorl 24*p1-24(%rdi),%eax ;\
  2597. + movl %eax,24*p1(%rdi) ;\
  2598. + xorl 24*p1-20(%rdi),%eax ;\
  2599. + movl %eax,24*p1+4(%rdi) ;\
  2600. + xorl %eax,%esi ;\
  2601. + xorl %esi,%ebp ;\
  2602. + movl %esi,24*p1+8(%rdi) ;\
  2603. + movl %ebp,24*p1+12(%rdi) ;\
  2604. + xorl %ebp,%edx ;\
  2605. + xorl %edx,%ebx ;\
  2606. + movl %edx,24*p1+16(%rdi) ;\
  2607. + movl %ebx,24*p1+20(%rdi)
  2608. +
  2609. +#define ksc8(p1) \
  2610. + rol $24,%ebx ;\
  2611. + mix_col(aes_fl_tab) ;\
  2612. + ror $8,%ebx ;\
  2613. + xorl 4*p1+aes_rcon_tab,%eax ;\
  2614. + xorl 32*p1-32(%rdi),%eax ;\
  2615. + movl %eax,32*p1(%rdi) ;\
  2616. + xorl 32*p1-28(%rdi),%eax ;\
  2617. + movl %eax,32*p1+4(%rdi) ;\
  2618. + xorl 32*p1-24(%rdi),%eax ;\
  2619. + movl %eax,32*p1+8(%rdi) ;\
  2620. + xorl 32*p1-20(%rdi),%eax ;\
  2621. + movl %eax,32*p1+12(%rdi) ;\
  2622. + pushq %rbx ;\
  2623. + movl %eax,%ebx ;\
  2624. + mix_col(aes_fl_tab) ;\
  2625. + popq %rbx ;\
  2626. + xorl %eax,%esi ;\
  2627. + xorl %esi,%ebp ;\
  2628. + movl %esi,32*p1+16(%rdi) ;\
  2629. + movl %ebp,32*p1+20(%rdi) ;\
  2630. + xorl %ebp,%edx ;\
  2631. + xorl %edx,%ebx ;\
  2632. + movl %edx,32*p1+24(%rdi) ;\
  2633. + movl %ebx,32*p1+28(%rdi)
  2634. +
  2635. +// rdi = pointer to AES context
  2636. +// rsi = pointer to key bytes
  2637. +// rdx = key length, bytes or bits
  2638. +// rcx = ed_flag, 1=encrypt only, 0=both encrypt and decrypt
  2639. +
  2640. + .align ALIGN64BYTES
  2641. +aes_set_key:
  2642. + pushfq
  2643. + pushq %rbp
  2644. + pushq %rbx
  2645. +
  2646. + movq %rcx,%r11 // ed_flg
  2647. + movq %rdx,%rcx // key length
  2648. + movq %rdi,%r10 // AES context
  2649. +
  2650. + cmpl $128,%ecx
  2651. + jb aes_30
  2652. + shrl $3,%ecx
  2653. +aes_30: cmpl $32,%ecx
  2654. + je aes_32
  2655. + cmpl $24,%ecx
  2656. + je aes_32
  2657. + movl $16,%ecx
  2658. +aes_32: shrl $2,%ecx
  2659. + movl %ecx,nkey(%r10)
  2660. + leaq 6(%rcx),%rax // 10/12/14 for 4/6/8 32-bit key length
  2661. + movl %eax,nrnd(%r10)
  2662. + leaq ekey(%r10),%rdi // key position in AES context
  2663. + cld
  2664. + movl %ecx,%eax // save key length in eax
  2665. + rep ; movsl // words in the key schedule
  2666. + movl -4(%rsi),%ebx // put some values in registers
  2667. + movl -8(%rsi),%edx // to allow faster code
  2668. + movl -12(%rsi),%ebp
  2669. + movl -16(%rsi),%esi
  2670. +
  2671. + cmpl $4,%eax // jump on key size
  2672. + je aes_36
  2673. + cmpl $6,%eax
  2674. + je aes_35
  2675. +
  2676. + ksc8(0)
  2677. + ksc8(1)
  2678. + ksc8(2)
  2679. + ksc8(3)
  2680. + ksc8(4)
  2681. + ksc8(5)
  2682. + ksc8(6)
  2683. + jmp aes_37
  2684. +aes_35: ksc6(0)
  2685. + ksc6(1)
  2686. + ksc6(2)
  2687. + ksc6(3)
  2688. + ksc6(4)
  2689. + ksc6(5)
  2690. + ksc6(6)
  2691. + ksc6(7)
  2692. + jmp aes_37
  2693. +aes_36: ksc4(0)
  2694. + ksc4(1)
  2695. + ksc4(2)
  2696. + ksc4(3)
  2697. + ksc4(4)
  2698. + ksc4(5)
  2699. + ksc4(6)
  2700. + ksc4(7)
  2701. + ksc4(8)
  2702. + ksc4(9)
  2703. +aes_37: cmpl $0,%r11d // ed_flg
  2704. + jne aes_39
  2705. +
  2706. +// compile decryption key schedule from encryption schedule - reverse
  2707. +// order and do mix_column operation on round keys except first and last
  2708. +
  2709. + movl nrnd(%r10),%eax // kt = cx->d_key + nc * cx->Nrnd
  2710. + shl $2,%rax
  2711. + leaq dkey(%r10,%rax,4),%rdi
  2712. + leaq ekey(%r10),%rsi // kf = cx->e_key
  2713. +
  2714. + movsq // copy first round key (unmodified)
  2715. + movsq
  2716. + subq $32,%rdi
  2717. + movl $1,%r9d
  2718. +aes_38: // do mix column on each column of
  2719. + lodsl // each round key
  2720. + movl %eax,%ebx
  2721. + mix_col(aes_im_tab)
  2722. + stosl
  2723. + lodsl
  2724. + movl %eax,%ebx
  2725. + mix_col(aes_im_tab)
  2726. + stosl
  2727. + lodsl
  2728. + movl %eax,%ebx
  2729. + mix_col(aes_im_tab)
  2730. + stosl
  2731. + lodsl
  2732. + movl %eax,%ebx
  2733. + mix_col(aes_im_tab)
  2734. + stosl
  2735. + subq $32,%rdi
  2736. +
  2737. + incl %r9d
  2738. + cmpl nrnd(%r10),%r9d
  2739. + jb aes_38
  2740. +
  2741. + movsq // copy last round key (unmodified)
  2742. + movsq
  2743. +aes_39: popq %rbx
  2744. + popq %rbp
  2745. + popfq
  2746. + ret
  2747. +
  2748. +
  2749. +// finite field multiplies by {02}, {04} and {08}
  2750. +
  2751. +#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
  2752. +#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
  2753. +#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
  2754. +
  2755. +// finite field multiplies required in table generation
  2756. +
  2757. +#define f3(x) (f2(x) ^ x)
  2758. +#define f9(x) (f8(x) ^ x)
  2759. +#define fb(x) (f8(x) ^ f2(x) ^ x)
  2760. +#define fd(x) (f8(x) ^ f4(x) ^ x)
  2761. +#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
  2762. +
  2763. +// These defines generate the forward table entries
  2764. +
  2765. +#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x))
  2766. +#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x))
  2767. +#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x)
  2768. +#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x)
  2769. +
  2770. +// These defines generate the inverse table entries
  2771. +
  2772. +#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x))
  2773. +#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x))
  2774. +#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x))
  2775. +#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x))
  2776. +
  2777. +// These defines generate entries for the last round tables
  2778. +
  2779. +#define w0(x) (x)
  2780. +#define w1(x) (x << 8)
  2781. +#define w2(x) (x << 16)
  2782. +#define w3(x) (x << 24)
  2783. +
  2784. +// macro to generate inverse mix column tables (needed for the key schedule)
  2785. +
  2786. +#define im_data0(p1) \
  2787. + .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\
  2788. + .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\
  2789. + .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\
  2790. + .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f)
  2791. +#define im_data1(p1) \
  2792. + .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\
  2793. + .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\
  2794. + .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\
  2795. + .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f)
  2796. +#define im_data2(p1) \
  2797. + .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\
  2798. + .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\
  2799. + .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\
  2800. + .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f)
  2801. +#define im_data3(p1) \
  2802. + .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\
  2803. + .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\
  2804. + .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\
  2805. + .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f)
  2806. +#define im_data4(p1) \
  2807. + .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\
  2808. + .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\
  2809. + .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\
  2810. + .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f)
  2811. +#define im_data5(p1) \
  2812. + .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\
  2813. + .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\
  2814. + .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\
  2815. + .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf)
  2816. +#define im_data6(p1) \
  2817. + .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\
  2818. + .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\
  2819. + .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\
  2820. + .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf)
  2821. +#define im_data7(p1) \
  2822. + .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\
  2823. + .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\
  2824. + .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\
  2825. + .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff)
  2826. +
  2827. +// S-box data - 256 entries
  2828. +
  2829. +#define sb_data0(p1) \
  2830. + .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\
  2831. + .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\
  2832. + .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\
  2833. + .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0)
  2834. +#define sb_data1(p1) \
  2835. + .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\
  2836. + .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\
  2837. + .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\
  2838. + .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75)
  2839. +#define sb_data2(p1) \
  2840. + .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\
  2841. + .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\
  2842. + .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\
  2843. + .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf)
  2844. +#define sb_data3(p1) \
  2845. + .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\
  2846. + .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\
  2847. + .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\
  2848. + .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2)
  2849. +#define sb_data4(p1) \
  2850. + .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\
  2851. + .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\
  2852. + .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\
  2853. + .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb)
  2854. +#define sb_data5(p1) \
  2855. + .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\
  2856. + .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\
  2857. + .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\
  2858. + .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08)
  2859. +#define sb_data6(p1) \
  2860. + .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\
  2861. + .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\
  2862. + .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\
  2863. + .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e)
  2864. +#define sb_data7(p1) \
  2865. + .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\
  2866. + .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\
  2867. + .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\
  2868. + .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16)
  2869. +
  2870. +// Inverse S-box data - 256 entries
  2871. +
  2872. +#define ib_data0(p1) \
  2873. + .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\
  2874. + .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\
  2875. + .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\
  2876. + .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb)
  2877. +#define ib_data1(p1) \
  2878. + .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\
  2879. + .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\
  2880. + .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\
  2881. + .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25)
  2882. +#define ib_data2(p1) \
  2883. + .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\
  2884. + .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\
  2885. + .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\
  2886. + .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84)
  2887. +#define ib_data3(p1) \
  2888. + .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\
  2889. + .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\
  2890. + .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\
  2891. + .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b)
  2892. +#define ib_data4(p1) \
  2893. + .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\
  2894. + .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\
  2895. + .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\
  2896. + .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e)
  2897. +#define ib_data5(p1) \
  2898. + .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\
  2899. + .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\
  2900. + .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\
  2901. + .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4)
  2902. +#define ib_data6(p1) \
  2903. + .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\
  2904. + .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\
  2905. + .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\
  2906. + .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef)
  2907. +#define ib_data7(p1) \
  2908. + .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\
  2909. + .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\
  2910. + .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\
  2911. + .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d)
  2912. +
  2913. +// The rcon_table (needed for the key schedule)
  2914. +//
  2915. +// Here is original Dr Brian Gladman's source code:
  2916. +// _rcon_tab:
  2917. +// %assign x 1
  2918. +// %rep 29
  2919. +// dd x
  2920. +// %assign x f2(x)
  2921. +// %endrep
  2922. +//
  2923. +// Here is precomputed output (it's more portable this way):
  2924. +
  2925. + .section .rodata
  2926. + .align ALIGN64BYTES
  2927. +aes_rcon_tab:
  2928. + .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
  2929. + .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f
  2930. + .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4
  2931. + .long 0xb3,0x7d,0xfa,0xef,0xc5
  2932. +
  2933. +// The forward xor tables
  2934. +
  2935. + .align ALIGN64BYTES
  2936. +aes_ft_tab:
  2937. + sb_data0(u0)
  2938. + sb_data1(u0)
  2939. + sb_data2(u0)
  2940. + sb_data3(u0)
  2941. + sb_data4(u0)
  2942. + sb_data5(u0)
  2943. + sb_data6(u0)
  2944. + sb_data7(u0)
  2945. +
  2946. + sb_data0(u1)
  2947. + sb_data1(u1)
  2948. + sb_data2(u1)
  2949. + sb_data3(u1)
  2950. + sb_data4(u1)
  2951. + sb_data5(u1)
  2952. + sb_data6(u1)
  2953. + sb_data7(u1)
  2954. +
  2955. + sb_data0(u2)
  2956. + sb_data1(u2)
  2957. + sb_data2(u2)
  2958. + sb_data3(u2)
  2959. + sb_data4(u2)
  2960. + sb_data5(u2)
  2961. + sb_data6(u2)
  2962. + sb_data7(u2)
  2963. +
  2964. + sb_data0(u3)
  2965. + sb_data1(u3)
  2966. + sb_data2(u3)
  2967. + sb_data3(u3)
  2968. + sb_data4(u3)
  2969. + sb_data5(u3)
  2970. + sb_data6(u3)
  2971. + sb_data7(u3)
  2972. +
  2973. + .align ALIGN64BYTES
  2974. +aes_fl_tab:
  2975. + sb_data0(w0)
  2976. + sb_data1(w0)
  2977. + sb_data2(w0)
  2978. + sb_data3(w0)
  2979. + sb_data4(w0)
  2980. + sb_data5(w0)
  2981. + sb_data6(w0)
  2982. + sb_data7(w0)
  2983. +
  2984. + sb_data0(w1)
  2985. + sb_data1(w1)
  2986. + sb_data2(w1)
  2987. + sb_data3(w1)
  2988. + sb_data4(w1)
  2989. + sb_data5(w1)
  2990. + sb_data6(w1)
  2991. + sb_data7(w1)
  2992. +
  2993. + sb_data0(w2)
  2994. + sb_data1(w2)
  2995. + sb_data2(w2)
  2996. + sb_data3(w2)
  2997. + sb_data4(w2)
  2998. + sb_data5(w2)
  2999. + sb_data6(w2)
  3000. + sb_data7(w2)
  3001. +
  3002. + sb_data0(w3)
  3003. + sb_data1(w3)
  3004. + sb_data2(w3)
  3005. + sb_data3(w3)
  3006. + sb_data4(w3)
  3007. + sb_data5(w3)
  3008. + sb_data6(w3)
  3009. + sb_data7(w3)
  3010. +
  3011. +// The inverse xor tables
  3012. +
  3013. + .align ALIGN64BYTES
  3014. +aes_it_tab:
  3015. + ib_data0(v0)
  3016. + ib_data1(v0)
  3017. + ib_data2(v0)
  3018. + ib_data3(v0)
  3019. + ib_data4(v0)
  3020. + ib_data5(v0)
  3021. + ib_data6(v0)
  3022. + ib_data7(v0)
  3023. +
  3024. + ib_data0(v1)
  3025. + ib_data1(v1)
  3026. + ib_data2(v1)
  3027. + ib_data3(v1)
  3028. + ib_data4(v1)
  3029. + ib_data5(v1)
  3030. + ib_data6(v1)
  3031. + ib_data7(v1)
  3032. +
  3033. + ib_data0(v2)
  3034. + ib_data1(v2)
  3035. + ib_data2(v2)
  3036. + ib_data3(v2)
  3037. + ib_data4(v2)
  3038. + ib_data5(v2)
  3039. + ib_data6(v2)
  3040. + ib_data7(v2)
  3041. +
  3042. + ib_data0(v3)
  3043. + ib_data1(v3)
  3044. + ib_data2(v3)
  3045. + ib_data3(v3)
  3046. + ib_data4(v3)
  3047. + ib_data5(v3)
  3048. + ib_data6(v3)
  3049. + ib_data7(v3)
  3050. +
  3051. + .align ALIGN64BYTES
  3052. +aes_il_tab:
  3053. + ib_data0(w0)
  3054. + ib_data1(w0)
  3055. + ib_data2(w0)
  3056. + ib_data3(w0)
  3057. + ib_data4(w0)
  3058. + ib_data5(w0)
  3059. + ib_data6(w0)
  3060. + ib_data7(w0)
  3061. +
  3062. + ib_data0(w1)
  3063. + ib_data1(w1)
  3064. + ib_data2(w1)
  3065. + ib_data3(w1)
  3066. + ib_data4(w1)
  3067. + ib_data5(w1)
  3068. + ib_data6(w1)
  3069. + ib_data7(w1)
  3070. +
  3071. + ib_data0(w2)
  3072. + ib_data1(w2)
  3073. + ib_data2(w2)
  3074. + ib_data3(w2)
  3075. + ib_data4(w2)
  3076. + ib_data5(w2)
  3077. + ib_data6(w2)
  3078. + ib_data7(w2)
  3079. +
  3080. + ib_data0(w3)
  3081. + ib_data1(w3)
  3082. + ib_data2(w3)
  3083. + ib_data3(w3)
  3084. + ib_data4(w3)
  3085. + ib_data5(w3)
  3086. + ib_data6(w3)
  3087. + ib_data7(w3)
  3088. +
  3089. +// The inverse mix column tables
  3090. +
  3091. + .align ALIGN64BYTES
  3092. +aes_im_tab:
  3093. + im_data0(v0)
  3094. + im_data1(v0)
  3095. + im_data2(v0)
  3096. + im_data3(v0)
  3097. + im_data4(v0)
  3098. + im_data5(v0)
  3099. + im_data6(v0)
  3100. + im_data7(v0)
  3101. +
  3102. + im_data0(v1)
  3103. + im_data1(v1)
  3104. + im_data2(v1)
  3105. + im_data3(v1)
  3106. + im_data4(v1)
  3107. + im_data5(v1)
  3108. + im_data6(v1)
  3109. + im_data7(v1)
  3110. +
  3111. + im_data0(v2)
  3112. + im_data1(v2)
  3113. + im_data2(v2)
  3114. + im_data3(v2)
  3115. + im_data4(v2)
  3116. + im_data5(v2)
  3117. + im_data6(v2)
  3118. + im_data7(v2)
  3119. +
  3120. + im_data0(v3)
  3121. + im_data1(v3)
  3122. + im_data2(v3)
  3123. + im_data3(v3)
  3124. + im_data4(v3)
  3125. + im_data5(v3)
  3126. + im_data6(v3)
  3127. + im_data7(v3)
  3128. diff -pruN linux-2.4.27_orig/drivers/misc/aes-x86.S linux-2.4.27/drivers/misc/aes-x86.S
  3129. --- linux-2.4.27_orig/drivers/misc/aes-x86.S 1970-01-01 01:00:00.000000000 +0100
  3130. +++ linux-2.4.27/drivers/misc/aes-x86.S 2004-10-25 14:20:44.725003256 +0200
  3131. @@ -0,0 +1,922 @@
  3132. +//
  3133. +// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
  3134. +// All rights reserved.
  3135. +//
  3136. +// TERMS
  3137. +//
  3138. +// Redistribution and use in source and binary forms, with or without
  3139. +// modification, are permitted subject to the following conditions:
  3140. +//
  3141. +// 1. Redistributions of source code must retain the above copyright
  3142. +// notice, this list of conditions and the following disclaimer.
  3143. +//
  3144. +// 2. Redistributions in binary form must reproduce the above copyright
  3145. +// notice, this list of conditions and the following disclaimer in the
  3146. +// documentation and/or other materials provided with the distribution.
  3147. +//
  3148. +// 3. The copyright holder's name must not be used to endorse or promote
  3149. +// any products derived from this software without his specific prior
  3150. +// written permission.
  3151. +//
  3152. +// This software is provided 'as is' with no express or implied warranties
  3153. +// of correctness or fitness for purpose.
  3154. +
  3155. +// Modified by Jari Ruusu, December 24 2001
  3156. +// - Converted syntax to GNU CPP/assembler syntax
  3157. +// - C programming interface converted back to "old" API
  3158. +// - Minor portability cleanups and speed optimizations
  3159. +
  3160. +// Modified by Jari Ruusu, April 11 2002
  3161. +// - Added above copyright and terms to resulting object code so that
  3162. +// binary distributions can avoid legal trouble
  3163. +
  3164. +// An AES (Rijndael) implementation for x86 compatible processors. This
  3165. +// version uses i386 instruction set but instruction scheduling is optimized
  3166. +// for Pentium-2. This version only implements the standard AES block length
  3167. +// (128 bits, 16 bytes). This code does not preserve the eax, ecx or edx
  3168. +// registers or the artihmetic status flags. However, the ebx, esi, edi, and
  3169. +// ebp registers are preserved across calls.
  3170. +
  3171. +// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f)
  3172. +// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
  3173. +// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
  3174. +
  3175. +#if defined(USE_UNDERLINE)
  3176. +# define aes_set_key _aes_set_key
  3177. +# define aes_encrypt _aes_encrypt
  3178. +# define aes_decrypt _aes_decrypt
  3179. +#endif
  3180. +#if !defined(ALIGN32BYTES)
  3181. +# define ALIGN32BYTES 32
  3182. +#endif
  3183. +
  3184. + .file "aes-x86.S"
  3185. + .globl aes_set_key
  3186. + .globl aes_encrypt
  3187. + .globl aes_decrypt
  3188. +
  3189. + .text
  3190. +copyright:
  3191. + .ascii " \000"
  3192. + .ascii "Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.\000"
  3193. + .ascii "All rights reserved.\000"
  3194. + .ascii " \000"
  3195. + .ascii "TERMS\000"
  3196. + .ascii " \000"
  3197. + .ascii " Redistribution and use in source and binary forms, with or without\000"
  3198. + .ascii " modification, are permitted subject to the following conditions:\000"
  3199. + .ascii " \000"
  3200. + .ascii " 1. Redistributions of source code must retain the above copyright\000"
  3201. + .ascii " notice, this list of conditions and the following disclaimer.\000"
  3202. + .ascii " \000"
  3203. + .ascii " 2. Redistributions in binary form must reproduce the above copyright\000"
  3204. + .ascii " notice, this list of conditions and the following disclaimer in the\000"
  3205. + .ascii " documentation and/or other materials provided with the distribution.\000"
  3206. + .ascii " \000"
  3207. + .ascii " 3. The copyright holder's name must not be used to endorse or promote\000"
  3208. + .ascii " any products derived from this software without his specific prior\000"
  3209. + .ascii " written permission.\000"
  3210. + .ascii " \000"
  3211. + .ascii " This software is provided 'as is' with no express or implied warranties\000"
  3212. + .ascii " of correctness or fitness for purpose.\000"
  3213. + .ascii " \000"
  3214. +
  3215. +#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
  3216. +
  3217. +// offsets to parameters with one register pushed onto stack
  3218. +
  3219. +#define ctx 8 // AES context structure
  3220. +#define in_blk 12 // input byte array address parameter
  3221. +#define out_blk 16 // output byte array address parameter
  3222. +
  3223. +// offsets in context structure
  3224. +
  3225. +#define nkey 0 // key length, size 4
  3226. +#define nrnd 4 // number of rounds, size 4
  3227. +#define ekey 8 // encryption key schedule base address, size 256
  3228. +#define dkey 264 // decryption key schedule base address, size 256
  3229. +
  3230. +// This macro performs a forward encryption cycle. It is entered with
  3231. +// the first previous round column values in %eax, %ebx, %esi and %edi and
  3232. +// exits with the final values in the same registers.
  3233. +
  3234. +#define fwd_rnd(p1,p2) \
  3235. + mov %ebx,(%esp) ;\
  3236. + movzbl %al,%edx ;\
  3237. + mov %eax,%ecx ;\
  3238. + mov p2(%ebp),%eax ;\
  3239. + mov %edi,4(%esp) ;\
  3240. + mov p2+12(%ebp),%edi ;\
  3241. + xor p1(,%edx,4),%eax ;\
  3242. + movzbl %ch,%edx ;\
  3243. + shr $16,%ecx ;\
  3244. + mov p2+4(%ebp),%ebx ;\
  3245. + xor p1+tlen(,%edx,4),%edi ;\
  3246. + movzbl %cl,%edx ;\
  3247. + movzbl %ch,%ecx ;\
  3248. + xor p1+3*tlen(,%ecx,4),%ebx ;\
  3249. + mov %esi,%ecx ;\
  3250. + mov p1+2*tlen(,%edx,4),%esi ;\
  3251. + movzbl %cl,%edx ;\
  3252. + xor p1(,%edx,4),%esi ;\
  3253. + movzbl %ch,%edx ;\
  3254. + shr $16,%ecx ;\
  3255. + xor p1+tlen(,%edx,4),%ebx ;\
  3256. + movzbl %cl,%edx ;\
  3257. + movzbl %ch,%ecx ;\
  3258. + xor p1+2*tlen(,%edx,4),%eax ;\
  3259. + mov (%esp),%edx ;\
  3260. + xor p1+3*tlen(,%ecx,4),%edi ;\
  3261. + movzbl %dl,%ecx ;\
  3262. + xor p2+8(%ebp),%esi ;\
  3263. + xor p1(,%ecx,4),%ebx ;\
  3264. + movzbl %dh,%ecx ;\
  3265. + shr $16,%edx ;\
  3266. + xor p1+tlen(,%ecx,4),%eax ;\
  3267. + movzbl %dl,%ecx ;\
  3268. + movzbl %dh,%edx ;\
  3269. + xor p1+2*tlen(,%ecx,4),%edi ;\
  3270. + mov 4(%esp),%ecx ;\
  3271. + xor p1+3*tlen(,%edx,4),%esi ;\
  3272. + movzbl %cl,%edx ;\
  3273. + xor p1(,%edx,4),%edi ;\
  3274. + movzbl %ch,%edx ;\
  3275. + shr $16,%ecx ;\
  3276. + xor p1+tlen(,%edx,4),%esi ;\
  3277. + movzbl %cl,%edx ;\
  3278. + movzbl %ch,%ecx ;\
  3279. + xor p1+2*tlen(,%edx,4),%ebx ;\
  3280. + xor p1+3*tlen(,%ecx,4),%eax
  3281. +
  3282. +// This macro performs an inverse encryption cycle. It is entered with
  3283. +// the first previous round column values in %eax, %ebx, %esi and %edi and
  3284. +// exits with the final values in the same registers.
  3285. +
  3286. +#define inv_rnd(p1,p2) \
  3287. + movzbl %al,%edx ;\
  3288. + mov %ebx,(%esp) ;\
  3289. + mov %eax,%ecx ;\
  3290. + mov p2(%ebp),%eax ;\
  3291. + mov %edi,4(%esp) ;\
  3292. + mov p2+4(%ebp),%ebx ;\
  3293. + xor p1(,%edx,4),%eax ;\
  3294. + movzbl %ch,%edx ;\
  3295. + shr $16,%ecx ;\
  3296. + mov p2+12(%ebp),%edi ;\
  3297. + xor p1+tlen(,%edx,4),%ebx ;\
  3298. + movzbl %cl,%edx ;\
  3299. + movzbl %ch,%ecx ;\
  3300. + xor p1+3*tlen(,%ecx,4),%edi ;\
  3301. + mov %esi,%ecx ;\
  3302. + mov p1+2*tlen(,%edx,4),%esi ;\
  3303. + movzbl %cl,%edx ;\
  3304. + xor p1(,%edx,4),%esi ;\
  3305. + movzbl %ch,%edx ;\
  3306. + shr $16,%ecx ;\
  3307. + xor p1+tlen(,%edx,4),%edi ;\
  3308. + movzbl %cl,%edx ;\
  3309. + movzbl %ch,%ecx ;\
  3310. + xor p1+2*tlen(,%edx,4),%eax ;\
  3311. + mov (%esp),%edx ;\
  3312. + xor p1+3*tlen(,%ecx,4),%ebx ;\
  3313. + movzbl %dl,%ecx ;\
  3314. + xor p2+8(%ebp),%esi ;\
  3315. + xor p1(,%ecx,4),%ebx ;\
  3316. + movzbl %dh,%ecx ;\
  3317. + shr $16,%edx ;\
  3318. + xor p1+tlen(,%ecx,4),%esi ;\
  3319. + movzbl %dl,%ecx ;\
  3320. + movzbl %dh,%edx ;\
  3321. + xor p1+2*tlen(,%ecx,4),%edi ;\
  3322. + mov 4(%esp),%ecx ;\
  3323. + xor p1+3*tlen(,%edx,4),%eax ;\
  3324. + movzbl %cl,%edx ;\
  3325. + xor p1(,%edx,4),%edi ;\
  3326. + movzbl %ch,%edx ;\
  3327. + shr $16,%ecx ;\
  3328. + xor p1+tlen(,%edx,4),%eax ;\
  3329. + movzbl %cl,%edx ;\
  3330. + movzbl %ch,%ecx ;\
  3331. + xor p1+2*tlen(,%edx,4),%ebx ;\
  3332. + xor p1+3*tlen(,%ecx,4),%esi
  3333. +
  3334. +// AES (Rijndael) Encryption Subroutine
  3335. +
  3336. + .text
  3337. + .align ALIGN32BYTES
  3338. +aes_encrypt:
  3339. + push %ebp
  3340. + mov ctx(%esp),%ebp // pointer to context
  3341. + mov in_blk(%esp),%ecx
  3342. + push %ebx
  3343. + push %esi
  3344. + push %edi
  3345. + mov nrnd(%ebp),%edx // number of rounds
  3346. + lea ekey+16(%ebp),%ebp // key pointer
  3347. +
  3348. +// input four columns and xor in first round key
  3349. +
  3350. + mov (%ecx),%eax
  3351. + mov 4(%ecx),%ebx
  3352. + mov 8(%ecx),%esi
  3353. + mov 12(%ecx),%edi
  3354. + xor -16(%ebp),%eax
  3355. + xor -12(%ebp),%ebx
  3356. + xor -8(%ebp),%esi
  3357. + xor -4(%ebp),%edi
  3358. +
  3359. + sub $8,%esp // space for register saves on stack
  3360. +
  3361. + sub $10,%edx
  3362. + je aes_15
  3363. + add $32,%ebp
  3364. + sub $2,%edx
  3365. + je aes_13
  3366. + add $32,%ebp
  3367. +
  3368. + fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key
  3369. + fwd_rnd(aes_ft_tab,-48)
  3370. +aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key
  3371. + fwd_rnd(aes_ft_tab,-16)
  3372. +aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key
  3373. + fwd_rnd(aes_ft_tab,16)
  3374. + fwd_rnd(aes_ft_tab,32)
  3375. + fwd_rnd(aes_ft_tab,48)
  3376. + fwd_rnd(aes_ft_tab,64)
  3377. + fwd_rnd(aes_ft_tab,80)
  3378. + fwd_rnd(aes_ft_tab,96)
  3379. + fwd_rnd(aes_ft_tab,112)
  3380. + fwd_rnd(aes_ft_tab,128)
  3381. + fwd_rnd(aes_fl_tab,144) // last round uses a different table
  3382. +
  3383. +// move final values to the output array.
  3384. +
  3385. + mov out_blk+20(%esp),%ebp
  3386. + add $8,%esp
  3387. + mov %eax,(%ebp)
  3388. + mov %ebx,4(%ebp)
  3389. + mov %esi,8(%ebp)
  3390. + mov %edi,12(%ebp)
  3391. + pop %edi
  3392. + pop %esi
  3393. + pop %ebx
  3394. + pop %ebp
  3395. + ret
  3396. +
  3397. +
  3398. +// AES (Rijndael) Decryption Subroutine
  3399. +
  3400. + .align ALIGN32BYTES
  3401. +aes_decrypt:
  3402. + push %ebp
  3403. + mov ctx(%esp),%ebp // pointer to context
  3404. + mov in_blk(%esp),%ecx
  3405. + push %ebx
  3406. + push %esi
  3407. + push %edi
  3408. + mov nrnd(%ebp),%edx // number of rounds
  3409. + lea dkey+16(%ebp),%ebp // key pointer
  3410. +
  3411. +// input four columns and xor in first round key
  3412. +
  3413. + mov (%ecx),%eax
  3414. + mov 4(%ecx),%ebx
  3415. + mov 8(%ecx),%esi
  3416. + mov 12(%ecx),%edi
  3417. + xor -16(%ebp),%eax
  3418. + xor -12(%ebp),%ebx
  3419. + xor -8(%ebp),%esi
  3420. + xor -4(%ebp),%edi
  3421. +
  3422. + sub $8,%esp // space for register saves on stack
  3423. +
  3424. + sub $10,%edx
  3425. + je aes_25
  3426. + add $32,%ebp
  3427. + sub $2,%edx
  3428. + je aes_23
  3429. + add $32,%ebp
  3430. +
  3431. + inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key
  3432. + inv_rnd(aes_it_tab,-48)
  3433. +aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key
  3434. + inv_rnd(aes_it_tab,-16)
  3435. +aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key
  3436. + inv_rnd(aes_it_tab,16)
  3437. + inv_rnd(aes_it_tab,32)
  3438. + inv_rnd(aes_it_tab,48)
  3439. + inv_rnd(aes_it_tab,64)
  3440. + inv_rnd(aes_it_tab,80)
  3441. + inv_rnd(aes_it_tab,96)
  3442. + inv_rnd(aes_it_tab,112)
  3443. + inv_rnd(aes_it_tab,128)
  3444. + inv_rnd(aes_il_tab,144) // last round uses a different table
  3445. +
  3446. +// move final values to the output array.
  3447. +
  3448. + mov out_blk+20(%esp),%ebp
  3449. + add $8,%esp
  3450. + mov %eax,(%ebp)
  3451. + mov %ebx,4(%ebp)
  3452. + mov %esi,8(%ebp)
  3453. + mov %edi,12(%ebp)
  3454. + pop %edi
  3455. + pop %esi
  3456. + pop %ebx
  3457. + pop %ebp
  3458. + ret
  3459. +
  3460. +// AES (Rijndael) Key Schedule Subroutine
  3461. +
  3462. +// input/output parameters
  3463. +
  3464. +#define aes_cx 12 // AES context
  3465. +#define in_key 16 // key input array address
  3466. +#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256)
  3467. +#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only
  3468. +
  3469. +// offsets for locals
  3470. +
  3471. +#define cnt -4
  3472. +#define slen 8
  3473. +
  3474. +// This macro performs a column mixing operation on an input 32-bit
  3475. +// word to give a 32-bit result. It uses each of the 4 bytes in the
  3476. +// the input column to index 4 different tables of 256 32-bit words
  3477. +// that are xored together to form the output value.
  3478. +
  3479. +#define mix_col(p1) \
  3480. + movzbl %bl,%ecx ;\
  3481. + mov p1(,%ecx,4),%eax ;\
  3482. + movzbl %bh,%ecx ;\
  3483. + ror $16,%ebx ;\
  3484. + xor p1+tlen(,%ecx,4),%eax ;\
  3485. + movzbl %bl,%ecx ;\
  3486. + xor p1+2*tlen(,%ecx,4),%eax ;\
  3487. + movzbl %bh,%ecx ;\
  3488. + xor p1+3*tlen(,%ecx,4),%eax
  3489. +
  3490. +// Key Schedule Macros
  3491. +
  3492. +#define ksc4(p1) \
  3493. + rol $24,%ebx ;\
  3494. + mix_col(aes_fl_tab) ;\
  3495. + ror $8,%ebx ;\
  3496. + xor 4*p1+aes_rcon_tab,%eax ;\
  3497. + xor %eax,%esi ;\
  3498. + xor %esi,%ebp ;\
  3499. + mov %esi,16*p1(%edi) ;\
  3500. + mov %ebp,16*p1+4(%edi) ;\
  3501. + xor %ebp,%edx ;\
  3502. + xor %edx,%ebx ;\
  3503. + mov %edx,16*p1+8(%edi) ;\
  3504. + mov %ebx,16*p1+12(%edi)
  3505. +
  3506. +#define ksc6(p1) \
  3507. + rol $24,%ebx ;\
  3508. + mix_col(aes_fl_tab) ;\
  3509. + ror $8,%ebx ;\
  3510. + xor 4*p1+aes_rcon_tab,%eax ;\
  3511. + xor 24*p1-24(%edi),%eax ;\
  3512. + mov %eax,24*p1(%edi) ;\
  3513. + xor 24*p1-20(%edi),%eax ;\
  3514. + mov %eax,24*p1+4(%edi) ;\
  3515. + xor %eax,%esi ;\
  3516. + xor %esi,%ebp ;\
  3517. + mov %esi,24*p1+8(%edi) ;\
  3518. + mov %ebp,24*p1+12(%edi) ;\
  3519. + xor %ebp,%edx ;\
  3520. + xor %edx,%ebx ;\
  3521. + mov %edx,24*p1+16(%edi) ;\
  3522. + mov %ebx,24*p1+20(%edi)
  3523. +
  3524. +#define ksc8(p1) \
  3525. + rol $24,%ebx ;\
  3526. + mix_col(aes_fl_tab) ;\
  3527. + ror $8,%ebx ;\
  3528. + xor 4*p1+aes_rcon_tab,%eax ;\
  3529. + xor 32*p1-32(%edi),%eax ;\
  3530. + mov %eax,32*p1(%edi) ;\
  3531. + xor 32*p1-28(%edi),%eax ;\
  3532. + mov %eax,32*p1+4(%edi) ;\
  3533. + xor 32*p1-24(%edi),%eax ;\
  3534. + mov %eax,32*p1+8(%edi) ;\
  3535. + xor 32*p1-20(%edi),%eax ;\
  3536. + mov %eax,32*p1+12(%edi) ;\
  3537. + push %ebx ;\
  3538. + mov %eax,%ebx ;\
  3539. + mix_col(aes_fl_tab) ;\
  3540. + pop %ebx ;\
  3541. + xor %eax,%esi ;\
  3542. + xor %esi,%ebp ;\
  3543. + mov %esi,32*p1+16(%edi) ;\
  3544. + mov %ebp,32*p1+20(%edi) ;\
  3545. + xor %ebp,%edx ;\
  3546. + xor %edx,%ebx ;\
  3547. + mov %edx,32*p1+24(%edi) ;\
  3548. + mov %ebx,32*p1+28(%edi)
  3549. +
  3550. + .align ALIGN32BYTES
  3551. +aes_set_key:
  3552. + pushfl
  3553. + push %ebp
  3554. + mov %esp,%ebp
  3555. + sub $slen,%esp
  3556. + push %ebx
  3557. + push %esi
  3558. + push %edi
  3559. +
  3560. + mov aes_cx(%ebp),%edx // edx -> AES context
  3561. +
  3562. + mov key_ln(%ebp),%ecx // key length
  3563. + cmpl $128,%ecx
  3564. + jb aes_30
  3565. + shr $3,%ecx
  3566. +aes_30: cmpl $32,%ecx
  3567. + je aes_32
  3568. + cmpl $24,%ecx
  3569. + je aes_32
  3570. + mov $16,%ecx
  3571. +aes_32: shr $2,%ecx
  3572. + mov %ecx,nkey(%edx)
  3573. +
  3574. + lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length
  3575. + mov %eax,nrnd(%edx)
  3576. +
  3577. + mov in_key(%ebp),%esi // key input array
  3578. + lea ekey(%edx),%edi // key position in AES context
  3579. + cld
  3580. + push %ebp
  3581. + mov %ecx,%eax // save key length in eax
  3582. + rep ; movsl // words in the key schedule
  3583. + mov -4(%esi),%ebx // put some values in registers
  3584. + mov -8(%esi),%edx // to allow faster code
  3585. + mov -12(%esi),%ebp
  3586. + mov -16(%esi),%esi
  3587. +
  3588. + cmpl $4,%eax // jump on key size
  3589. + je aes_36
  3590. + cmpl $6,%eax
  3591. + je aes_35
  3592. +
  3593. + ksc8(0)
  3594. + ksc8(1)
  3595. + ksc8(2)
  3596. + ksc8(3)
  3597. + ksc8(4)
  3598. + ksc8(5)
  3599. + ksc8(6)
  3600. + jmp aes_37
  3601. +aes_35: ksc6(0)
  3602. + ksc6(1)
  3603. + ksc6(2)
  3604. + ksc6(3)
  3605. + ksc6(4)
  3606. + ksc6(5)
  3607. + ksc6(6)
  3608. + ksc6(7)
  3609. + jmp aes_37
  3610. +aes_36: ksc4(0)
  3611. + ksc4(1)
  3612. + ksc4(2)
  3613. + ksc4(3)
  3614. + ksc4(4)
  3615. + ksc4(5)
  3616. + ksc4(6)
  3617. + ksc4(7)
  3618. + ksc4(8)
  3619. + ksc4(9)
  3620. +aes_37: pop %ebp
  3621. + mov aes_cx(%ebp),%edx // edx -> AES context
  3622. + cmpl $0,ed_flg(%ebp)
  3623. + jne aes_39
  3624. +
  3625. +// compile decryption key schedule from encryption schedule - reverse
  3626. +// order and do mix_column operation on round keys except first and last
  3627. +
  3628. + mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd
  3629. + shl $2,%eax
  3630. + lea dkey(%edx,%eax,4),%edi
  3631. + lea ekey(%edx),%esi // kf = cx->e_key
  3632. +
  3633. + movsl // copy first round key (unmodified)
  3634. + movsl
  3635. + movsl
  3636. + movsl
  3637. + sub $32,%edi
  3638. + movl $1,cnt(%ebp)
  3639. +aes_38: // do mix column on each column of
  3640. + lodsl // each round key
  3641. + mov %eax,%ebx
  3642. + mix_col(aes_im_tab)
  3643. + stosl
  3644. + lodsl
  3645. + mov %eax,%ebx
  3646. + mix_col(aes_im_tab)
  3647. + stosl
  3648. + lodsl
  3649. + mov %eax,%ebx
  3650. + mix_col(aes_im_tab)
  3651. + stosl
  3652. + lodsl
  3653. + mov %eax,%ebx
  3654. + mix_col(aes_im_tab)
  3655. + stosl
  3656. + sub $32,%edi
  3657. +
  3658. + incl cnt(%ebp)
  3659. + mov cnt(%ebp),%eax
  3660. + cmp nrnd(%edx),%eax
  3661. + jb aes_38
  3662. +
  3663. + movsl // copy last round key (unmodified)
  3664. + movsl
  3665. + movsl
  3666. + movsl
  3667. +aes_39: pop %edi
  3668. + pop %esi
  3669. + pop %ebx
  3670. + mov %ebp,%esp
  3671. + pop %ebp
  3672. + popfl
  3673. + ret
  3674. +
  3675. +
  3676. +// finite field multiplies by {02}, {04} and {08}
  3677. +
  3678. +#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
  3679. +#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
  3680. +#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
  3681. +
  3682. +// finite field multiplies required in table generation
  3683. +
  3684. +#define f3(x) (f2(x) ^ x)
  3685. +#define f9(x) (f8(x) ^ x)
  3686. +#define fb(x) (f8(x) ^ f2(x) ^ x)
  3687. +#define fd(x) (f8(x) ^ f4(x) ^ x)
  3688. +#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
  3689. +
  3690. +// These defines generate the forward table entries
  3691. +
  3692. +#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x))
  3693. +#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x))
  3694. +#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x)
  3695. +#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x)
  3696. +
  3697. +// These defines generate the inverse table entries
  3698. +
  3699. +#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x))
  3700. +#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x))
  3701. +#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x))
  3702. +#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x))
  3703. +
  3704. +// These defines generate entries for the last round tables
  3705. +
  3706. +#define w0(x) (x)
  3707. +#define w1(x) (x << 8)
  3708. +#define w2(x) (x << 16)
  3709. +#define w3(x) (x << 24)
  3710. +
  3711. +// macro to generate inverse mix column tables (needed for the key schedule)
  3712. +
  3713. +#define im_data0(p1) \
  3714. + .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\
  3715. + .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\
  3716. + .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\
  3717. + .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f)
  3718. +#define im_data1(p1) \
  3719. + .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\
  3720. + .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\
  3721. + .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\
  3722. + .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f)
  3723. +#define im_data2(p1) \
  3724. + .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\
  3725. + .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\
  3726. + .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\
  3727. + .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f)
  3728. +#define im_data3(p1) \
  3729. + .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\
  3730. + .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\
  3731. + .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\
  3732. + .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f)
  3733. +#define im_data4(p1) \
  3734. + .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\
  3735. + .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\
  3736. + .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\
  3737. + .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f)
  3738. +#define im_data5(p1) \
  3739. + .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\
  3740. + .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\
  3741. + .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\
  3742. + .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf)
  3743. +#define im_data6(p1) \
  3744. + .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\
  3745. + .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\
  3746. + .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\
  3747. + .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf)
  3748. +#define im_data7(p1) \
  3749. + .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\
  3750. + .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\
  3751. + .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\
  3752. + .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff)
  3753. +
  3754. +// S-box data - 256 entries
  3755. +
  3756. +#define sb_data0(p1) \
  3757. + .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\
  3758. + .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\
  3759. + .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\
  3760. + .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0)
  3761. +#define sb_data1(p1) \
  3762. + .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\
  3763. + .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\
  3764. + .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\
  3765. + .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75)
  3766. +#define sb_data2(p1) \
  3767. + .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\
  3768. + .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\
  3769. + .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\
  3770. + .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf)
  3771. +#define sb_data3(p1) \
  3772. + .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\
  3773. + .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\
  3774. + .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\
  3775. + .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2)
  3776. +#define sb_data4(p1) \
  3777. + .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\
  3778. + .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\
  3779. + .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\
  3780. + .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb)
  3781. +#define sb_data5(p1) \
  3782. + .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\
  3783. + .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\
  3784. + .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\
  3785. + .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08)
  3786. +#define sb_data6(p1) \
  3787. + .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\
  3788. + .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\
  3789. + .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\
  3790. + .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e)
  3791. +#define sb_data7(p1) \
  3792. + .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\
  3793. + .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\
  3794. + .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\
  3795. + .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16)
  3796. +
  3797. +// Inverse S-box data - 256 entries
  3798. +
  3799. +#define ib_data0(p1) \
  3800. + .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\
  3801. + .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\
  3802. + .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\
  3803. + .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb)
  3804. +#define ib_data1(p1) \
  3805. + .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\
  3806. + .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\
  3807. + .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\
  3808. + .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25)
  3809. +#define ib_data2(p1) \
  3810. + .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\
  3811. + .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\
  3812. + .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\
  3813. + .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84)
  3814. +#define ib_data3(p1) \
  3815. + .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\
  3816. + .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\
  3817. + .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\
  3818. + .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b)
  3819. +#define ib_data4(p1) \
  3820. + .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\
  3821. + .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\
  3822. + .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\
  3823. + .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e)
  3824. +#define ib_data5(p1) \
  3825. + .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\
  3826. + .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\
  3827. + .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\
  3828. + .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4)
  3829. +#define ib_data6(p1) \
  3830. + .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\
  3831. + .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\
  3832. + .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\
  3833. + .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef)
  3834. +#define ib_data7(p1) \
  3835. + .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\
  3836. + .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\
  3837. + .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\
  3838. + .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d)
  3839. +
  3840. +// The rcon_table (needed for the key schedule)
  3841. +//
  3842. +// Here is original Dr Brian Gladman's source code:
  3843. +// _rcon_tab:
  3844. +// %assign x 1
  3845. +// %rep 29
  3846. +// dd x
  3847. +// %assign x f2(x)
  3848. +// %endrep
  3849. +//
  3850. +// Here is precomputed output (it's more portable this way):
  3851. +
  3852. + .align ALIGN32BYTES
  3853. +aes_rcon_tab:
  3854. + .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
  3855. + .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f
  3856. + .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4
  3857. + .long 0xb3,0x7d,0xfa,0xef,0xc5
  3858. +
  3859. +// The forward xor tables
  3860. +
  3861. + .align ALIGN32BYTES
  3862. +aes_ft_tab:
  3863. + sb_data0(u0)
  3864. + sb_data1(u0)
  3865. + sb_data2(u0)
  3866. + sb_data3(u0)
  3867. + sb_data4(u0)
  3868. + sb_data5(u0)
  3869. + sb_data6(u0)
  3870. + sb_data7(u0)
  3871. +
  3872. + sb_data0(u1)
  3873. + sb_data1(u1)
  3874. + sb_data2(u1)
  3875. + sb_data3(u1)
  3876. + sb_data4(u1)
  3877. + sb_data5(u1)
  3878. + sb_data6(u1)
  3879. + sb_data7(u1)
  3880. +
  3881. + sb_data0(u2)
  3882. + sb_data1(u2)
  3883. + sb_data2(u2)
  3884. + sb_data3(u2)
  3885. + sb_data4(u2)
  3886. + sb_data5(u2)
  3887. + sb_data6(u2)
  3888. + sb_data7(u2)
  3889. +
  3890. + sb_data0(u3)
  3891. + sb_data1(u3)
  3892. + sb_data2(u3)
  3893. + sb_data3(u3)
  3894. + sb_data4(u3)
  3895. + sb_data5(u3)
  3896. + sb_data6(u3)
  3897. + sb_data7(u3)
  3898. +
  3899. + .align ALIGN32BYTES
  3900. +aes_fl_tab:
  3901. + sb_data0(w0)
  3902. + sb_data1(w0)
  3903. + sb_data2(w0)
  3904. + sb_data3(w0)
  3905. + sb_data4(w0)
  3906. + sb_data5(w0)
  3907. + sb_data6(w0)
  3908. + sb_data7(w0)
  3909. +
  3910. + sb_data0(w1)
  3911. + sb_data1(w1)
  3912. + sb_data2(w1)
  3913. + sb_data3(w1)
  3914. + sb_data4(w1)
  3915. + sb_data5(w1)
  3916. + sb_data6(w1)
  3917. + sb_data7(w1)
  3918. +
  3919. + sb_data0(w2)
  3920. + sb_data1(w2)
  3921. + sb_data2(w2)
  3922. + sb_data3(w2)
  3923. + sb_data4(w2)
  3924. + sb_data5(w2)
  3925. + sb_data6(w2)
  3926. + sb_data7(w2)
  3927. +
  3928. + sb_data0(w3)
  3929. + sb_data1(w3)
  3930. + sb_data2(w3)
  3931. + sb_data3(w3)
  3932. + sb_data4(w3)
  3933. + sb_data5(w3)
  3934. + sb_data6(w3)
  3935. + sb_data7(w3)
  3936. +
  3937. +// The inverse xor tables
  3938. +
  3939. + .align ALIGN32BYTES
  3940. +aes_it_tab:
  3941. + ib_data0(v0)
  3942. + ib_data1(v0)
  3943. + ib_data2(v0)
  3944. + ib_data3(v0)
  3945. + ib_data4(v0)
  3946. + ib_data5(v0)
  3947. + ib_data6(v0)
  3948. + ib_data7(v0)
  3949. +
  3950. + ib_data0(v1)
  3951. + ib_data1(v1)
  3952. + ib_data2(v1)
  3953. + ib_data3(v1)
  3954. + ib_data4(v1)
  3955. + ib_data5(v1)
  3956. + ib_data6(v1)
  3957. + ib_data7(v1)
  3958. +
  3959. + ib_data0(v2)
  3960. + ib_data1(v2)
  3961. + ib_data2(v2)
  3962. + ib_data3(v2)
  3963. + ib_data4(v2)
  3964. + ib_data5(v2)
  3965. + ib_data6(v2)
  3966. + ib_data7(v2)
  3967. +
  3968. + ib_data0(v3)
  3969. + ib_data1(v3)
  3970. + ib_data2(v3)
  3971. + ib_data3(v3)
  3972. + ib_data4(v3)
  3973. + ib_data5(v3)
  3974. + ib_data6(v3)
  3975. + ib_data7(v3)
  3976. +
  3977. + .align ALIGN32BYTES
  3978. +aes_il_tab:
  3979. + ib_data0(w0)
  3980. + ib_data1(w0)
  3981. + ib_data2(w0)
  3982. + ib_data3(w0)
  3983. + ib_data4(w0)
  3984. + ib_data5(w0)
  3985. + ib_data6(w0)
  3986. + ib_data7(w0)
  3987. +
  3988. + ib_data0(w1)
  3989. + ib_data1(w1)
  3990. + ib_data2(w1)
  3991. + ib_data3(w1)
  3992. + ib_data4(w1)
  3993. + ib_data5(w1)
  3994. + ib_data6(w1)
  3995. + ib_data7(w1)
  3996. +
  3997. + ib_data0(w2)
  3998. + ib_data1(w2)
  3999. + ib_data2(w2)
  4000. + ib_data3(w2)
  4001. + ib_data4(w2)
  4002. + ib_data5(w2)
  4003. + ib_data6(w2)
  4004. + ib_data7(w2)
  4005. +
  4006. + ib_data0(w3)
  4007. + ib_data1(w3)
  4008. + ib_data2(w3)
  4009. + ib_data3(w3)
  4010. + ib_data4(w3)
  4011. + ib_data5(w3)
  4012. + ib_data6(w3)
  4013. + ib_data7(w3)
  4014. +
  4015. +// The inverse mix column tables
  4016. +
  4017. + .align ALIGN32BYTES
  4018. +aes_im_tab:
  4019. + im_data0(v0)
  4020. + im_data1(v0)
  4021. + im_data2(v0)
  4022. + im_data3(v0)
  4023. + im_data4(v0)
  4024. + im_data5(v0)
  4025. + im_data6(v0)
  4026. + im_data7(v0)
  4027. +
  4028. + im_data0(v1)
  4029. + im_data1(v1)
  4030. + im_data2(v1)
  4031. + im_data3(v1)
  4032. + im_data4(v1)
  4033. + im_data5(v1)
  4034. + im_data6(v1)
  4035. + im_data7(v1)
  4036. +
  4037. + im_data0(v2)
  4038. + im_data1(v2)
  4039. + im_data2(v2)
  4040. + im_data3(v2)
  4041. + im_data4(v2)
  4042. + im_data5(v2)
  4043. + im_data6(v2)
  4044. + im_data7(v2)
  4045. +
  4046. + im_data0(v3)
  4047. + im_data1(v3)
  4048. + im_data2(v3)
  4049. + im_data3(v3)
  4050. + im_data4(v3)
  4051. + im_data5(v3)
  4052. + im_data6(v3)
  4053. + im_data7(v3)
  4054. diff -pruN linux-2.4.27_orig/drivers/misc/aes.c linux-2.4.27/drivers/misc/aes.c
  4055. --- linux-2.4.27_orig/drivers/misc/aes.c 1970-01-01 01:00:00.000000000 +0100
  4056. +++ linux-2.4.27/drivers/misc/aes.c 2004-10-25 14:20:44.730002496 +0200
  4057. @@ -0,0 +1,1479 @@
  4058. +// I retain copyright in this code but I encourage its free use provided
  4059. +// that I don't carry any responsibility for the results. I am especially
  4060. +// happy to see it used in free and open source software. If you do use
  4061. +// it I would appreciate an acknowledgement of its origin in the code or
  4062. +// the product that results and I would also appreciate knowing a little
  4063. +// about the use to which it is being put. I am grateful to Frank Yellin
  4064. +// for some ideas that are used in this implementation.
  4065. +//
  4066. +// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
  4067. +//
  4068. +// This is an implementation of the AES encryption algorithm (Rijndael)
  4069. +// designed by Joan Daemen and Vincent Rijmen. This version is designed
  4070. +// to provide both fixed and dynamic block and key lengths and can also
  4071. +// run with either big or little endian internal byte order (see aes.h).
  4072. +// It inputs block and key lengths in bytes with the legal values being
  4073. +// 16, 24 and 32.
  4074. +
  4075. +/*
  4076. + * Modified by Jari Ruusu, May 1 2001
  4077. + * - Fixed some compile warnings, code was ok but gcc warned anyway.
  4078. + * - Changed basic types: byte -> unsigned char, word -> u_int32_t
  4079. + * - Major name space cleanup: Names visible to outside now begin
  4080. + * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
  4081. + * - Removed C++ and DLL support as part of name space cleanup.
  4082. + * - Eliminated unnecessary recomputation of tables. (actual bug fix)
  4083. + * - Merged precomputed constant tables to aes.c file.
  4084. + * - Removed data alignment restrictions for portability reasons.
  4085. + * - Made block and key lengths accept bit count (128/192/256)
  4086. + * as well byte count (16/24/32).
  4087. + * - Removed all error checks. This change also eliminated the need
  4088. + * to preinitialize the context struct to zero.
  4089. + * - Removed some totally unused constants.
  4090. + */
  4091. +/*
  4092. + * Modified by Jari Ruusu, April 21 2004
  4093. + * - Added back code that avoids byte swaps on big endian boxes.
  4094. + */
  4095. +
  4096. +#include "aes.h"
  4097. +
  4098. +// CONFIGURATION OPTIONS (see also aes.h)
  4099. +//
  4100. +// 1. Define UNROLL for full loop unrolling in encryption and decryption.
  4101. +// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
  4102. +// 3. Define FIXED_TABLES for compiled rather than dynamic tables.
  4103. +// 4. Define FF_TABLES to use tables for field multiplies and inverses.
  4104. +// Do not enable this without understanding stack space requirements.
  4105. +// 5. Define ARRAYS to use arrays to hold the local state block. If this
  4106. +// is not defined, individually declared 32-bit words are used.
  4107. +// 6. Define FAST_VARIABLE if a high speed variable block implementation
  4108. +// is needed (essentially three separate fixed block size code sequences)
  4109. +// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
  4110. +// version using 1 table (2 kbytes of table space) or 4 tables (8
  4111. +// kbytes of table space) for higher speed.
  4112. +// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
  4113. +// increase by using tables for the last rounds but with more table
  4114. +// space (2 or 8 kbytes extra).
  4115. +// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
  4116. +// slower version is provided.
  4117. +// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
  4118. +// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
  4119. +
  4120. +#define UNROLL
  4121. +//#define PARTIAL_UNROLL
  4122. +
  4123. +#define FIXED_TABLES
  4124. +//#define FF_TABLES
  4125. +//#define ARRAYS
  4126. +#define FAST_VARIABLE
  4127. +
  4128. +//#define ONE_TABLE
  4129. +#define FOUR_TABLES
  4130. +
  4131. +//#define ONE_LR_TABLE
  4132. +#define FOUR_LR_TABLES
  4133. +
  4134. +//#define ONE_IM_TABLE
  4135. +#define FOUR_IM_TABLES
  4136. +
  4137. +#if defined(UNROLL) && defined (PARTIAL_UNROLL)
  4138. +#error both UNROLL and PARTIAL_UNROLL are defined
  4139. +#endif
  4140. +
  4141. +#if defined(ONE_TABLE) && defined (FOUR_TABLES)
  4142. +#error both ONE_TABLE and FOUR_TABLES are defined
  4143. +#endif
  4144. +
  4145. +#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
  4146. +#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
  4147. +#endif
  4148. +
  4149. +#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
  4150. +#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
  4151. +#endif
  4152. +
  4153. +#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
  4154. +#error an illegal block size has been specified
  4155. +#endif
  4156. +
  4157. +/* INTERNAL_BYTE_ORDER: 0=unknown, 1=little endian, 2=big endian */
  4158. +#if defined(INTERNAL_BYTE_ORDER)
  4159. +#elif defined(__i386__)||defined(__i386)||defined(__x86_64__)||defined(__x86_64)||defined(__amd64__)||defined(__amd64)||defined(__AMD64__)||defined(__AMD64)
  4160. +# define INTERNAL_BYTE_ORDER 1
  4161. +# undef DATA_ALWAYS_ALIGNED
  4162. +# define DATA_ALWAYS_ALIGNED 1 /* unaligned access is always ok */
  4163. +#elif defined(__ppc__)||defined(__ppc)||defined(__PPC__)||defined(__PPC)||defined(__powerpc__)||defined(__powerpc)||defined(__POWERPC__)||defined(__POWERPC)||defined(__PowerPC__)||defined(__PowerPC)||defined(__ppc64__)||defined(__ppc64)||defined(__PPC64__)||defined(__PPC64)||defined(__powerpc64__)||defined(__powerpc64)||defined(__s390__)||defined(__s390)
  4164. +# define INTERNAL_BYTE_ORDER 2
  4165. +# undef DATA_ALWAYS_ALIGNED
  4166. +# define DATA_ALWAYS_ALIGNED 1 /* unaligned access is always ok */
  4167. +#elif defined(__alpha__)||defined(__alpha)||defined(__ia64__)||defined(__ia64)
  4168. +# define INTERNAL_BYTE_ORDER 1
  4169. +#elif defined(__hppa__)||defined(__hppa)||defined(__HPPA__)||defined(__HPPA)||defined(__parisc__)||defined(__parisc)||defined(__sparc__)||defined(__sparc)||defined(__sparc_v9__)||defined(__sparc_v9)||defined(__sparc64__)||defined(__sparc64)||defined(__mc68000__)||defined(__mc68000)
  4170. +# define INTERNAL_BYTE_ORDER 2
  4171. +#elif defined(CONFIGURE_DETECTS_BYTE_ORDER)
  4172. +# if WORDS_BIGENDIAN
  4173. +# define INTERNAL_BYTE_ORDER 2
  4174. +# else
  4175. +# define INTERNAL_BYTE_ORDER 1
  4176. +# endif
  4177. +#elif defined(__linux__) && defined(__KERNEL__)
  4178. +# include <asm/byteorder.h>
  4179. +# if defined(__BIG_ENDIAN)
  4180. +# define INTERNAL_BYTE_ORDER 2
  4181. +# else
  4182. +# define INTERNAL_BYTE_ORDER 1
  4183. +# endif
  4184. +#else
  4185. +# include <sys/param.h>
  4186. +# if (defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && (BYTE_ORDER == LITTLE_ENDIAN)) || (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN))
  4187. +# define INTERNAL_BYTE_ORDER 1
  4188. +# elif WORDS_BIGENDIAN || defined(__BIG_ENDIAN__) || (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)) || (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN))
  4189. +# define INTERNAL_BYTE_ORDER 2
  4190. +# else
  4191. +# define INTERNAL_BYTE_ORDER 0
  4192. +# endif
  4193. +#endif
  4194. +
  4195. +#if defined(DATA_ALWAYS_ALIGNED) && (INTERNAL_BYTE_ORDER > 0)
  4196. +# define word_in(x) *(u_int32_t*)(x)
  4197. +# define word_out(x,v) *(u_int32_t*)(x) = (v)
  4198. +#elif defined(__linux__) && defined(__KERNEL__)
  4199. +# include <asm/unaligned.h>
  4200. +# define word_in(x) get_unaligned((u_int32_t*)(x))
  4201. +# define word_out(x,v) put_unaligned((v),(u_int32_t*)(x))
  4202. +#else
  4203. +/* unknown endianness and/or unable to handle unaligned data */
  4204. +# undef INTERNAL_BYTE_ORDER
  4205. +# define INTERNAL_BYTE_ORDER 1
  4206. +# define word_in(x) ((u_int32_t)(((unsigned char *)(x))[0])|((u_int32_t)(((unsigned char *)(x))[1])<<8)|((u_int32_t)(((unsigned char *)(x))[2])<<16)|((u_int32_t)(((unsigned char *)(x))[3])<<24))
  4207. +# define word_out(x,v) ((unsigned char *)(x))[0]=(v),((unsigned char *)(x))[1]=((v)>>8),((unsigned char *)(x))[2]=((v)>>16),((unsigned char *)(x))[3]=((v)>>24)
  4208. +#endif
  4209. +
  4210. +// upr(x,n): rotates bytes within words by n positions, moving bytes
  4211. +// to higher index positions with wrap around into low positions
  4212. +// ups(x,n): moves bytes by n positions to higher index positions in
  4213. +// words but without wrap around
  4214. +// bval(x,n): extracts a byte from a word
  4215. +
  4216. +#if (INTERNAL_BYTE_ORDER < 2)
  4217. +/* little endian */
  4218. +#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
  4219. +#define ups(x,n) ((x) << 8 * (n))
  4220. +#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
  4221. +#define bytes2word(b0, b1, b2, b3) \
  4222. + ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
  4223. +#else
  4224. +/* big endian */
  4225. +#define upr(x,n) (((x) >> 8 * (n)) | ((x) << (32 - 8 * (n))))
  4226. +#define ups(x,n) ((x) >> 8 * (n)))
  4227. +#define bval(x,n) ((unsigned char)((x) >> (24 - 8 * (n))))
  4228. +#define bytes2word(b0, b1, b2, b3) \
  4229. + ((u_int32_t)(b0) << 24 | (u_int32_t)(b1) << 16 | (u_int32_t)(b2) << 8 | (b3))
  4230. +#endif
  4231. +
  4232. +// Disable at least some poor combinations of options
  4233. +
  4234. +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
  4235. +#define FIXED_TABLES
  4236. +#undef UNROLL
  4237. +#undef ONE_LR_TABLE
  4238. +#undef FOUR_LR_TABLES
  4239. +#undef ONE_IM_TABLE
  4240. +#undef FOUR_IM_TABLES
  4241. +#elif !defined(FOUR_TABLES)
  4242. +#ifdef FOUR_LR_TABLES
  4243. +#undef FOUR_LR_TABLES
  4244. +#define ONE_LR_TABLE
  4245. +#endif
  4246. +#ifdef FOUR_IM_TABLES
  4247. +#undef FOUR_IM_TABLES
  4248. +#define ONE_IM_TABLE
  4249. +#endif
  4250. +#elif !defined(AES_BLOCK_SIZE)
  4251. +#if defined(UNROLL)
  4252. +#define PARTIAL_UNROLL
  4253. +#undef UNROLL
  4254. +#endif
  4255. +#endif
  4256. +
  4257. +// the finite field modular polynomial and elements
  4258. +
  4259. +#define ff_poly 0x011b
  4260. +#define ff_hi 0x80
  4261. +
  4262. +// multiply four bytes in GF(2^8) by 'x' {02} in parallel
  4263. +
  4264. +#define m1 0x80808080
  4265. +#define m2 0x7f7f7f7f
  4266. +#define m3 0x0000001b
  4267. +#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
  4268. +
  4269. +// The following defines provide alternative definitions of FFmulX that might
  4270. +// give improved performance if a fast 32-bit multiply is not available. Note
  4271. +// that a temporary variable u needs to be defined where FFmulX is used.
  4272. +
  4273. +// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
  4274. +// #define m4 0x1b1b1b1b
  4275. +// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
  4276. +
  4277. +// perform column mix operation on four bytes in parallel
  4278. +
  4279. +#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
  4280. +
  4281. +#if defined(FIXED_TABLES)
  4282. +
  4283. +// the S-Box table
  4284. +
  4285. +static const unsigned char s_box[256] =
  4286. +{
  4287. + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
  4288. + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
  4289. + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
  4290. + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
  4291. + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
  4292. + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
  4293. + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
  4294. + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
  4295. + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
  4296. + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
  4297. + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
  4298. + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
  4299. + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
  4300. + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
  4301. + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
  4302. + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
  4303. + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
  4304. + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
  4305. + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
  4306. + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
  4307. + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
  4308. + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
  4309. + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
  4310. + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
  4311. + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
  4312. + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
  4313. + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
  4314. + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
  4315. + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
  4316. + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
  4317. + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
  4318. + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
  4319. +};
  4320. +
  4321. +// the inverse S-Box table
  4322. +
  4323. +static const unsigned char inv_s_box[256] =
  4324. +{
  4325. + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
  4326. + 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
  4327. + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
  4328. + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
  4329. + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
  4330. + 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
  4331. + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
  4332. + 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
  4333. + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
  4334. + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
  4335. + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
  4336. + 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
  4337. + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
  4338. + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
  4339. + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
  4340. + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
  4341. + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
  4342. + 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
  4343. + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
  4344. + 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
  4345. + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
  4346. + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
  4347. + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
  4348. + 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
  4349. + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
  4350. + 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
  4351. + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
  4352. + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
  4353. + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
  4354. + 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
  4355. + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
  4356. + 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
  4357. +};
  4358. +
  4359. +// used to ensure table is generated in the right format
  4360. +// depending on the internal byte order required
  4361. +
  4362. +#if (INTERNAL_BYTE_ORDER < 2)
  4363. +/* little endian */
  4364. +#define w0(p) 0x000000##p
  4365. +#else
  4366. +/* big endian */
  4367. +#define w0(p) 0x##p##000000
  4368. +#endif
  4369. +
  4370. +// Number of elements required in this table for different
  4371. +// block and key lengths is:
  4372. +//
  4373. +// Nk = 4 6 8
  4374. +// ----------
  4375. +// Nb = 4 | 10 8 7
  4376. +// 6 | 19 12 11
  4377. +// 8 | 29 19 14
  4378. +//
  4379. +// this table can be a table of bytes if the key schedule
  4380. +// code is adjusted accordingly
  4381. +
  4382. +static const u_int32_t rcon_tab[29] =
  4383. +{
  4384. + w0(01), w0(02), w0(04), w0(08),
  4385. + w0(10), w0(20), w0(40), w0(80),
  4386. + w0(1b), w0(36), w0(6c), w0(d8),
  4387. + w0(ab), w0(4d), w0(9a), w0(2f),
  4388. + w0(5e), w0(bc), w0(63), w0(c6),
  4389. + w0(97), w0(35), w0(6a), w0(d4),
  4390. + w0(b3), w0(7d), w0(fa), w0(ef),
  4391. + w0(c5)
  4392. +};
  4393. +
  4394. +#undef w0
  4395. +
  4396. +// used to ensure table is generated in the right format
  4397. +// depending on the internal byte order required
  4398. +
  4399. +#if (INTERNAL_BYTE_ORDER < 2)
  4400. +/* little endian */
  4401. +#define r0(p,q,r,s) 0x##p##q##r##s
  4402. +#define r1(p,q,r,s) 0x##q##r##s##p
  4403. +#define r2(p,q,r,s) 0x##r##s##p##q
  4404. +#define r3(p,q,r,s) 0x##s##p##q##r
  4405. +#define w0(p) 0x000000##p
  4406. +#define w1(p) 0x0000##p##00
  4407. +#define w2(p) 0x00##p##0000
  4408. +#define w3(p) 0x##p##000000
  4409. +#else
  4410. +/* big endian */
  4411. +#define r0(p,q,r,s) 0x##s##r##q##p
  4412. +#define r1(p,q,r,s) 0x##p##s##r##q
  4413. +#define r2(p,q,r,s) 0x##q##p##s##r
  4414. +#define r3(p,q,r,s) 0x##r##q##p##s
  4415. +#define w0(p) 0x##p##000000
  4416. +#define w1(p) 0x00##p##0000
  4417. +#define w2(p) 0x0000##p##00
  4418. +#define w3(p) 0x000000##p
  4419. +#endif
  4420. +
  4421. +#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
  4422. +
  4423. +// data for forward tables (other than last round)
  4424. +
  4425. +#define f_table \
  4426. + r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
  4427. + r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
  4428. + r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
  4429. + r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
  4430. + r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
  4431. + r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
  4432. + r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
  4433. + r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
  4434. + r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
  4435. + r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
  4436. + r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
  4437. + r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
  4438. + r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
  4439. + r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
  4440. + r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
  4441. + r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
  4442. + r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
  4443. + r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
  4444. + r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
  4445. + r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
  4446. + r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
  4447. + r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
  4448. + r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
  4449. + r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
  4450. + r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
  4451. + r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
  4452. + r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
  4453. + r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
  4454. + r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
  4455. + r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
  4456. + r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
  4457. + r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
  4458. + r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
  4459. + r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
  4460. + r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
  4461. + r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
  4462. + r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
  4463. + r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
  4464. + r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
  4465. + r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
  4466. + r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
  4467. + r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
  4468. + r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
  4469. + r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
  4470. + r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
  4471. + r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
  4472. + r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
  4473. + r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
  4474. + r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
  4475. + r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
  4476. + r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
  4477. + r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
  4478. + r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
  4479. + r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
  4480. + r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
  4481. + r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
  4482. + r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
  4483. + r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
  4484. + r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
  4485. + r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
  4486. + r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
  4487. + r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
  4488. + r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
  4489. + r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
  4490. +
  4491. +// data for inverse tables (other than last round)
  4492. +
  4493. +#define i_table \
  4494. + r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
  4495. + r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
  4496. + r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
  4497. + r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
  4498. + r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
  4499. + r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
  4500. + r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
  4501. + r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
  4502. + r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
  4503. + r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
  4504. + r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
  4505. + r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
  4506. + r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
  4507. + r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
  4508. + r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
  4509. + r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
  4510. + r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
  4511. + r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
  4512. + r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
  4513. + r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
  4514. + r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
  4515. + r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
  4516. + r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
  4517. + r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
  4518. + r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
  4519. + r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
  4520. + r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
  4521. + r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
  4522. + r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
  4523. + r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
  4524. + r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
  4525. + r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
  4526. + r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
  4527. + r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
  4528. + r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
  4529. + r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
  4530. + r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
  4531. + r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
  4532. + r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
  4533. + r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
  4534. + r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
  4535. + r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
  4536. + r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
  4537. + r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
  4538. + r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
  4539. + r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
  4540. + r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
  4541. + r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
  4542. + r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
  4543. + r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
  4544. + r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
  4545. + r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
  4546. + r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
  4547. + r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
  4548. + r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
  4549. + r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
  4550. + r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
  4551. + r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
  4552. + r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
  4553. + r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
  4554. + r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
  4555. + r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
  4556. + r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
  4557. + r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
  4558. +
  4559. +// generate the required tables in the desired endian format
  4560. +
  4561. +#undef r
  4562. +#define r r0
  4563. +
  4564. +#if defined(ONE_TABLE)
  4565. +static const u_int32_t ft_tab[256] =
  4566. + { f_table };
  4567. +#elif defined(FOUR_TABLES)
  4568. +static const u_int32_t ft_tab[4][256] =
  4569. +{ { f_table },
  4570. +#undef r
  4571. +#define r r1
  4572. + { f_table },
  4573. +#undef r
  4574. +#define r r2
  4575. + { f_table },
  4576. +#undef r
  4577. +#define r r3
  4578. + { f_table }
  4579. +};
  4580. +#endif
  4581. +
  4582. +#undef r
  4583. +#define r r0
  4584. +#if defined(ONE_TABLE)
  4585. +static const u_int32_t it_tab[256] =
  4586. + { i_table };
  4587. +#elif defined(FOUR_TABLES)
  4588. +static const u_int32_t it_tab[4][256] =
  4589. +{ { i_table },
  4590. +#undef r
  4591. +#define r r1
  4592. + { i_table },
  4593. +#undef r
  4594. +#define r r2
  4595. + { i_table },
  4596. +#undef r
  4597. +#define r r3
  4598. + { i_table }
  4599. +};
  4600. +#endif
  4601. +
  4602. +#endif
  4603. +
  4604. +#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
  4605. +
  4606. +// data for inverse tables (last round)
  4607. +
  4608. +#define li_table \
  4609. + w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
  4610. + w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
  4611. + w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
  4612. + w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
  4613. + w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
  4614. + w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
  4615. + w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
  4616. + w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
  4617. + w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
  4618. + w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
  4619. + w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
  4620. + w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
  4621. + w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
  4622. + w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
  4623. + w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
  4624. + w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
  4625. + w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
  4626. + w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
  4627. + w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
  4628. + w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
  4629. + w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
  4630. + w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
  4631. + w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
  4632. + w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
  4633. + w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
  4634. + w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
  4635. + w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
  4636. + w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
  4637. + w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
  4638. + w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
  4639. + w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
  4640. + w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
  4641. +
  4642. +// generate the required tables in the desired endian format
  4643. +
  4644. +#undef r
  4645. +#define r(p,q,r,s) w0(q)
  4646. +#if defined(ONE_LR_TABLE)
  4647. +static const u_int32_t fl_tab[256] =
  4648. + { f_table };
  4649. +#elif defined(FOUR_LR_TABLES)
  4650. +static const u_int32_t fl_tab[4][256] =
  4651. +{ { f_table },
  4652. +#undef r
  4653. +#define r(p,q,r,s) w1(q)
  4654. + { f_table },
  4655. +#undef r
  4656. +#define r(p,q,r,s) w2(q)
  4657. + { f_table },
  4658. +#undef r
  4659. +#define r(p,q,r,s) w3(q)
  4660. + { f_table }
  4661. +};
  4662. +#endif
  4663. +
  4664. +#undef w
  4665. +#define w w0
  4666. +#if defined(ONE_LR_TABLE)
  4667. +static const u_int32_t il_tab[256] =
  4668. + { li_table };
  4669. +#elif defined(FOUR_LR_TABLES)
  4670. +static const u_int32_t il_tab[4][256] =
  4671. +{ { li_table },
  4672. +#undef w
  4673. +#define w w1
  4674. + { li_table },
  4675. +#undef w
  4676. +#define w w2
  4677. + { li_table },
  4678. +#undef w
  4679. +#define w w3
  4680. + { li_table }
  4681. +};
  4682. +#endif
  4683. +
  4684. +#endif
  4685. +
  4686. +#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
  4687. +
  4688. +#define m_table \
  4689. + r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
  4690. + r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
  4691. + r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
  4692. + r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
  4693. + r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
  4694. + r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
  4695. + r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
  4696. + r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
  4697. + r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
  4698. + r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
  4699. + r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
  4700. + r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
  4701. + r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
  4702. + r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
  4703. + r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
  4704. + r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
  4705. + r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
  4706. + r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
  4707. + r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
  4708. + r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
  4709. + r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
  4710. + r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
  4711. + r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
  4712. + r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
  4713. + r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
  4714. + r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
  4715. + r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
  4716. + r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
  4717. + r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
  4718. + r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
  4719. + r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
  4720. + r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
  4721. + r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
  4722. + r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
  4723. + r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
  4724. + r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
  4725. + r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
  4726. + r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
  4727. + r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
  4728. + r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
  4729. + r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
  4730. + r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
  4731. + r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
  4732. + r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
  4733. + r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
  4734. + r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
  4735. + r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
  4736. + r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
  4737. + r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
  4738. + r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
  4739. + r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
  4740. + r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
  4741. + r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
  4742. + r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
  4743. + r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
  4744. + r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
  4745. + r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
  4746. + r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
  4747. + r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
  4748. + r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
  4749. + r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
  4750. + r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
  4751. + r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
  4752. + r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
  4753. +
  4754. +#undef r
  4755. +#define r r0
  4756. +
  4757. +#if defined(ONE_IM_TABLE)
  4758. +static const u_int32_t im_tab[256] =
  4759. + { m_table };
  4760. +#elif defined(FOUR_IM_TABLES)
  4761. +static const u_int32_t im_tab[4][256] =
  4762. +{ { m_table },
  4763. +#undef r
  4764. +#define r r1
  4765. + { m_table },
  4766. +#undef r
  4767. +#define r r2
  4768. + { m_table },
  4769. +#undef r
  4770. +#define r r3
  4771. + { m_table }
  4772. +};
  4773. +#endif
  4774. +
  4775. +#endif
  4776. +
  4777. +#else
  4778. +
  4779. +static int tab_gen = 0;
  4780. +
  4781. +static unsigned char s_box[256]; // the S box
  4782. +static unsigned char inv_s_box[256]; // the inverse S box
  4783. +static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
  4784. +
  4785. +#if defined(ONE_TABLE)
  4786. +static u_int32_t ft_tab[256];
  4787. +static u_int32_t it_tab[256];
  4788. +#elif defined(FOUR_TABLES)
  4789. +static u_int32_t ft_tab[4][256];
  4790. +static u_int32_t it_tab[4][256];
  4791. +#endif
  4792. +
  4793. +#if defined(ONE_LR_TABLE)
  4794. +static u_int32_t fl_tab[256];
  4795. +static u_int32_t il_tab[256];
  4796. +#elif defined(FOUR_LR_TABLES)
  4797. +static u_int32_t fl_tab[4][256];
  4798. +static u_int32_t il_tab[4][256];
  4799. +#endif
  4800. +
  4801. +#if defined(ONE_IM_TABLE)
  4802. +static u_int32_t im_tab[256];
  4803. +#elif defined(FOUR_IM_TABLES)
  4804. +static u_int32_t im_tab[4][256];
  4805. +#endif
  4806. +
  4807. +// Generate the tables for the dynamic table option
  4808. +
  4809. +#if !defined(FF_TABLES)
  4810. +
  4811. +// It will generally be sensible to use tables to compute finite
  4812. +// field multiplies and inverses but where memory is scarse this
  4813. +// code might sometimes be better.
  4814. +
  4815. +// return 2 ^ (n - 1) where n is the bit number of the highest bit
  4816. +// set in x with x in the range 1 < x < 0x00000200. This form is
  4817. +// used so that locals within FFinv can be bytes rather than words
  4818. +
  4819. +static unsigned char hibit(const u_int32_t x)
  4820. +{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
  4821. +
  4822. + r |= (r >> 2);
  4823. + r |= (r >> 4);
  4824. + return (r + 1) >> 1;
  4825. +}
  4826. +
  4827. +// return the inverse of the finite field element x
  4828. +
  4829. +static unsigned char FFinv(const unsigned char x)
  4830. +{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
  4831. +
  4832. + if(x < 2) return x;
  4833. +
  4834. + for(;;)
  4835. + {
  4836. + if(!n1) return v1;
  4837. +
  4838. + while(n2 >= n1)
  4839. + {
  4840. + n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
  4841. + }
  4842. +
  4843. + if(!n2) return v2;
  4844. +
  4845. + while(n1 >= n2)
  4846. + {
  4847. + n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
  4848. + }
  4849. + }
  4850. +}
  4851. +
  4852. +// define the finite field multiplies required for Rijndael
  4853. +
  4854. +#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
  4855. +#define FFmul03(x) ((x) ^ FFmul02(x))
  4856. +#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
  4857. +#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
  4858. +#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
  4859. +#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
  4860. +
  4861. +#else
  4862. +
  4863. +#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
  4864. +
  4865. +#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
  4866. +#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
  4867. +#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
  4868. +#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
  4869. +#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
  4870. +#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
  4871. +
  4872. +#endif
  4873. +
  4874. +// The forward and inverse affine transformations used in the S-box
  4875. +
  4876. +#define fwd_affine(x) \
  4877. + (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
  4878. +
  4879. +#define inv_affine(x) \
  4880. + (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
  4881. +
  4882. +static void gen_tabs(void)
  4883. +{ u_int32_t i, w;
  4884. +
  4885. +#if defined(FF_TABLES)
  4886. +
  4887. + unsigned char pow[512], log[256];
  4888. +
  4889. + // log and power tables for GF(2^8) finite field with
  4890. + // 0x011b as modular polynomial - the simplest primitive
  4891. + // root is 0x03, used here to generate the tables
  4892. +
  4893. + i = 0; w = 1;
  4894. + do
  4895. + {
  4896. + pow[i] = (unsigned char)w;
  4897. + pow[i + 255] = (unsigned char)w;
  4898. + log[w] = (unsigned char)i++;
  4899. + w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
  4900. + }
  4901. + while (w != 1);
  4902. +
  4903. +#endif
  4904. +
  4905. + for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
  4906. + {
  4907. + rcon_tab[i] = bytes2word(w, 0, 0, 0);
  4908. + w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
  4909. + }
  4910. +
  4911. + for(i = 0; i < 256; ++i)
  4912. + { unsigned char b;
  4913. +
  4914. + s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
  4915. +
  4916. + w = bytes2word(b, 0, 0, 0);
  4917. +#if defined(ONE_LR_TABLE)
  4918. + fl_tab[i] = w;
  4919. +#elif defined(FOUR_LR_TABLES)
  4920. + fl_tab[0][i] = w;
  4921. + fl_tab[1][i] = upr(w,1);
  4922. + fl_tab[2][i] = upr(w,2);
  4923. + fl_tab[3][i] = upr(w,3);
  4924. +#endif
  4925. + w = bytes2word(FFmul02(b), b, b, FFmul03(b));
  4926. +#if defined(ONE_TABLE)
  4927. + ft_tab[i] = w;
  4928. +#elif defined(FOUR_TABLES)
  4929. + ft_tab[0][i] = w;
  4930. + ft_tab[1][i] = upr(w,1);
  4931. + ft_tab[2][i] = upr(w,2);
  4932. + ft_tab[3][i] = upr(w,3);
  4933. +#endif
  4934. + inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
  4935. +
  4936. + w = bytes2word(b, 0, 0, 0);
  4937. +#if defined(ONE_LR_TABLE)
  4938. + il_tab[i] = w;
  4939. +#elif defined(FOUR_LR_TABLES)
  4940. + il_tab[0][i] = w;
  4941. + il_tab[1][i] = upr(w,1);
  4942. + il_tab[2][i] = upr(w,2);
  4943. + il_tab[3][i] = upr(w,3);
  4944. +#endif
  4945. + w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
  4946. +#if defined(ONE_TABLE)
  4947. + it_tab[i] = w;
  4948. +#elif defined(FOUR_TABLES)
  4949. + it_tab[0][i] = w;
  4950. + it_tab[1][i] = upr(w,1);
  4951. + it_tab[2][i] = upr(w,2);
  4952. + it_tab[3][i] = upr(w,3);
  4953. +#endif
  4954. +#if defined(ONE_IM_TABLE)
  4955. + im_tab[b] = w;
  4956. +#elif defined(FOUR_IM_TABLES)
  4957. + im_tab[0][b] = w;
  4958. + im_tab[1][b] = upr(w,1);
  4959. + im_tab[2][b] = upr(w,2);
  4960. + im_tab[3][b] = upr(w,3);
  4961. +#endif
  4962. +
  4963. + }
  4964. +}
  4965. +
  4966. +#endif
  4967. +
  4968. +#define no_table(x,box,vf,rf,c) bytes2word( \
  4969. + box[bval(vf(x,0,c),rf(0,c))], \
  4970. + box[bval(vf(x,1,c),rf(1,c))], \
  4971. + box[bval(vf(x,2,c),rf(2,c))], \
  4972. + box[bval(vf(x,3,c),rf(3,c))])
  4973. +
  4974. +#define one_table(x,op,tab,vf,rf,c) \
  4975. + ( tab[bval(vf(x,0,c),rf(0,c))] \
  4976. + ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
  4977. + ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
  4978. + ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
  4979. +
  4980. +#define four_tables(x,tab,vf,rf,c) \
  4981. + ( tab[0][bval(vf(x,0,c),rf(0,c))] \
  4982. + ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
  4983. + ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
  4984. + ^ tab[3][bval(vf(x,3,c),rf(3,c))])
  4985. +
  4986. +#define vf1(x,r,c) (x)
  4987. +#define rf1(r,c) (r)
  4988. +#define rf2(r,c) ((r-c)&3)
  4989. +
  4990. +#if defined(FOUR_LR_TABLES)
  4991. +#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
  4992. +#elif defined(ONE_LR_TABLE)
  4993. +#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
  4994. +#else
  4995. +#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
  4996. +#endif
  4997. +
  4998. +#if defined(FOUR_IM_TABLES)
  4999. +#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
  5000. +#elif defined(ONE_IM_TABLE)
  5001. +#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
  5002. +#else
  5003. +#define inv_mcol(x) \
  5004. + (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
  5005. + f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
  5006. +#endif
  5007. +
  5008. +// Subroutine to set the block size (if variable) in bytes, legal
  5009. +// values being 16, 24 and 32.
  5010. +
  5011. +#if defined(AES_BLOCK_SIZE)
  5012. +#define nc (AES_BLOCK_SIZE / 4)
  5013. +#else
  5014. +#define nc (cx->aes_Ncol)
  5015. +
  5016. +void aes_set_blk(aes_context *cx, int n_bytes)
  5017. +{
  5018. +#if !defined(FIXED_TABLES)
  5019. + if(!tab_gen) { gen_tabs(); tab_gen = 1; }
  5020. +#endif
  5021. +
  5022. + switch(n_bytes) {
  5023. + case 32: /* bytes */
  5024. + case 256: /* bits */
  5025. + nc = 8;
  5026. + break;
  5027. + case 24: /* bytes */
  5028. + case 192: /* bits */
  5029. + nc = 6;
  5030. + break;
  5031. + case 16: /* bytes */
  5032. + case 128: /* bits */
  5033. + default:
  5034. + nc = 4;
  5035. + break;
  5036. + }
  5037. +}
  5038. +
  5039. +#endif
  5040. +
  5041. +// Initialise the key schedule from the user supplied key. The key
  5042. +// length is now specified in bytes - 16, 24 or 32 as appropriate.
  5043. +// This corresponds to bit lengths of 128, 192 and 256 bits, and
  5044. +// to Nk values of 4, 6 and 8 respectively.
  5045. +
  5046. +#define mx(t,f) (*t++ = inv_mcol(*f),f++)
  5047. +#define cp(t,f) *t++ = *f++
  5048. +
  5049. +#if AES_BLOCK_SIZE == 16
  5050. +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
  5051. +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
  5052. +#elif AES_BLOCK_SIZE == 24
  5053. +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
  5054. + cp(d,s); cp(d,s)
  5055. +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
  5056. + mx(d,s); mx(d,s)
  5057. +#elif AES_BLOCK_SIZE == 32
  5058. +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
  5059. + cp(d,s); cp(d,s); cp(d,s); cp(d,s)
  5060. +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
  5061. + mx(d,s); mx(d,s); mx(d,s); mx(d,s)
  5062. +#else
  5063. +
  5064. +#define cpy(d,s) \
  5065. +switch(nc) \
  5066. +{ case 8: cp(d,s); cp(d,s); \
  5067. + case 6: cp(d,s); cp(d,s); \
  5068. + case 4: cp(d,s); cp(d,s); \
  5069. + cp(d,s); cp(d,s); \
  5070. +}
  5071. +
  5072. +#define mix(d,s) \
  5073. +switch(nc) \
  5074. +{ case 8: mx(d,s); mx(d,s); \
  5075. + case 6: mx(d,s); mx(d,s); \
  5076. + case 4: mx(d,s); mx(d,s); \
  5077. + mx(d,s); mx(d,s); \
  5078. +}
  5079. +
  5080. +#endif
  5081. +
  5082. +void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
  5083. +{ u_int32_t *kf, *kt, rci;
  5084. +
  5085. +#if !defined(FIXED_TABLES)
  5086. + if(!tab_gen) { gen_tabs(); tab_gen = 1; }
  5087. +#endif
  5088. +
  5089. + switch(n_bytes) {
  5090. + case 32: /* bytes */
  5091. + case 256: /* bits */
  5092. + cx->aes_Nkey = 8;
  5093. + break;
  5094. + case 24: /* bytes */
  5095. + case 192: /* bits */
  5096. + cx->aes_Nkey = 6;
  5097. + break;
  5098. + case 16: /* bytes */
  5099. + case 128: /* bits */
  5100. + default:
  5101. + cx->aes_Nkey = 4;
  5102. + break;
  5103. + }
  5104. +
  5105. + cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6;
  5106. +
  5107. + cx->aes_e_key[0] = word_in(in_key );
  5108. + cx->aes_e_key[1] = word_in(in_key + 4);
  5109. + cx->aes_e_key[2] = word_in(in_key + 8);
  5110. + cx->aes_e_key[3] = word_in(in_key + 12);
  5111. +
  5112. + kf = cx->aes_e_key;
  5113. + kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey;
  5114. + rci = 0;
  5115. +
  5116. + switch(cx->aes_Nkey)
  5117. + {
  5118. + case 4: do
  5119. + { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
  5120. + kf[5] = kf[1] ^ kf[4];
  5121. + kf[6] = kf[2] ^ kf[5];
  5122. + kf[7] = kf[3] ^ kf[6];
  5123. + kf += 4;
  5124. + }
  5125. + while(kf < kt);
  5126. + break;
  5127. +
  5128. + case 6: cx->aes_e_key[4] = word_in(in_key + 16);
  5129. + cx->aes_e_key[5] = word_in(in_key + 20);
  5130. + do
  5131. + { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
  5132. + kf[ 7] = kf[1] ^ kf[ 6];
  5133. + kf[ 8] = kf[2] ^ kf[ 7];
  5134. + kf[ 9] = kf[3] ^ kf[ 8];
  5135. + kf[10] = kf[4] ^ kf[ 9];
  5136. + kf[11] = kf[5] ^ kf[10];
  5137. + kf += 6;
  5138. + }
  5139. + while(kf < kt);
  5140. + break;
  5141. +
  5142. + case 8: cx->aes_e_key[4] = word_in(in_key + 16);
  5143. + cx->aes_e_key[5] = word_in(in_key + 20);
  5144. + cx->aes_e_key[6] = word_in(in_key + 24);
  5145. + cx->aes_e_key[7] = word_in(in_key + 28);
  5146. + do
  5147. + { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
  5148. + kf[ 9] = kf[1] ^ kf[ 8];
  5149. + kf[10] = kf[2] ^ kf[ 9];
  5150. + kf[11] = kf[3] ^ kf[10];
  5151. + kf[12] = kf[4] ^ ls_box(kf[11],0);
  5152. + kf[13] = kf[5] ^ kf[12];
  5153. + kf[14] = kf[6] ^ kf[13];
  5154. + kf[15] = kf[7] ^ kf[14];
  5155. + kf += 8;
  5156. + }
  5157. + while (kf < kt);
  5158. + break;
  5159. + }
  5160. +
  5161. + if(!f)
  5162. + { u_int32_t i;
  5163. +
  5164. + kt = cx->aes_d_key + nc * cx->aes_Nrnd;
  5165. + kf = cx->aes_e_key;
  5166. +
  5167. + cpy(kt, kf); kt -= 2 * nc;
  5168. +
  5169. + for(i = 1; i < cx->aes_Nrnd; ++i)
  5170. + {
  5171. +#if defined(ONE_TABLE) || defined(FOUR_TABLES)
  5172. +#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
  5173. + u_int32_t f2, f4, f8, f9;
  5174. +#endif
  5175. + mix(kt, kf);
  5176. +#else
  5177. + cpy(kt, kf);
  5178. +#endif
  5179. + kt -= 2 * nc;
  5180. + }
  5181. +
  5182. + cpy(kt, kf);
  5183. + }
  5184. +}
  5185. +
  5186. +// y = output word, x = input word, r = row, c = column
  5187. +// for r = 0, 1, 2 and 3 = column accessed for row r
  5188. +
  5189. +#if defined(ARRAYS)
  5190. +#define s(x,c) x[c]
  5191. +#else
  5192. +#define s(x,c) x##c
  5193. +#endif
  5194. +
  5195. +// I am grateful to Frank Yellin for the following constructions
  5196. +// which, given the column (c) of the output state variable that
  5197. +// is being computed, return the input state variables which are
  5198. +// needed for each row (r) of the state
  5199. +
  5200. +// For the fixed block size options, compilers reduce these two
  5201. +// expressions to fixed variable references. For variable block
  5202. +// size code conditional clauses will sometimes be returned
  5203. +
  5204. +#define unused 77 // Sunset Strip
  5205. +
  5206. +#define fwd_var(x,r,c) \
  5207. + ( r==0 ? \
  5208. + ( c==0 ? s(x,0) \
  5209. + : c==1 ? s(x,1) \
  5210. + : c==2 ? s(x,2) \
  5211. + : c==3 ? s(x,3) \
  5212. + : c==4 ? s(x,4) \
  5213. + : c==5 ? s(x,5) \
  5214. + : c==6 ? s(x,6) \
  5215. + : s(x,7)) \
  5216. + : r==1 ? \
  5217. + ( c==0 ? s(x,1) \
  5218. + : c==1 ? s(x,2) \
  5219. + : c==2 ? s(x,3) \
  5220. + : c==3 ? nc==4 ? s(x,0) : s(x,4) \
  5221. + : c==4 ? s(x,5) \
  5222. + : c==5 ? nc==8 ? s(x,6) : s(x,0) \
  5223. + : c==6 ? s(x,7) \
  5224. + : s(x,0)) \
  5225. + : r==2 ? \
  5226. + ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
  5227. + : c==1 ? nc==8 ? s(x,4) : s(x,3) \
  5228. + : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
  5229. + : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
  5230. + : c==4 ? nc==8 ? s(x,7) : s(x,0) \
  5231. + : c==5 ? nc==8 ? s(x,0) : s(x,1) \
  5232. + : c==6 ? s(x,1) \
  5233. + : s(x,2)) \
  5234. + : \
  5235. + ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
  5236. + : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
  5237. + : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
  5238. + : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
  5239. + : c==4 ? nc==8 ? s(x,0) : s(x,1) \
  5240. + : c==5 ? nc==8 ? s(x,1) : s(x,2) \
  5241. + : c==6 ? s(x,2) \
  5242. + : s(x,3)))
  5243. +
  5244. +#define inv_var(x,r,c) \
  5245. + ( r==0 ? \
  5246. + ( c==0 ? s(x,0) \
  5247. + : c==1 ? s(x,1) \
  5248. + : c==2 ? s(x,2) \
  5249. + : c==3 ? s(x,3) \
  5250. + : c==4 ? s(x,4) \
  5251. + : c==5 ? s(x,5) \
  5252. + : c==6 ? s(x,6) \
  5253. + : s(x,7)) \
  5254. + : r==1 ? \
  5255. + ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
  5256. + : c==1 ? s(x,0) \
  5257. + : c==2 ? s(x,1) \
  5258. + : c==3 ? s(x,2) \
  5259. + : c==4 ? s(x,3) \
  5260. + : c==5 ? s(x,4) \
  5261. + : c==6 ? s(x,5) \
  5262. + : s(x,6)) \
  5263. + : r==2 ? \
  5264. + ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
  5265. + : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
  5266. + : c==2 ? nc==8 ? s(x,7) : s(x,0) \
  5267. + : c==3 ? nc==8 ? s(x,0) : s(x,1) \
  5268. + : c==4 ? nc==8 ? s(x,1) : s(x,2) \
  5269. + : c==5 ? nc==8 ? s(x,2) : s(x,3) \
  5270. + : c==6 ? s(x,3) \
  5271. + : s(x,4)) \
  5272. + : \
  5273. + ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
  5274. + : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
  5275. + : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
  5276. + : c==3 ? nc==8 ? s(x,7) : s(x,0) \
  5277. + : c==4 ? nc==8 ? s(x,0) : s(x,1) \
  5278. + : c==5 ? nc==8 ? s(x,1) : s(x,2) \
  5279. + : c==6 ? s(x,2) \
  5280. + : s(x,3)))
  5281. +
  5282. +#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c]
  5283. +#define so(y,x,c) word_out(y + 4 * c, s(x,c))
  5284. +
  5285. +#if defined(FOUR_TABLES)
  5286. +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
  5287. +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
  5288. +#elif defined(ONE_TABLE)
  5289. +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
  5290. +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
  5291. +#else
  5292. +#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
  5293. +#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
  5294. +#endif
  5295. +
  5296. +#if defined(FOUR_LR_TABLES)
  5297. +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
  5298. +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
  5299. +#elif defined(ONE_LR_TABLE)
  5300. +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
  5301. +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
  5302. +#else
  5303. +#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
  5304. +#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
  5305. +#endif
  5306. +
  5307. +#if AES_BLOCK_SIZE == 16
  5308. +
  5309. +#if defined(ARRAYS)
  5310. +#define locals(y,x) x[4],y[4]
  5311. +#else
  5312. +#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
  5313. +// the following defines prevent the compiler requiring the declaration
  5314. +// of generated but unused variables in the fwd_var and inv_var macros
  5315. +#define b04 unused
  5316. +#define b05 unused
  5317. +#define b06 unused
  5318. +#define b07 unused
  5319. +#define b14 unused
  5320. +#define b15 unused
  5321. +#define b16 unused
  5322. +#define b17 unused
  5323. +#endif
  5324. +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
  5325. + s(y,2) = s(x,2); s(y,3) = s(x,3);
  5326. +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
  5327. +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
  5328. +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
  5329. +
  5330. +#elif AES_BLOCK_SIZE == 24
  5331. +
  5332. +#if defined(ARRAYS)
  5333. +#define locals(y,x) x[6],y[6]
  5334. +#else
  5335. +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
  5336. + y##0,y##1,y##2,y##3,y##4,y##5
  5337. +#define b06 unused
  5338. +#define b07 unused
  5339. +#define b16 unused
  5340. +#define b17 unused
  5341. +#endif
  5342. +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
  5343. + s(y,2) = s(x,2); s(y,3) = s(x,3); \
  5344. + s(y,4) = s(x,4); s(y,5) = s(x,5);
  5345. +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
  5346. + si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
  5347. +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
  5348. + so(y,x,3); so(y,x,4); so(y,x,5)
  5349. +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
  5350. + rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
  5351. +#else
  5352. +
  5353. +#if defined(ARRAYS)
  5354. +#define locals(y,x) x[8],y[8]
  5355. +#else
  5356. +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
  5357. + y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
  5358. +#endif
  5359. +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
  5360. + s(y,2) = s(x,2); s(y,3) = s(x,3); \
  5361. + s(y,4) = s(x,4); s(y,5) = s(x,5); \
  5362. + s(y,6) = s(x,6); s(y,7) = s(x,7);
  5363. +
  5364. +#if AES_BLOCK_SIZE == 32
  5365. +
  5366. +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
  5367. + si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
  5368. +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
  5369. + so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
  5370. +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
  5371. + rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
  5372. +#else
  5373. +
  5374. +#define state_in(y,x,k) \
  5375. +switch(nc) \
  5376. +{ case 8: si(y,x,k,7); si(y,x,k,6); \
  5377. + case 6: si(y,x,k,5); si(y,x,k,4); \
  5378. + case 4: si(y,x,k,3); si(y,x,k,2); \
  5379. + si(y,x,k,1); si(y,x,k,0); \
  5380. +}
  5381. +
  5382. +#define state_out(y,x) \
  5383. +switch(nc) \
  5384. +{ case 8: so(y,x,7); so(y,x,6); \
  5385. + case 6: so(y,x,5); so(y,x,4); \
  5386. + case 4: so(y,x,3); so(y,x,2); \
  5387. + so(y,x,1); so(y,x,0); \
  5388. +}
  5389. +
  5390. +#if defined(FAST_VARIABLE)
  5391. +
  5392. +#define round(rm,y,x,k) \
  5393. +switch(nc) \
  5394. +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
  5395. + rm(y,x,k,5); rm(y,x,k,4); \
  5396. + rm(y,x,k,3); rm(y,x,k,2); \
  5397. + rm(y,x,k,1); rm(y,x,k,0); \
  5398. + break; \
  5399. + case 6: rm(y,x,k,5); rm(y,x,k,4); \
  5400. + rm(y,x,k,3); rm(y,x,k,2); \
  5401. + rm(y,x,k,1); rm(y,x,k,0); \
  5402. + break; \
  5403. + case 4: rm(y,x,k,3); rm(y,x,k,2); \
  5404. + rm(y,x,k,1); rm(y,x,k,0); \
  5405. + break; \
  5406. +}
  5407. +#else
  5408. +
  5409. +#define round(rm,y,x,k) \
  5410. +switch(nc) \
  5411. +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
  5412. + case 6: rm(y,x,k,5); rm(y,x,k,4); \
  5413. + case 4: rm(y,x,k,3); rm(y,x,k,2); \
  5414. + rm(y,x,k,1); rm(y,x,k,0); \
  5415. +}
  5416. +
  5417. +#endif
  5418. +
  5419. +#endif
  5420. +#endif
  5421. +
  5422. +void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
  5423. +{ u_int32_t locals(b0, b1);
  5424. + const u_int32_t *kp = cx->aes_e_key;
  5425. +
  5426. +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
  5427. + u_int32_t f2;
  5428. +#endif
  5429. +
  5430. + state_in(b0, in_blk, kp); kp += nc;
  5431. +
  5432. +#if defined(UNROLL)
  5433. +
  5434. + switch(cx->aes_Nrnd)
  5435. + {
  5436. + case 14: round(fwd_rnd, b1, b0, kp );
  5437. + round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
  5438. + case 12: round(fwd_rnd, b1, b0, kp );
  5439. + round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
  5440. + case 10: round(fwd_rnd, b1, b0, kp );
  5441. + round(fwd_rnd, b0, b1, kp + nc);
  5442. + round(fwd_rnd, b1, b0, kp + 2 * nc);
  5443. + round(fwd_rnd, b0, b1, kp + 3 * nc);
  5444. + round(fwd_rnd, b1, b0, kp + 4 * nc);
  5445. + round(fwd_rnd, b0, b1, kp + 5 * nc);
  5446. + round(fwd_rnd, b1, b0, kp + 6 * nc);
  5447. + round(fwd_rnd, b0, b1, kp + 7 * nc);
  5448. + round(fwd_rnd, b1, b0, kp + 8 * nc);
  5449. + round(fwd_lrnd, b0, b1, kp + 9 * nc);
  5450. + }
  5451. +
  5452. +#elif defined(PARTIAL_UNROLL)
  5453. + { u_int32_t rnd;
  5454. +
  5455. + for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
  5456. + {
  5457. + round(fwd_rnd, b1, b0, kp);
  5458. + round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
  5459. + }
  5460. +
  5461. + round(fwd_rnd, b1, b0, kp);
  5462. + round(fwd_lrnd, b0, b1, kp + nc);
  5463. + }
  5464. +#else
  5465. + { u_int32_t rnd;
  5466. +
  5467. + for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
  5468. + {
  5469. + round(fwd_rnd, b1, b0, kp);
  5470. + l_copy(b0, b1); kp += nc;
  5471. + }
  5472. +
  5473. + round(fwd_lrnd, b0, b1, kp);
  5474. + }
  5475. +#endif
  5476. +
  5477. + state_out(out_blk, b0);
  5478. +}
  5479. +
  5480. +void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
  5481. +{ u_int32_t locals(b0, b1);
  5482. + const u_int32_t *kp = cx->aes_d_key;
  5483. +
  5484. +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
  5485. + u_int32_t f2, f4, f8, f9;
  5486. +#endif
  5487. +
  5488. + state_in(b0, in_blk, kp); kp += nc;
  5489. +
  5490. +#if defined(UNROLL)
  5491. +
  5492. + switch(cx->aes_Nrnd)
  5493. + {
  5494. + case 14: round(inv_rnd, b1, b0, kp );
  5495. + round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
  5496. + case 12: round(inv_rnd, b1, b0, kp );
  5497. + round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
  5498. + case 10: round(inv_rnd, b1, b0, kp );
  5499. + round(inv_rnd, b0, b1, kp + nc);
  5500. + round(inv_rnd, b1, b0, kp + 2 * nc);
  5501. + round(inv_rnd, b0, b1, kp + 3 * nc);
  5502. + round(inv_rnd, b1, b0, kp + 4 * nc);
  5503. + round(inv_rnd, b0, b1, kp + 5 * nc);
  5504. + round(inv_rnd, b1, b0, kp + 6 * nc);
  5505. + round(inv_rnd, b0, b1, kp + 7 * nc);
  5506. + round(inv_rnd, b1, b0, kp + 8 * nc);
  5507. + round(inv_lrnd, b0, b1, kp + 9 * nc);
  5508. + }
  5509. +
  5510. +#elif defined(PARTIAL_UNROLL)
  5511. + { u_int32_t rnd;
  5512. +
  5513. + for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
  5514. + {
  5515. + round(inv_rnd, b1, b0, kp);
  5516. + round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
  5517. + }
  5518. +
  5519. + round(inv_rnd, b1, b0, kp);
  5520. + round(inv_lrnd, b0, b1, kp + nc);
  5521. + }
  5522. +#else
  5523. + { u_int32_t rnd;
  5524. +
  5525. + for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
  5526. + {
  5527. + round(inv_rnd, b1, b0, kp);
  5528. + l_copy(b0, b1); kp += nc;
  5529. + }
  5530. +
  5531. + round(inv_lrnd, b0, b1, kp);
  5532. + }
  5533. +#endif
  5534. +
  5535. + state_out(out_blk, b0);
  5536. +}
  5537. diff -pruN linux-2.4.27_orig/drivers/misc/aes.h linux-2.4.27/drivers/misc/aes.h
  5538. --- linux-2.4.27_orig/drivers/misc/aes.h 1970-01-01 01:00:00.000000000 +0100
  5539. +++ linux-2.4.27/drivers/misc/aes.h 2004-10-25 14:20:44.731002344 +0200
  5540. @@ -0,0 +1,113 @@
  5541. +// I retain copyright in this code but I encourage its free use provided
  5542. +// that I don't carry any responsibility for the results. I am especially
  5543. +// happy to see it used in free and open source software. If you do use
  5544. +// it I would appreciate an acknowledgement of its origin in the code or
  5545. +// the product that results and I would also appreciate knowing a little
  5546. +// about the use to which it is being put. I am grateful to Frank Yellin
  5547. +// for some ideas that are used in this implementation.
  5548. +//
  5549. +// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
  5550. +//
  5551. +// This is an implementation of the AES encryption algorithm (Rijndael)
  5552. +// designed by Joan Daemen and Vincent Rijmen. This version is designed
  5553. +// to provide both fixed and dynamic block and key lengths and can also
  5554. +// run with either big or little endian internal byte order (see aes.h).
  5555. +// It inputs block and key lengths in bytes with the legal values being
  5556. +// 16, 24 and 32.
  5557. +
  5558. +/*
  5559. + * Modified by Jari Ruusu, May 1 2001
  5560. + * - Fixed some compile warnings, code was ok but gcc warned anyway.
  5561. + * - Changed basic types: byte -> unsigned char, word -> u_int32_t
  5562. + * - Major name space cleanup: Names visible to outside now begin
  5563. + * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
  5564. + * - Removed C++ and DLL support as part of name space cleanup.
  5565. + * - Eliminated unnecessary recomputation of tables. (actual bug fix)
  5566. + * - Merged precomputed constant tables to aes.c file.
  5567. + * - Removed data alignment restrictions for portability reasons.
  5568. + * - Made block and key lengths accept bit count (128/192/256)
  5569. + * as well byte count (16/24/32).
  5570. + * - Removed all error checks. This change also eliminated the need
  5571. + * to preinitialize the context struct to zero.
  5572. + * - Removed some totally unused constants.
  5573. + */
  5574. +
  5575. +#ifndef _AES_H
  5576. +#define _AES_H
  5577. +
  5578. +#include <linux/types.h>
  5579. +#include <linux/linkage.h>
  5580. +#include <linux/config.h>
  5581. +#include <linux/module.h>
  5582. +
  5583. +// CONFIGURATION OPTIONS (see also aes.c)
  5584. +//
  5585. +// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or
  5586. +// leave this undefined for dynamically variable block size (this will
  5587. +// result in much slower code).
  5588. +// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If
  5589. +// left undefined a slower version providing variable block length is compiled
  5590. +
  5591. +#define AES_BLOCK_SIZE 16
  5592. +
  5593. +// The number of key schedule words for different block and key lengths
  5594. +// allowing for method of computation which requires the length to be a
  5595. +// multiple of the key length
  5596. +//
  5597. +// Nk = 4 6 8
  5598. +// -------------
  5599. +// Nb = 4 | 60 60 64
  5600. +// 6 | 96 90 96
  5601. +// 8 | 120 120 120
  5602. +
  5603. +#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32)
  5604. +#define AES_KS_LENGTH 120
  5605. +#define AES_RC_LENGTH 29
  5606. +#else
  5607. +#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE
  5608. +#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8
  5609. +#endif
  5610. +
  5611. +typedef struct
  5612. +{
  5613. + u_int32_t aes_Nkey; // the number of words in the key input block
  5614. + u_int32_t aes_Nrnd; // the number of cipher rounds
  5615. + u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule
  5616. + u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule
  5617. +#if !defined(AES_BLOCK_SIZE)
  5618. + u_int32_t aes_Ncol; // the number of columns in the cipher state
  5619. +#endif
  5620. +} aes_context;
  5621. +
  5622. +// avoid global name conflict with mainline kernel
  5623. +#define aes_set_key _aes_set_key
  5624. +#define aes_encrypt _aes_encrypt
  5625. +#define aes_decrypt _aes_decrypt
  5626. +
  5627. +// THE CIPHER INTERFACE
  5628. +
  5629. +#if !defined(AES_BLOCK_SIZE)
  5630. +extern void aes_set_blk(aes_context *, const int);
  5631. +#endif
  5632. +
  5633. +#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
  5634. + asmlinkage
  5635. +#endif
  5636. +extern void aes_set_key(aes_context *, const unsigned char [], const int, const int);
  5637. +
  5638. +#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
  5639. + asmlinkage
  5640. +#endif
  5641. +extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []);
  5642. +
  5643. +#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
  5644. + asmlinkage
  5645. +#endif
  5646. +extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []);
  5647. +
  5648. +// The block length inputs to aes_set_block and aes_set_key are in numbers
  5649. +// of bytes or bits. The calls to subroutines must be made in the above
  5650. +// order but multiple calls can be made without repeating earlier calls
  5651. +// if their parameters have not changed.
  5652. +
  5653. +#endif // _AES_H
  5654. diff -pruN linux-2.4.27_orig/drivers/misc/crypto-ksym.c linux-2.4.27/drivers/misc/crypto-ksym.c
  5655. --- linux-2.4.27_orig/drivers/misc/crypto-ksym.c 1970-01-01 01:00:00.000000000 +0100
  5656. +++ linux-2.4.27/drivers/misc/crypto-ksym.c 2004-10-25 14:20:44.731002344 +0200
  5657. @@ -0,0 +1,7 @@
  5658. +#include <linux/module.h>
  5659. +#include "aes.h"
  5660. +#include "md5.h"
  5661. +EXPORT_SYMBOL_NOVERS(aes_set_key);
  5662. +EXPORT_SYMBOL_NOVERS(aes_encrypt);
  5663. +EXPORT_SYMBOL_NOVERS(aes_decrypt);
  5664. +EXPORT_SYMBOL_NOVERS(md5_transform_CPUbyteorder);
  5665. diff -pruN linux-2.4.27_orig/drivers/misc/md5-amd64.S linux-2.4.27/drivers/misc/md5-amd64.S
  5666. --- linux-2.4.27_orig/drivers/misc/md5-amd64.S 1970-01-01 01:00:00.000000000 +0100
  5667. +++ linux-2.4.27/drivers/misc/md5-amd64.S 2004-10-25 14:20:44.732002192 +0200
  5668. @@ -0,0 +1,200 @@
  5669. +//
  5670. +// md5-amd64.S
  5671. +//
  5672. +// Written by Jari Ruusu, October 1 2003
  5673. +//
  5674. +// Copyright 2003 by Jari Ruusu.
  5675. +// Redistribution of this file is permitted under the GNU Public License.
  5676. +//
  5677. +
  5678. +// Modified by Jari Ruusu, June 12 2004
  5679. +// - Converted 32 bit x86 code to 64 bit AMD64 code
  5680. +
  5681. +// A MD5 transform implementation for AMD64 compatible processors.
  5682. +// This code does not preserve the rax, rcx, rdx, rsi, rdi or r8-r11
  5683. +// registers or the artihmetic status flags. However, the rbx, rbp and
  5684. +// r12-r15 registers are preserved across calls.
  5685. +
  5686. +// void md5_transform_CPUbyteorder(u_int32_t *hash, u_int32_t *in)
  5687. +
  5688. +#if defined(USE_UNDERLINE)
  5689. +# define md5_transform_CPUbyteorder _md5_transform_CPUbyteorder
  5690. +#endif
  5691. +#if !defined(ALIGN64BYTES)
  5692. +# define ALIGN64BYTES 64
  5693. +#endif
  5694. +
  5695. + .file "md5-amd64.S"
  5696. + .globl md5_transform_CPUbyteorder
  5697. +
  5698. +// rdi = pointer to hash[4] array which is read and written
  5699. +// rsi = pointer to in[16] array which is read only
  5700. +
  5701. + .text
  5702. + .align ALIGN64BYTES
  5703. +md5_transform_CPUbyteorder:
  5704. + movl 12(%rdi),%eax
  5705. + movl 8(%rdi),%ecx
  5706. + movl (%rdi),%r8d
  5707. + movl 4(%rdi),%r9d
  5708. + movl (%rsi),%r10d
  5709. + prefetcht0 60(%rsi)
  5710. + movl %eax,%edx
  5711. + xorl %ecx,%eax
  5712. +
  5713. +#define REPEAT1(p1w,p2x,p3z,p4c,p5s,p6Nin,p7Nz,p8Ny) \
  5714. + addl $p4c,p1w ;\
  5715. + andl p2x,%eax ;\
  5716. + addl %r10d,p1w ;\
  5717. + xorl p3z,%eax ;\
  5718. + movl p6Nin*4(%rsi),%r10d ;\
  5719. + addl %eax,p1w ;\
  5720. + movl p7Nz,%eax ;\
  5721. + roll $p5s,p1w ;\
  5722. + xorl p8Ny,%eax ;\
  5723. + addl p2x,p1w
  5724. +
  5725. + REPEAT1(%r8d,%r9d,%edx,0xd76aa478, 7, 1,%ecx,%r9d)
  5726. + REPEAT1(%edx,%r8d,%ecx,0xe8c7b756,12, 2,%r9d,%r8d)
  5727. + REPEAT1(%ecx,%edx,%r9d,0x242070db,17, 3,%r8d,%edx)
  5728. + REPEAT1(%r9d,%ecx,%r8d,0xc1bdceee,22, 4,%edx,%ecx)
  5729. + REPEAT1(%r8d,%r9d,%edx,0xf57c0faf, 7, 5,%ecx,%r9d)
  5730. + REPEAT1(%edx,%r8d,%ecx,0x4787c62a,12, 6,%r9d,%r8d)
  5731. + REPEAT1(%ecx,%edx,%r9d,0xa8304613,17, 7,%r8d,%edx)
  5732. + REPEAT1(%r9d,%ecx,%r8d,0xfd469501,22, 8,%edx,%ecx)
  5733. + REPEAT1(%r8d,%r9d,%edx,0x698098d8, 7, 9,%ecx,%r9d)
  5734. + REPEAT1(%edx,%r8d,%ecx,0x8b44f7af,12,10,%r9d,%r8d)
  5735. + REPEAT1(%ecx,%edx,%r9d,0xffff5bb1,17,11,%r8d,%edx)
  5736. + REPEAT1(%r9d,%ecx,%r8d,0x895cd7be,22,12,%edx,%ecx)
  5737. + REPEAT1(%r8d,%r9d,%edx,0x6b901122, 7,13,%ecx,%r9d)
  5738. + REPEAT1(%edx,%r8d,%ecx,0xfd987193,12,14,%r9d,%r8d)
  5739. + REPEAT1(%ecx,%edx,%r9d,0xa679438e,17,15,%r8d,%edx)
  5740. +
  5741. + addl $0x49b40821,%r9d
  5742. + andl %ecx,%eax
  5743. + addl %r10d,%r9d
  5744. + xorl %r8d,%eax
  5745. + movl 1*4(%rsi),%r10d
  5746. + addl %eax,%r9d
  5747. + movl %ecx,%eax
  5748. + roll $22,%r9d
  5749. + addl %ecx,%r9d
  5750. +
  5751. +#define REPEAT2(p1w,p2x,p3y,p4z,p5c,p6s,p7Nin,p8Ny) \
  5752. + xorl p2x,%eax ;\
  5753. + addl $p5c,p1w ;\
  5754. + andl p4z,%eax ;\
  5755. + addl %r10d,p1w ;\
  5756. + xorl p3y,%eax ;\
  5757. + movl p7Nin*4(%rsi),%r10d ;\
  5758. + addl %eax,p1w ;\
  5759. + movl p8Ny,%eax ;\
  5760. + roll $p6s,p1w ;\
  5761. + addl p2x,p1w
  5762. +
  5763. + REPEAT2(%r8d,%r9d,%ecx,%edx,0xf61e2562, 5, 6,%r9d)
  5764. + REPEAT2(%edx,%r8d,%r9d,%ecx,0xc040b340, 9,11,%r8d)
  5765. + REPEAT2(%ecx,%edx,%r8d,%r9d,0x265e5a51,14, 0,%edx)
  5766. + REPEAT2(%r9d,%ecx,%edx,%r8d,0xe9b6c7aa,20, 5,%ecx)
  5767. + REPEAT2(%r8d,%r9d,%ecx,%edx,0xd62f105d, 5,10,%r9d)
  5768. + REPEAT2(%edx,%r8d,%r9d,%ecx,0x02441453, 9,15,%r8d)
  5769. + REPEAT2(%ecx,%edx,%r8d,%r9d,0xd8a1e681,14, 4,%edx)
  5770. + REPEAT2(%r9d,%ecx,%edx,%r8d,0xe7d3fbc8,20, 9,%ecx)
  5771. + REPEAT2(%r8d,%r9d,%ecx,%edx,0x21e1cde6, 5,14,%r9d)
  5772. + REPEAT2(%edx,%r8d,%r9d,%ecx,0xc33707d6, 9, 3,%r8d)
  5773. + REPEAT2(%ecx,%edx,%r8d,%r9d,0xf4d50d87,14, 8,%edx)
  5774. + REPEAT2(%r9d,%ecx,%edx,%r8d,0x455a14ed,20,13,%ecx)
  5775. + REPEAT2(%r8d,%r9d,%ecx,%edx,0xa9e3e905, 5, 2,%r9d)
  5776. + REPEAT2(%edx,%r8d,%r9d,%ecx,0xfcefa3f8, 9, 7,%r8d)
  5777. + REPEAT2(%ecx,%edx,%r8d,%r9d,0x676f02d9,14,12,%edx)
  5778. +
  5779. + xorl %ecx,%eax
  5780. + addl $0x8d2a4c8a,%r9d
  5781. + andl %r8d,%eax
  5782. + addl %r10d,%r9d
  5783. + xorl %edx,%eax
  5784. + movl 5*4(%rsi),%r10d
  5785. + addl %eax,%r9d
  5786. + movl %ecx,%eax
  5787. + roll $20,%r9d
  5788. + xorl %edx,%eax
  5789. + addl %ecx,%r9d
  5790. +
  5791. +#define REPEAT3(p1w,p2x,p3c,p4s,p5Nin,p6Ny,p7Nz) \
  5792. + addl $p3c,p1w ;\
  5793. + xorl p2x,%eax ;\
  5794. + addl %r10d,p1w ;\
  5795. + movl p5Nin*4(%rsi),%r10d ;\
  5796. + addl %eax,p1w ;\
  5797. + movl p6Ny,%eax ;\
  5798. + roll $p4s,p1w ;\
  5799. + xorl p7Nz,%eax ;\
  5800. + addl p2x,p1w
  5801. +
  5802. + REPEAT3(%r8d,%r9d,0xfffa3942, 4, 8,%r9d,%ecx)
  5803. + REPEAT3(%edx,%r8d,0x8771f681,11,11,%r8d,%r9d)
  5804. + REPEAT3(%ecx,%edx,0x6d9d6122,16,14,%edx,%r8d)
  5805. + REPEAT3(%r9d,%ecx,0xfde5380c,23, 1,%ecx,%edx)
  5806. + REPEAT3(%r8d,%r9d,0xa4beea44, 4, 4,%r9d,%ecx)
  5807. + REPEAT3(%edx,%r8d,0x4bdecfa9,11, 7,%r8d,%r9d)
  5808. + REPEAT3(%ecx,%edx,0xf6bb4b60,16,10,%edx,%r8d)
  5809. + REPEAT3(%r9d,%ecx,0xbebfbc70,23,13,%ecx,%edx)
  5810. + REPEAT3(%r8d,%r9d,0x289b7ec6, 4, 0,%r9d,%ecx)
  5811. + REPEAT3(%edx,%r8d,0xeaa127fa,11, 3,%r8d,%r9d)
  5812. + REPEAT3(%ecx,%edx,0xd4ef3085,16, 6,%edx,%r8d)
  5813. + REPEAT3(%r9d,%ecx,0x04881d05,23, 9,%ecx,%edx)
  5814. + REPEAT3(%r8d,%r9d,0xd9d4d039, 4,12,%r9d,%ecx)
  5815. + REPEAT3(%edx,%r8d,0xe6db99e5,11,15,%r8d,%r9d)
  5816. + REPEAT3(%ecx,%edx,0x1fa27cf8,16, 2,%edx,%r8d)
  5817. +
  5818. + addl $0xc4ac5665,%r9d
  5819. + xorl %ecx,%eax
  5820. + addl %r10d,%r9d
  5821. + movl (%rsi),%r10d
  5822. + addl %eax,%r9d
  5823. + movl %edx,%eax
  5824. + roll $23,%r9d
  5825. + notl %eax
  5826. + addl %ecx,%r9d
  5827. +
  5828. +#define REPEAT4(p1w,p2x,p3y,p4c,p5s,p6Nin,p7Nz) \
  5829. + addl $p4c,p1w ;\
  5830. + orl p2x,%eax ;\
  5831. + addl %r10d,p1w ;\
  5832. + xorl p3y,%eax ;\
  5833. + movl p6Nin*4(%rsi),%r10d ;\
  5834. + addl %eax,p1w ;\
  5835. + movl p7Nz,%eax ;\
  5836. + roll $p5s,p1w ;\
  5837. + notl %eax ;\
  5838. + addl p2x,p1w
  5839. +
  5840. + REPEAT4(%r8d,%r9d,%ecx,0xf4292244, 6, 7,%ecx)
  5841. + REPEAT4(%edx,%r8d,%r9d,0x432aff97,10,14,%r9d)
  5842. + REPEAT4(%ecx,%edx,%r8d,0xab9423a7,15, 5,%r8d)
  5843. + REPEAT4(%r9d,%ecx,%edx,0xfc93a039,21,12,%edx)
  5844. + REPEAT4(%r8d,%r9d,%ecx,0x655b59c3, 6, 3,%ecx)
  5845. + REPEAT4(%edx,%r8d,%r9d,0x8f0ccc92,10,10,%r9d)
  5846. + REPEAT4(%ecx,%edx,%r8d,0xffeff47d,15, 1,%r8d)
  5847. + REPEAT4(%r9d,%ecx,%edx,0x85845dd1,21, 8,%edx)
  5848. + REPEAT4(%r8d,%r9d,%ecx,0x6fa87e4f, 6,15,%ecx)
  5849. + REPEAT4(%edx,%r8d,%r9d,0xfe2ce6e0,10, 6,%r9d)
  5850. + REPEAT4(%ecx,%edx,%r8d,0xa3014314,15,13,%r8d)
  5851. + REPEAT4(%r9d,%ecx,%edx,0x4e0811a1,21, 4,%edx)
  5852. + REPEAT4(%r8d,%r9d,%ecx,0xf7537e82, 6,11,%ecx)
  5853. + REPEAT4(%edx,%r8d,%r9d,0xbd3af235,10, 2,%r9d)
  5854. + REPEAT4(%ecx,%edx,%r8d,0x2ad7d2bb,15, 9,%r8d)
  5855. +
  5856. + addl $0xeb86d391,%r9d
  5857. + orl %ecx,%eax
  5858. + addl %r10d,%r9d
  5859. + xorl %edx,%eax
  5860. + addl %eax,%r9d
  5861. + roll $21,%r9d
  5862. + addl %ecx,%r9d
  5863. +
  5864. + addl %r8d,(%rdi)
  5865. + addl %r9d,4(%rdi)
  5866. + addl %ecx,8(%rdi)
  5867. + addl %edx,12(%rdi)
  5868. + ret
  5869. diff -pruN linux-2.4.27_orig/drivers/misc/md5-x86.S linux-2.4.27/drivers/misc/md5-x86.S
  5870. --- linux-2.4.27_orig/drivers/misc/md5-x86.S 1970-01-01 01:00:00.000000000 +0100
  5871. +++ linux-2.4.27/drivers/misc/md5-x86.S 2004-10-25 14:20:44.733002040 +0200
  5872. @@ -0,0 +1,207 @@
  5873. +//
  5874. +// md5-x86.S
  5875. +//
  5876. +// Written by Jari Ruusu, October 1 2003
  5877. +//
  5878. +// Copyright 2003 by Jari Ruusu.
  5879. +// Redistribution of this file is permitted under the GNU Public License.
  5880. +//
  5881. +
  5882. +// A MD5 transform implementation for x86 compatible processors. This
  5883. +// version uses i386 instruction set but instruction scheduling is optimized
  5884. +// for Pentium-2. This code does not preserve the eax, ecx or edx registers
  5885. +// or the artihmetic status flags. However, the ebx, esi, edi, and ebp
  5886. +// registers are preserved across calls.
  5887. +
  5888. +// void md5_transform_CPUbyteorder(u_int32_t *hash, u_int32_t *in)
  5889. +
  5890. +#if defined(USE_UNDERLINE)
  5891. +# define md5_transform_CPUbyteorder _md5_transform_CPUbyteorder
  5892. +#endif
  5893. +#if !defined(ALIGN32BYTES)
  5894. +# define ALIGN32BYTES 32
  5895. +#endif
  5896. +
  5897. + .file "md5-x86.S"
  5898. + .globl md5_transform_CPUbyteorder
  5899. + .text
  5900. + .align ALIGN32BYTES
  5901. +
  5902. +md5_transform_CPUbyteorder:
  5903. + push %ebp
  5904. + mov 4+4(%esp),%eax // pointer to 'hash' input
  5905. + mov 8+4(%esp),%ebp // pointer to 'in' array
  5906. + push %ebx
  5907. + push %esi
  5908. + push %edi
  5909. +
  5910. + mov (%eax),%esi
  5911. + mov 4(%eax),%edi
  5912. + mov 8(%eax),%ecx
  5913. + mov 12(%eax),%eax
  5914. + mov (%ebp),%ebx
  5915. + mov %eax,%edx
  5916. + xor %ecx,%eax
  5917. +
  5918. +#define REPEAT1(p1w,p2x,p3z,p4c,p5s,p6Nin,p7Nz,p8Ny) \
  5919. + add $p4c,p1w ;\
  5920. + and p2x,%eax ;\
  5921. + add %ebx,p1w ;\
  5922. + xor p3z,%eax ;\
  5923. + mov p6Nin*4(%ebp),%ebx ;\
  5924. + add %eax,p1w ;\
  5925. + mov p7Nz,%eax ;\
  5926. + rol $p5s,p1w ;\
  5927. + xor p8Ny,%eax ;\
  5928. + add p2x,p1w
  5929. +
  5930. + REPEAT1(%esi,%edi,%edx,0xd76aa478, 7, 1,%ecx,%edi)
  5931. + REPEAT1(%edx,%esi,%ecx,0xe8c7b756,12, 2,%edi,%esi)
  5932. + REPEAT1(%ecx,%edx,%edi,0x242070db,17, 3,%esi,%edx)
  5933. + REPEAT1(%edi,%ecx,%esi,0xc1bdceee,22, 4,%edx,%ecx)
  5934. + REPEAT1(%esi,%edi,%edx,0xf57c0faf, 7, 5,%ecx,%edi)
  5935. + REPEAT1(%edx,%esi,%ecx,0x4787c62a,12, 6,%edi,%esi)
  5936. + REPEAT1(%ecx,%edx,%edi,0xa8304613,17, 7,%esi,%edx)
  5937. + REPEAT1(%edi,%ecx,%esi,0xfd469501,22, 8,%edx,%ecx)
  5938. + REPEAT1(%esi,%edi,%edx,0x698098d8, 7, 9,%ecx,%edi)
  5939. + REPEAT1(%edx,%esi,%ecx,0x8b44f7af,12,10,%edi,%esi)
  5940. + REPEAT1(%ecx,%edx,%edi,0xffff5bb1,17,11,%esi,%edx)
  5941. + REPEAT1(%edi,%ecx,%esi,0x895cd7be,22,12,%edx,%ecx)
  5942. + REPEAT1(%esi,%edi,%edx,0x6b901122, 7,13,%ecx,%edi)
  5943. + REPEAT1(%edx,%esi,%ecx,0xfd987193,12,14,%edi,%esi)
  5944. + REPEAT1(%ecx,%edx,%edi,0xa679438e,17,15,%esi,%edx)
  5945. +
  5946. + add $0x49b40821,%edi
  5947. + and %ecx,%eax
  5948. + add %ebx,%edi
  5949. + xor %esi,%eax
  5950. + mov 1*4(%ebp),%ebx
  5951. + add %eax,%edi
  5952. + mov %ecx,%eax
  5953. + rol $22,%edi
  5954. + add %ecx,%edi
  5955. +
  5956. +#define REPEAT2(p1w,p2x,p3y,p4z,p5c,p6s,p7Nin,p8Ny) \
  5957. + xor p2x,%eax ;\
  5958. + add $p5c,p1w ;\
  5959. + and p4z,%eax ;\
  5960. + add %ebx,p1w ;\
  5961. + xor p3y,%eax ;\
  5962. + mov p7Nin*4(%ebp),%ebx ;\
  5963. + add %eax,p1w ;\
  5964. + mov p8Ny,%eax ;\
  5965. + rol $p6s,p1w ;\
  5966. + add p2x,p1w
  5967. +
  5968. + REPEAT2(%esi,%edi,%ecx,%edx,0xf61e2562, 5, 6,%edi)
  5969. + REPEAT2(%edx,%esi,%edi,%ecx,0xc040b340, 9,11,%esi)
  5970. + REPEAT2(%ecx,%edx,%esi,%edi,0x265e5a51,14, 0,%edx)
  5971. + REPEAT2(%edi,%ecx,%edx,%esi,0xe9b6c7aa,20, 5,%ecx)
  5972. + REPEAT2(%esi,%edi,%ecx,%edx,0xd62f105d, 5,10,%edi)
  5973. + REPEAT2(%edx,%esi,%edi,%ecx,0x02441453, 9,15,%esi)
  5974. + REPEAT2(%ecx,%edx,%esi,%edi,0xd8a1e681,14, 4,%edx)
  5975. + REPEAT2(%edi,%ecx,%edx,%esi,0xe7d3fbc8,20, 9,%ecx)
  5976. + REPEAT2(%esi,%edi,%ecx,%edx,0x21e1cde6, 5,14,%edi)
  5977. + REPEAT2(%edx,%esi,%edi,%ecx,0xc33707d6, 9, 3,%esi)
  5978. + REPEAT2(%ecx,%edx,%esi,%edi,0xf4d50d87,14, 8,%edx)
  5979. + REPEAT2(%edi,%ecx,%edx,%esi,0x455a14ed,20,13,%ecx)
  5980. + REPEAT2(%esi,%edi,%ecx,%edx,0xa9e3e905, 5, 2,%edi)
  5981. + REPEAT2(%edx,%esi,%edi,%ecx,0xfcefa3f8, 9, 7,%esi)
  5982. + REPEAT2(%ecx,%edx,%esi,%edi,0x676f02d9,14,12,%edx)
  5983. +
  5984. + xor %ecx,%eax
  5985. + add $0x8d2a4c8a,%edi
  5986. + and %esi,%eax
  5987. + add %ebx,%edi
  5988. + xor %edx,%eax
  5989. + mov 5*4(%ebp),%ebx
  5990. + add %eax,%edi
  5991. + mov %ecx,%eax
  5992. + rol $20,%edi
  5993. + xor %edx,%eax
  5994. + add %ecx,%edi
  5995. +
  5996. +#define REPEAT3(p1w,p2x,p3c,p4s,p5Nin,p6Ny,p7Nz) \
  5997. + add $p3c,p1w ;\
  5998. + xor p2x,%eax ;\
  5999. + add %ebx,p1w ;\
  6000. + mov p5Nin*4(%ebp),%ebx ;\
  6001. + add %eax,p1w ;\
  6002. + mov p6Ny,%eax ;\
  6003. + rol $p4s,p1w ;\
  6004. + xor p7Nz,%eax ;\
  6005. + add p2x,p1w
  6006. +
  6007. + REPEAT3(%esi,%edi,0xfffa3942, 4, 8,%edi,%ecx)
  6008. + REPEAT3(%edx,%esi,0x8771f681,11,11,%esi,%edi)
  6009. + REPEAT3(%ecx,%edx,0x6d9d6122,16,14,%edx,%esi)
  6010. + REPEAT3(%edi,%ecx,0xfde5380c,23, 1,%ecx,%edx)
  6011. + REPEAT3(%esi,%edi,0xa4beea44, 4, 4,%edi,%ecx)
  6012. + REPEAT3(%edx,%esi,0x4bdecfa9,11, 7,%esi,%edi)
  6013. + REPEAT3(%ecx,%edx,0xf6bb4b60,16,10,%edx,%esi)
  6014. + REPEAT3(%edi,%ecx,0xbebfbc70,23,13,%ecx,%edx)
  6015. + REPEAT3(%esi,%edi,0x289b7ec6, 4, 0,%edi,%ecx)
  6016. + REPEAT3(%edx,%esi,0xeaa127fa,11, 3,%esi,%edi)
  6017. + REPEAT3(%ecx,%edx,0xd4ef3085,16, 6,%edx,%esi)
  6018. + REPEAT3(%edi,%ecx,0x04881d05,23, 9,%ecx,%edx)
  6019. + REPEAT3(%esi,%edi,0xd9d4d039, 4,12,%edi,%ecx)
  6020. + REPEAT3(%edx,%esi,0xe6db99e5,11,15,%esi,%edi)
  6021. + REPEAT3(%ecx,%edx,0x1fa27cf8,16, 2,%edx,%esi)
  6022. +
  6023. + add $0xc4ac5665,%edi
  6024. + xor %ecx,%eax
  6025. + add %ebx,%edi
  6026. + mov (%ebp),%ebx
  6027. + add %eax,%edi
  6028. + mov %edx,%eax
  6029. + rol $23,%edi
  6030. + not %eax
  6031. + add %ecx,%edi
  6032. +
  6033. +#define REPEAT4(p1w,p2x,p3y,p4c,p5s,p6Nin,p7Nz) \
  6034. + add $p4c,p1w ;\
  6035. + or p2x,%eax ;\
  6036. + add %ebx,p1w ;\
  6037. + xor p3y,%eax ;\
  6038. + mov p6Nin*4(%ebp),%ebx ;\
  6039. + add %eax,p1w ;\
  6040. + mov p7Nz,%eax ;\
  6041. + rol $p5s,p1w ;\
  6042. + not %eax ;\
  6043. + add p2x,p1w
  6044. +
  6045. + REPEAT4(%esi,%edi,%ecx,0xf4292244, 6, 7,%ecx)
  6046. + REPEAT4(%edx,%esi,%edi,0x432aff97,10,14,%edi)
  6047. + REPEAT4(%ecx,%edx,%esi,0xab9423a7,15, 5,%esi)
  6048. + REPEAT4(%edi,%ecx,%edx,0xfc93a039,21,12,%edx)
  6049. + REPEAT4(%esi,%edi,%ecx,0x655b59c3, 6, 3,%ecx)
  6050. + REPEAT4(%edx,%esi,%edi,0x8f0ccc92,10,10,%edi)
  6051. + REPEAT4(%ecx,%edx,%esi,0xffeff47d,15, 1,%esi)
  6052. + REPEAT4(%edi,%ecx,%edx,0x85845dd1,21, 8,%edx)
  6053. + REPEAT4(%esi,%edi,%ecx,0x6fa87e4f, 6,15,%ecx)
  6054. + REPEAT4(%edx,%esi,%edi,0xfe2ce6e0,10, 6,%edi)
  6055. + REPEAT4(%ecx,%edx,%esi,0xa3014314,15,13,%esi)
  6056. + REPEAT4(%edi,%ecx,%edx,0x4e0811a1,21, 4,%edx)
  6057. + REPEAT4(%esi,%edi,%ecx,0xf7537e82, 6,11,%ecx)
  6058. + REPEAT4(%edx,%esi,%edi,0xbd3af235,10, 2,%edi)
  6059. + REPEAT4(%ecx,%edx,%esi,0x2ad7d2bb,15, 9,%esi)
  6060. +
  6061. + add $0xeb86d391,%edi
  6062. + or %ecx,%eax
  6063. + add %ebx,%edi
  6064. + xor %edx,%eax
  6065. + mov 4+16(%esp),%ebp // pointer to 'hash' output
  6066. + add %eax,%edi
  6067. + rol $21,%edi
  6068. + add %ecx,%edi
  6069. +
  6070. + add %esi,(%ebp)
  6071. + add %edi,4(%ebp)
  6072. + add %ecx,8(%ebp)
  6073. + add %edx,12(%ebp)
  6074. +
  6075. + pop %edi
  6076. + pop %esi
  6077. + pop %ebx
  6078. + pop %ebp
  6079. + ret
  6080. diff -pruN linux-2.4.27_orig/drivers/misc/md5.c linux-2.4.27/drivers/misc/md5.c
  6081. --- linux-2.4.27_orig/drivers/misc/md5.c 1970-01-01 01:00:00.000000000 +0100
  6082. +++ linux-2.4.27/drivers/misc/md5.c 2004-10-25 14:20:44.743000520 +0200
  6083. @@ -0,0 +1,106 @@
  6084. +/*
  6085. + * MD5 Message Digest Algorithm (RFC1321).
  6086. + *
  6087. + * Derived from cryptoapi implementation, originally based on the
  6088. + * public domain implementation written by Colin Plumb in 1993.
  6089. + *
  6090. + * Copyright (c) Cryptoapi developers.
  6091. + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
  6092. + *
  6093. + * This program is free software; you can redistribute it and/or modify it
  6094. + * under the terms of the GNU General Public License as published by the Free
  6095. + * Software Foundation; either version 2 of the License, or (at your option)
  6096. + * any later version.
  6097. + */
  6098. +
  6099. +#include "md5.h"
  6100. +
  6101. +#define MD5_F1(x, y, z) (z ^ (x & (y ^ z)))
  6102. +#define MD5_F2(x, y, z) MD5_F1(z, x, y)
  6103. +#define MD5_F3(x, y, z) (x ^ y ^ z)
  6104. +#define MD5_F4(x, y, z) (y ^ (x | ~z))
  6105. +#define MD5_STEP(f, w, x, y, z, in, s) \
  6106. + (w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x)
  6107. +
  6108. +void md5_transform_CPUbyteorder(u_int32_t *hash, u_int32_t const *in)
  6109. +{
  6110. + u_int32_t a, b, c, d;
  6111. +
  6112. + a = hash[0];
  6113. + b = hash[1];
  6114. + c = hash[2];
  6115. + d = hash[3];
  6116. +
  6117. + MD5_STEP(MD5_F1, a, b, c, d, in[0] + 0xd76aa478, 7);
  6118. + MD5_STEP(MD5_F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
  6119. + MD5_STEP(MD5_F1, c, d, a, b, in[2] + 0x242070db, 17);
  6120. + MD5_STEP(MD5_F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
  6121. + MD5_STEP(MD5_F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
  6122. + MD5_STEP(MD5_F1, d, a, b, c, in[5] + 0x4787c62a, 12);
  6123. + MD5_STEP(MD5_F1, c, d, a, b, in[6] + 0xa8304613, 17);
  6124. + MD5_STEP(MD5_F1, b, c, d, a, in[7] + 0xfd469501, 22);
  6125. + MD5_STEP(MD5_F1, a, b, c, d, in[8] + 0x698098d8, 7);
  6126. + MD5_STEP(MD5_F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
  6127. + MD5_STEP(MD5_F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  6128. + MD5_STEP(MD5_F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  6129. + MD5_STEP(MD5_F1, a, b, c, d, in[12] + 0x6b901122, 7);
  6130. + MD5_STEP(MD5_F1, d, a, b, c, in[13] + 0xfd987193, 12);
  6131. + MD5_STEP(MD5_F1, c, d, a, b, in[14] + 0xa679438e, 17);
  6132. + MD5_STEP(MD5_F1, b, c, d, a, in[15] + 0x49b40821, 22);
  6133. +
  6134. + MD5_STEP(MD5_F2, a, b, c, d, in[1] + 0xf61e2562, 5);
  6135. + MD5_STEP(MD5_F2, d, a, b, c, in[6] + 0xc040b340, 9);
  6136. + MD5_STEP(MD5_F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  6137. + MD5_STEP(MD5_F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
  6138. + MD5_STEP(MD5_F2, a, b, c, d, in[5] + 0xd62f105d, 5);
  6139. + MD5_STEP(MD5_F2, d, a, b, c, in[10] + 0x02441453, 9);
  6140. + MD5_STEP(MD5_F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  6141. + MD5_STEP(MD5_F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
  6142. + MD5_STEP(MD5_F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
  6143. + MD5_STEP(MD5_F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  6144. + MD5_STEP(MD5_F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
  6145. + MD5_STEP(MD5_F2, b, c, d, a, in[8] + 0x455a14ed, 20);
  6146. + MD5_STEP(MD5_F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  6147. + MD5_STEP(MD5_F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
  6148. + MD5_STEP(MD5_F2, c, d, a, b, in[7] + 0x676f02d9, 14);
  6149. + MD5_STEP(MD5_F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
  6150. +
  6151. + MD5_STEP(MD5_F3, a, b, c, d, in[5] + 0xfffa3942, 4);
  6152. + MD5_STEP(MD5_F3, d, a, b, c, in[8] + 0x8771f681, 11);
  6153. + MD5_STEP(MD5_F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  6154. + MD5_STEP(MD5_F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  6155. + MD5_STEP(MD5_F3, a, b, c, d, in[1] + 0xa4beea44, 4);
  6156. + MD5_STEP(MD5_F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
  6157. + MD5_STEP(MD5_F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
  6158. + MD5_STEP(MD5_F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  6159. + MD5_STEP(MD5_F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  6160. + MD5_STEP(MD5_F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
  6161. + MD5_STEP(MD5_F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
  6162. + MD5_STEP(MD5_F3, b, c, d, a, in[6] + 0x04881d05, 23);
  6163. + MD5_STEP(MD5_F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
  6164. + MD5_STEP(MD5_F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  6165. + MD5_STEP(MD5_F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  6166. + MD5_STEP(MD5_F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
  6167. +
  6168. + MD5_STEP(MD5_F4, a, b, c, d, in[0] + 0xf4292244, 6);
  6169. + MD5_STEP(MD5_F4, d, a, b, c, in[7] + 0x432aff97, 10);
  6170. + MD5_STEP(MD5_F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  6171. + MD5_STEP(MD5_F4, b, c, d, a, in[5] + 0xfc93a039, 21);
  6172. + MD5_STEP(MD5_F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  6173. + MD5_STEP(MD5_F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
  6174. + MD5_STEP(MD5_F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  6175. + MD5_STEP(MD5_F4, b, c, d, a, in[1] + 0x85845dd1, 21);
  6176. + MD5_STEP(MD5_F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
  6177. + MD5_STEP(MD5_F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  6178. + MD5_STEP(MD5_F4, c, d, a, b, in[6] + 0xa3014314, 15);
  6179. + MD5_STEP(MD5_F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  6180. + MD5_STEP(MD5_F4, a, b, c, d, in[4] + 0xf7537e82, 6);
  6181. + MD5_STEP(MD5_F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  6182. + MD5_STEP(MD5_F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
  6183. + MD5_STEP(MD5_F4, b, c, d, a, in[9] + 0xeb86d391, 21);
  6184. +
  6185. + hash[0] += a;
  6186. + hash[1] += b;
  6187. + hash[2] += c;
  6188. + hash[3] += d;
  6189. +}
  6190. diff -pruN linux-2.4.27_orig/drivers/misc/md5.h linux-2.4.27/drivers/misc/md5.h
  6191. --- linux-2.4.27_orig/drivers/misc/md5.h 1970-01-01 01:00:00.000000000 +0100
  6192. +++ linux-2.4.27/drivers/misc/md5.h 2004-10-25 14:20:44.743000520 +0200
  6193. @@ -0,0 +1,11 @@
  6194. +/* md5.h */
  6195. +
  6196. +#include <linux/types.h>
  6197. +#include <linux/linkage.h>
  6198. +#include <linux/config.h>
  6199. +#include <linux/module.h>
  6200. +
  6201. +#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
  6202. + asmlinkage
  6203. +#endif
  6204. +extern void md5_transform_CPUbyteorder(u_int32_t *, u_int32_t const *);
  6205. diff -pruN linux-2.4.27_orig/include/linux/loop.h linux-2.4.27/include/linux/loop.h
  6206. --- linux-2.4.27_orig/include/linux/loop.h 2001-09-17 22:16:30.000000000 +0200
  6207. +++ linux-2.4.27/include/linux/loop.h 2004-10-25 14:20:44.744000368 +0200
  6208. @@ -17,6 +17,11 @@
  6209. #ifdef __KERNEL__
  6210. +/* definitions for IV metric -- cryptoapi specific */
  6211. +#define LOOP_IV_SECTOR_BITS 9
  6212. +#define LOOP_IV_SECTOR_SIZE (1 << LOOP_IV_SECTOR_BITS)
  6213. +typedef int loop_iv_t;
  6214. +
  6215. /* Possible states of device */
  6216. enum {
  6217. Lo_unbound,
  6218. @@ -27,35 +32,47 @@ enum {
  6219. struct loop_device {
  6220. int lo_number;
  6221. int lo_refcnt;
  6222. - kdev_t lo_device;
  6223. - int lo_offset;
  6224. + loff_t lo_offset;
  6225. + loff_t lo_sizelimit;
  6226. int lo_encrypt_type;
  6227. int lo_encrypt_key_size;
  6228. - int lo_flags;
  6229. int (*transfer)(struct loop_device *, int cmd,
  6230. char *raw_buf, char *loop_buf, int size,
  6231. int real_block);
  6232. + int (*ioctl)(struct loop_device *, int cmd,
  6233. + unsigned long arg);
  6234. char lo_name[LO_NAME_SIZE];
  6235. char lo_encrypt_key[LO_KEY_SIZE];
  6236. __u32 lo_init[2];
  6237. uid_t lo_key_owner; /* Who set the key */
  6238. - int (*ioctl)(struct loop_device *, int cmd,
  6239. - unsigned long arg);
  6240. + kdev_t lo_device;
  6241. + int lo_flags;
  6242. struct file * lo_backing_file;
  6243. - void *key_data;
  6244. + void *key_data;
  6245. char key_reserved[48]; /* for use by the filter modules */
  6246. int old_gfp_mask;
  6247. + int lo_state;
  6248. + struct buffer_head *lo_bh_que0;
  6249. + struct buffer_head *lo_bh_que1;
  6250. + struct buffer_head *lo_bh_que2;
  6251. + struct buffer_head *lo_bh_free;
  6252. spinlock_t lo_lock;
  6253. - struct buffer_head *lo_bh;
  6254. - struct buffer_head *lo_bhtail;
  6255. - int lo_state;
  6256. struct semaphore lo_sem;
  6257. struct semaphore lo_ctl_mutex;
  6258. - struct semaphore lo_bh_mutex;
  6259. atomic_t lo_pending;
  6260. + int lo_bh_flsh;
  6261. + int lo_bh_need;
  6262. + wait_queue_head_t lo_bh_wait;
  6263. + unsigned long lo_offs_sec;
  6264. + unsigned long lo_iv_remove;
  6265. + unsigned char lo_crypt_name[LO_NAME_SIZE];
  6266. +#if CONFIG_BLK_DEV_LOOP_KEYSCRUB
  6267. + void (*lo_keyscrub_fn)(void *);
  6268. + void *lo_keyscrub_ptr;
  6269. +#endif
  6270. };
  6271. typedef int (* transfer_proc_t)(struct loop_device *, int cmd,
  6272. @@ -77,20 +94,19 @@ static inline int lo_do_transfer(struct
  6273. */
  6274. #define LO_FLAGS_DO_BMAP 1
  6275. #define LO_FLAGS_READ_ONLY 2
  6276. -#define LO_FLAGS_BH_REMAP 4
  6277. -/*
  6278. +/*
  6279. * Note that this structure gets the wrong offsets when directly used
  6280. * from a glibc program, because glibc has a 32bit dev_t.
  6281. - * Prevent people from shooting in their own foot.
  6282. + * Prevent people from shooting in their own foot.
  6283. */
  6284. #if __GLIBC__ >= 2 && !defined(dev_t)
  6285. #error "Wrong dev_t in loop.h"
  6286. -#endif
  6287. +#endif
  6288. /*
  6289. * This uses kdev_t because glibc currently has no appropiate
  6290. - * conversion version for the loop ioctls.
  6291. + * conversion version for the loop ioctls.
  6292. * The situation is very unpleasant
  6293. */
  6294. @@ -109,6 +125,22 @@ struct loop_info {
  6295. char reserved[4];
  6296. };
  6297. +struct loop_info64 {
  6298. + __u64 lo_device; /* ioctl r/o */
  6299. + __u64 lo_inode; /* ioctl r/o */
  6300. + __u64 lo_rdevice; /* ioctl r/o */
  6301. + __u64 lo_offset;
  6302. + __u64 lo_sizelimit;/* bytes, 0 == max available */
  6303. + __u32 lo_number; /* ioctl r/o */
  6304. + __u32 lo_encrypt_type;
  6305. + __u32 lo_encrypt_key_size; /* ioctl w/o */
  6306. + __u32 lo_flags; /* ioctl r/o */
  6307. + __u8 lo_file_name[LO_NAME_SIZE];
  6308. + __u8 lo_crypt_name[LO_NAME_SIZE];
  6309. + __u8 lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
  6310. + __u64 lo_init[2];
  6311. +};
  6312. +
  6313. /*
  6314. * Loop filter types
  6315. */
  6316. @@ -122,25 +154,27 @@ struct loop_info {
  6317. #define LO_CRYPT_IDEA 6
  6318. #define LO_CRYPT_DUMMY 9
  6319. #define LO_CRYPT_SKIPJACK 10
  6320. +#define LO_CRYPT_AES 16
  6321. +#define LO_CRYPT_CRYPTOAPI 18
  6322. #define MAX_LO_CRYPT 20
  6323. #ifdef __KERNEL__
  6324. /* Support for loadable transfer modules */
  6325. struct loop_func_table {
  6326. - int number; /* filter type */
  6327. + int number; /* filter type */
  6328. int (*transfer)(struct loop_device *lo, int cmd, char *raw_buf,
  6329. char *loop_buf, int size, int real_block);
  6330. - int (*init)(struct loop_device *, struct loop_info *);
  6331. + int (*init)(struct loop_device *, struct loop_info *);
  6332. /* release is called from loop_unregister_transfer or clr_fd */
  6333. - int (*release)(struct loop_device *);
  6334. + int (*release)(struct loop_device *);
  6335. int (*ioctl)(struct loop_device *, int cmd, unsigned long arg);
  6336. - /* lock and unlock manage the module use counts */
  6337. + /* lock and unlock manage the module use counts */
  6338. void (*lock)(struct loop_device *);
  6339. void (*unlock)(struct loop_device *);
  6340. -};
  6341. +};
  6342. -int loop_register_transfer(struct loop_func_table *funcs);
  6343. -int loop_unregister_transfer(int number);
  6344. +int loop_register_transfer(struct loop_func_table *funcs);
  6345. +int loop_unregister_transfer(int number);
  6346. #endif
  6347. /*
  6348. @@ -151,5 +185,9 @@ int loop_unregister_transfer(int number)
  6349. #define LOOP_CLR_FD 0x4C01
  6350. #define LOOP_SET_STATUS 0x4C02
  6351. #define LOOP_GET_STATUS 0x4C03
  6352. +#define LOOP_SET_STATUS64 0x4C04
  6353. +#define LOOP_GET_STATUS64 0x4C05
  6354. +
  6355. +#define LOOP_MULTI_KEY_SETUP 0x4C4D
  6356. #endif