| [2] | 1 | |
|---|
| 2 | /* |
|---|
| 3 | * Multiple-Precision Modular Arithmetic Routines |
|---|
| 4 | * |
|---|
| 5 | * |
|---|
| 6 | * Change log: 07/17/02 - Created. |
|---|
| 7 | */ |
|---|
| 8 | |
|---|
| 9 | #if !defined(__MP2_H__) |
|---|
| 10 | #define __MP2_H__ |
|---|
| 11 | |
|---|
| 12 | #if !defined(RSA_BITS) |
|---|
| 13 | #define RSA_BITS 1024 |
|---|
| 14 | #endif |
|---|
| 15 | /* Data structure for big numbers */ |
|---|
| 16 | |
|---|
| 17 | typedef unsigned long * mp; /* we represent each mp number as an array of |
|---|
| 18 | * 30-bit long numbers (each group of 30-bit |
|---|
| 19 | * will be called a 'chunk') */ |
|---|
| 20 | /* Other types needed */ |
|---|
| 21 | typedef unsigned char u8; |
|---|
| 22 | typedef unsigned long u32; |
|---|
| 23 | typedef signed char s8; |
|---|
| 24 | typedef signed long s32; |
|---|
| 25 | |
|---|
| 26 | #define CHARL 8 /* number of bits in a byte */ |
|---|
| 27 | #define SIZEOFLONG 4 /* number of bytes in a long */ |
|---|
| 28 | #define BITSOFLONG (CHARL*SIZEOFLONG) /* number of bits in a long */ |
|---|
| 29 | |
|---|
| 30 | #define NBITS 30 /* number of bits used per chunk, |
|---|
| 31 | * It must be even and <32 */ |
|---|
| 32 | #define RADIX (1L << NBITS) /* this is 'b' in the algorithms */ |
|---|
| 33 | #define UNUSEDBITS (BITSOFLONG-NBITS) /* no. bits unused in chunk */ |
|---|
| 34 | |
|---|
| 35 | #define NBITSH (NBITS >> 1L) /* half the number of bits/chunk */ |
|---|
| 36 | #define RADIXM (RADIX-1) /* RADIX mask */ |
|---|
| 37 | #define RADIXROOT (1L<<NBITSH) /* "RADIX" for half chunk */ |
|---|
| 38 | #define RADIXROOTM (RADIXROOT-1) /* RADIXROOT mask */ |
|---|
| 39 | #define NBITSM1 (NBITS-1) |
|---|
| 40 | #define MSBMASK (1L << NBITSM1) /* most significant bit mask */ |
|---|
| 41 | #define MASK RADIXM /* marks which bits are used in chunk */ |
|---|
| 42 | |
|---|
| 43 | #define MPSIZE RSA_BITS /* size in bits of mp numbers */ |
|---|
| 44 | #define SIZE ((MPSIZE+NBITS-1)/NBITS)+1 /* size in chunks of mp numbers */ |
|---|
| 45 | #define EXTSIZE (SIZE+2) /* include space to store actual size */ |
|---|
| 46 | #define LONGEXTSIZE ((EXTSIZE*2)+2) /* for temp results in multiplications */ |
|---|
| 47 | |
|---|
| 48 | #define OK 0xFE0AF2FAUL /* RSA signature verifies OK */ |
|---|
| 49 | #define BAD 0x01 /* RSA sig NOT ok. */ |
|---|
| 50 | /* (it must be != OK ) */ |
|---|
| 51 | |
|---|
| 52 | //#define CACHE_RSA_ADDRESS 0x800094 |
|---|
| 53 | |
|---|
| 54 | /* Layout of mp numbers: |
|---|
| 55 | Consider 'a' is a mp number (eg. 'mp a;') |
|---|
| 56 | - |a[0]| stores the actual size (in 32-bit words), say n. |
|---|
| 57 | - a[1] ... a[n] stores the big number, a[1] is the least significant digit |
|---|
| 58 | |
|---|
| 59 | The absolute value of the number represented by 'a' is |
|---|
| 60 | the sum over i=1..n of a[i]*2^((i-1)*NBITS). |
|---|
| 61 | The sign of this number is the sign of a[0] [Note: most of the time, only |
|---|
| 62 | positive numbers are used] |
|---|
| 63 | |
|---|
| 64 | Memory Allocation: |
|---|
| 65 | Numbers allocate either EXTSIZE or LONGEXTSIZE 32-bit words. |
|---|
| 66 | |
|---|
| 67 | Zeroize at init: a[0]= 1; a[1] = 0; |
|---|
| 68 | */ |
|---|
| 69 | |
|---|
| 70 | /* Arithmetic Operations */ |
|---|
| 71 | |
|---|
| 72 | /* Comparison of two numbers */ |
|---|
| 73 | s32 mpcompare (mp a, mp b); |
|---|
| 74 | |
|---|
| 75 | /* Addition of mp numbers: |
|---|
| 76 | * c = a + b */ |
|---|
| 77 | void mpadd (mp a, mp b, mp c); |
|---|
| 78 | |
|---|
| 79 | /* Substraction of mp numbers: |
|---|
| 80 | * c = a - b */ |
|---|
| 81 | void mpsub (mp a, mp b, mp c); |
|---|
| 82 | |
|---|
| 83 | /* Division (quotient, rest) of mp numbers: |
|---|
| 84 | * q = a / b ; r = a % b */ |
|---|
| 85 | int mpdiv (mp a, mp b, mp q, mp r); |
|---|
| 86 | |
|---|
| 87 | /* Multiplication of mp numbers: |
|---|
| 88 | * c = a * b */ |
|---|
| 89 | void mpmul(mp a, mp b, mp c); |
|---|
| 90 | |
|---|
| 91 | /* Left shift a by k units of 30-bits. |
|---|
| 92 | * b = a << 32*k */ |
|---|
| 93 | void mpclshift (mp a, u32 k, mp b); |
|---|
| 94 | |
|---|
| 95 | /* RSA Signature Verification (RSA Encryption) */ |
|---|
| 96 | int rsa (void *input, void *pubkey, void *digest); |
|---|
| 97 | |
|---|
| 98 | /* Internal functions */ |
|---|
| 99 | |
|---|
| 100 | /* w = (w + c + x * y) / RADIX; |
|---|
| 101 | * c = (w + c + x * y) % RADIX; |
|---|
| 102 | */ |
|---|
| 103 | void addmul(u32 * w, u32* c, u32 x, u32 y); |
|---|
| 104 | /* smalldiv returns 'q' and 'r' so |
|---|
| 105 | * q = (hi*RADIX + lo)/d; |
|---|
| 106 | * r = (hi*RADIX + lo)%d; |
|---|
| 107 | * Assumes 0 <= hi < d < RADIX and 0 <= lo < RADIX. |
|---|
| 108 | */ |
|---|
| 109 | int smalldiv (u32 hi, u32 lo, u32 d, u32 *q, u32 *r); |
|---|
| 110 | |
|---|
| 111 | void mpcopy (mp a, mp b); |
|---|
| 112 | void mpzero (mp a); |
|---|
| 113 | |
|---|
| 114 | /* Macros */ |
|---|
| 115 | |
|---|
| 116 | #define MAX(a,b) ((a>b)? a: b) |
|---|
| 117 | |
|---|
| 118 | /* Swaps two mp numbers */ |
|---|
| 119 | #define mpswap(a,b) \ |
|---|
| 120 | { \ |
|---|
| 121 | mp tmp = a; \ |
|---|
| 122 | a = b; \ |
|---|
| 123 | b = tmp; \ |
|---|
| 124 | } |
|---|
| 125 | |
|---|
| 126 | #if 0 |
|---|
| 127 | /* May use BCM-MIPS32-01 CTZ instruction instead */ |
|---|
| 128 | #define CLZ(rd, rs) \ |
|---|
| 129 | { \ |
|---|
| 130 | s32 _i=0; \ |
|---|
| 131 | rd = 32; \ |
|---|
| 132 | for (_i=31; _i>=0; _i--)\ |
|---|
| 133 | if (rs & (1L << _i)) \ |
|---|
| 134 | { \ |
|---|
| 135 | rd = 31-_i; \ |
|---|
| 136 | break; \ |
|---|
| 137 | } \ |
|---|
| 138 | } |
|---|
| 139 | #else |
|---|
| 140 | #define CLZ(rd, rs) __asm__("clz %0,%1":"=r"(rd):"r"(rs)) |
|---|
| 141 | #endif |
|---|
| 142 | |
|---|
| 143 | #define iszero(a) ( *(a)==1L && (a)[1] == 0L ) |
|---|
| 144 | #define sign(a) ( ((a)>0)? 1: ((a)<0)? -1: 0 ) |
|---|
| 145 | |
|---|
| 146 | #define ROTL32(a,n) (((a) << (n)) \ |
|---|
| 147 | | ((a) >> (32 - (n)))) |
|---|
| 148 | #define ROTR32(a,n) (((a) << (32-(n))) | (((unsigned long)(a)) >> (n))) |
|---|
| 149 | |
|---|
| 150 | |
|---|
| 151 | /* Endianness Conversion (taken from nessie.h) */ |
|---|
| 152 | |
|---|
| 153 | |
|---|
| 154 | #define BIG_ENDIAN |
|---|
| 155 | |
|---|
| 156 | #define ONE8 0xffU |
|---|
| 157 | #define T8(x) ((x) & ONE8) |
|---|
| 158 | |
|---|
| 159 | #ifdef BIG_ENDIAN |
|---|
| 160 | /* |
|---|
| 161 | * U8TO32_BIG(c) returns the 32-bit value stored in big-endian convention |
|---|
| 162 | * in the unsigned char array pointed to by c. |
|---|
| 163 | */ |
|---|
| 164 | |
|---|
| 165 | /* TODO: Replace with BCM-MIPS32-01 big-endian load instructions */ |
|---|
| 166 | #define U8TO32_BIG(c) (((u32)T8(*((c) + 3 )) << 24) | ((u32)T8(*((c) + 2)) << 16) | \ |
|---|
| 167 | ((u32)T8(*((c) + 1)) << 8) | ((u32)T8(*((c))))) |
|---|
| 168 | |
|---|
| 169 | #define CONVERT(c) (((u32)T8(*(c)) << 24) | ((u32)T8(*((c) + 1)) << 16) | \ |
|---|
| 170 | ((u32)T8(*((c) + 2)) << 8) | ((u32)T8(*((c) + 3)))) |
|---|
| 171 | /* |
|---|
| 172 | * U32TO8_BIG(c, v) stores the 32-bit-value v in big-endian convention |
|---|
| 173 | * into the unsigned char array pointed to by c. |
|---|
| 174 | */ |
|---|
| 175 | /* TODO: Replace with BCM-MIPS32-01 big-endian store instruction */ |
|---|
| 176 | #define U32TO8_BIG(c, v) do { \ |
|---|
| 177 | u32 x = (v); \ |
|---|
| 178 | u8 *d = (c); \ |
|---|
| 179 | d[3] = T8(x >> 24); \ |
|---|
| 180 | d[2] = T8(x >> 16); \ |
|---|
| 181 | d[1] = T8(x >> 8); \ |
|---|
| 182 | d[0] = T8(x); \ |
|---|
| 183 | } while (0) |
|---|
| 184 | |
|---|
| 185 | #else |
|---|
| 186 | |
|---|
| 187 | #define U8TO32_BIG(c) (((u32)T8(*(c)) << 24) | ((u32)T8(*((c) + 1)) << 16) | \ |
|---|
| 188 | ((u32)T8(*((c) + 2)) << 8) | ((u32)T8(*((c) + 3)))) |
|---|
| 189 | #define U32TO8_BIG(c, v) do { \ |
|---|
| 190 | u32 x = (v); \ |
|---|
| 191 | u8 *d = (c); \ |
|---|
| 192 | d[0] = T8(x >> 24); \ |
|---|
| 193 | d[1] = T8(x >> 16); \ |
|---|
| 194 | d[2] = T8(x >> 8); \ |
|---|
| 195 | d[3] = T8(x); \ |
|---|
| 196 | } while (0) |
|---|
| 197 | #endif |
|---|
| 198 | |
|---|
| 199 | void mpclshift (mp a, u32 k, mp b); |
|---|
| 200 | void mplshift (mp a, u32 k, mp b); |
|---|
| 201 | void mprshift (mp a, u32 k, mp b); |
|---|
| 202 | void unpack (mp src30, u32 *dest32, u32 n); |
|---|
| 203 | void pack (u32 *src32, mp dest30, u32 n); |
|---|
| 204 | |
|---|
| 205 | /* |
|---|
| 206 | RSA 1024 decryption function. |
|---|
| 207 | All pointers must be 4 bytes aligned as this function will access data as |
|---|
| 208 | unsigned int type. Failure to align data will result in unaligned access |
|---|
| 209 | exception. |
|---|
| 210 | */ |
|---|
| 211 | int rsa_decrypt (unsigned long * in, unsigned long * pubkey, unsigned long * decrypted_digest); |
|---|
| 212 | |
|---|
| 213 | /* |
|---|
| 214 | RSA 1024 RAW decryption function. Does not check padding. |
|---|
| 215 | All pointers must be 4 bytes aligned as this function will access data as |
|---|
| 216 | unsigned int type. Failure to align data will result in unaligned access |
|---|
| 217 | exception. |
|---|
| 218 | */ |
|---|
| 219 | int rsa_decrypt_raw (unsigned long * in, unsigned long * pubkey, unsigned long * out); |
|---|
| 220 | |
|---|
| 221 | #endif |
|---|
| 222 | |
|---|
| 223 | /* Please do not remove! */ |
|---|
| 224 | /* Local Variables: */ |
|---|
| 225 | /* mode: C */ |
|---|
| 226 | /* indent-tabs-mode: nil */ |
|---|
| 227 | /* End: */ |
|---|
| 228 | |
|---|