Author: dchapyshev Date: Thu Feb 26 13:29:58 2009 New Revision: 39764
URL: http://svn.reactos.org/svn/reactos?rev=39764&view=rev Log: - Sync rsaenh, shdocvw, shlwapi with Wine head
Modified: trunk/reactos/dll/win32/rsaenh/handle.c trunk/reactos/dll/win32/rsaenh/handle.h trunk/reactos/dll/win32/rsaenh/mpi.c trunk/reactos/dll/win32/rsaenh/rsaenh.c trunk/reactos/dll/win32/rsaenh/tomcrypt.h trunk/reactos/dll/win32/shdocvw/oleobject.c trunk/reactos/dll/win32/shlwapi/shlwapi.rc
Modified: trunk/reactos/dll/win32/rsaenh/handle.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/rsaenh/handle.c?r... ============================================================================== --- trunk/reactos/dll/win32/rsaenh/handle.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/rsaenh/handle.c [iso-8859-1] Thu Feb 26 13:29:58 2009 @@ -44,13 +44,10 @@ * lpTable [I] Pointer to the HANDLETABLE structure, which is to be initalized. * * NOTES - * Note that alloc_handle_table calls init_handle_table on it's own, which - * means that you only have to call init_handle_table, if you use a global - * variable of type HANDLETABLE for your handle table. However, in this - * case you have to call destroy_handle_table when you don't need the table + * You have to call destroy_handle_table when you don't need the table * any more. */ -void init_handle_table(HANDLETABLE *lpTable) +void init_handle_table(struct handle_table *lpTable) { TRACE("(lpTable=%p)\n", lpTable);
@@ -68,11 +65,8 @@ * * PARAMS * lpTable [I] Pointer to the handle table, which is to be destroyed. - * - * NOTES - * Note that release_handle_table takes care of this. - */ -void destroy_handle_table(HANDLETABLE *lpTable) + */ +void destroy_handle_table(struct handle_table *lpTable) { TRACE("(lpTable=%p)\n", lpTable);
@@ -96,7 +90,7 @@ * non zero, if handle is valid. * zero, if handle is not valid. */ -int is_valid_handle(HANDLETABLE *lpTable, HCRYPTKEY handle, DWORD dwType) +int is_valid_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType) { unsigned int index = HANDLE2INDEX(handle); int ret = 0; @@ -124,82 +118,6 @@ }
/****************************************************************************** - * release_all_handles - * - * Releases all valid handles in the given handle table and shrinks the table - * to zero size. - * - * PARAMS - * lpTable [I] The table of which all valid handles shall be released. - */ -static void release_all_handles(HANDLETABLE *lpTable) -{ - unsigned int i; - - TRACE("(lpTable=%p)\n", lpTable); - - EnterCriticalSection(&lpTable->mutex); - for (i=0; i<lpTable->iEntries; i++) - if (lpTable->paEntries[i].pObject) - release_handle(lpTable, lpTable->paEntries[i].pObject->dwType, INDEX2HANDLE(i)); - LeaveCriticalSection(&lpTable->mutex); -} - -/****************************************************************************** - * alloc_handle_table - * - * Allocates a new handle table - * - * PARAMS - * lplpTable [O] Pointer to the variable, to which the pointer to the newly - * allocated handle table is written. - * RETURNS - * non zero, if successful - * zero, if not successful (out of process heap memory) - * - * NOTES - * If all you need is a single handle table, you may as well declare a global - * variable of type HANDLETABLE and call init_handle_table on your own. - */ -int alloc_handle_table(HANDLETABLE **lplpTable) -{ - TRACE("(lplpTable=%p)\n", lplpTable); - - *lplpTable = HeapAlloc(GetProcessHeap(), 0, sizeof(HANDLETABLE)); - if (*lplpTable) - { - init_handle_table(*lplpTable); - return 1; - } - else - return 0; -} - -/****************************************************************************** - * release_handle_table - * - * Releases a handle table and frees the resources it used. - * - * PARAMS - * lpTable [I] Pointer to the handle table, which is to be released. - * - * RETURNS - * non zero, if successful - * zero, if not successful - * - * NOTES - * All valid handles still in the table are released also. - */ -int release_handle_table(HANDLETABLE *lpTable) -{ - TRACE("(lpTable=%p)\n", lpTable); - - release_all_handles(lpTable); - destroy_handle_table(lpTable); - return HeapFree(GetProcessHeap(), 0, lpTable); -} - -/****************************************************************************** * grow_handle_table [Internal] * * Grows the number of entries in the given table by TABLE_SIZE_INCREMENT @@ -214,20 +132,20 @@ * NOTES * This is a support function for alloc_handle. Do not call! */ -static int grow_handle_table(HANDLETABLE *lpTable) -{ - HANDLETABLEENTRY *newEntries; +static int grow_handle_table(struct handle_table *lpTable) +{ + struct handle_table_entry *newEntries; unsigned int i, newIEntries;
newIEntries = lpTable->iEntries + TABLE_SIZE_INCREMENT;
- newEntries = HeapAlloc(GetProcessHeap(), 0, sizeof(HANDLETABLEENTRY)*newIEntries); + newEntries = HeapAlloc(GetProcessHeap(), 0, sizeof(struct handle_table_entry)*newIEntries); if (!newEntries) return 0;
if (lpTable->paEntries) { - memcpy(newEntries, lpTable->paEntries, sizeof(HANDLETABLEENTRY)*lpTable->iEntries); + memcpy(newEntries, lpTable->paEntries, sizeof(struct handle_table_entry)*lpTable->iEntries); HeapFree(GetProcessHeap(), 0, lpTable->paEntries); }
@@ -259,7 +177,7 @@ * non zero, if successful * zero, if not successful (no free handle) */ -static int alloc_handle(HANDLETABLE *lpTable, OBJECTHDR *lpObject, HCRYPTKEY *lpHandle) +static int alloc_handle(struct handle_table *lpTable, OBJECTHDR *lpObject, HCRYPTKEY *lpHandle) { int ret = 0;
@@ -306,7 +224,7 @@ * non zero, if successful * zero, if not successful (invalid handle) */ -int release_handle(HANDLETABLE *lpTable, HCRYPTKEY handle, DWORD dwType) +int release_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType) { unsigned int index = HANDLE2INDEX(handle); OBJECTHDR *pObject; @@ -351,7 +269,7 @@ * non zero, if successful * zero, if not successful (invalid handle) */ -int lookup_handle(HANDLETABLE *lpTable, HCRYPTKEY handle, DWORD dwType, OBJECTHDR **lplpObject) +int lookup_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, OBJECTHDR **lplpObject) { int ret = 0;
@@ -386,7 +304,7 @@ * non zero, if successful * zero, if not successful (invalid handle or out of memory) */ -int copy_handle(HANDLETABLE *lpTable, HCRYPTKEY handle, DWORD dwType, HCRYPTKEY *copy) +int copy_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, HCRYPTKEY *copy) { OBJECTHDR *pObject; int ret; @@ -429,7 +347,7 @@ * INVALID_HANDLE_VALUE, if something went wrong. * a handle to the new object, if successful. */ -HCRYPTKEY new_object(HANDLETABLE *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor, +HCRYPTKEY new_object(struct handle_table *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor, OBJECTHDR **ppObject) { OBJECTHDR *pObject;
Modified: trunk/reactos/dll/win32/rsaenh/handle.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/rsaenh/handle.h?r... ============================================================================== --- trunk/reactos/dll/win32/rsaenh/handle.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/rsaenh/handle.h [iso-8859-1] Thu Feb 26 13:29:58 2009 @@ -42,34 +42,28 @@ DESTRUCTOR destructor; };
-typedef struct tagHANDLETABLEENTRY +struct handle_table_entry { OBJECTHDR *pObject; unsigned int iNextFree; -} HANDLETABLEENTRY; +};
-/* Prevent conflict with wingdi.h */ -#define tagHANDLETABLE tagHANDLETABLE_RSA -#define HANDLETABLE HANDLETABLE_RSA - -typedef struct tagHANDLETABLE +struct handle_table { unsigned int iEntries; unsigned int iFirstFree; - HANDLETABLEENTRY *paEntries; + struct handle_table_entry *paEntries; CRITICAL_SECTION mutex; -} HANDLETABLE; +};
-int alloc_handle_table (HANDLETABLE **lplpTable); -void init_handle_table (HANDLETABLE *lpTable); -int release_handle_table(HANDLETABLE *lpTable); -void destroy_handle_table(HANDLETABLE *lpTable); -int release_handle (HANDLETABLE *lpTable, HCRYPTKEY handle, DWORD dwType); -int copy_handle (HANDLETABLE *lpTable, HCRYPTKEY handle, DWORD dwType, HCRYPTKEY *copy); -int lookup_handle (HANDLETABLE *lpTable, HCRYPTKEY handle, DWORD dwType, OBJECTHDR **lplpObject); -int is_valid_handle (HANDLETABLE *lpTable, HCRYPTKEY handle, DWORD dwType); +void init_handle_table (struct handle_table *lpTable); +void destroy_handle_table(struct handle_table *lpTable); +int release_handle (struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType); +int copy_handle (struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, HCRYPTKEY *copy); +int lookup_handle (struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, OBJECTHDR **lplpObject); +int is_valid_handle (struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType);
-HCRYPTKEY new_object (HANDLETABLE *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor, +HCRYPTKEY new_object (struct handle_table *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor, OBJECTHDR **ppObject);
#ifdef __cplusplus
Modified: trunk/reactos/dll/win32/rsaenh/mpi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/rsaenh/mpi.c?rev=... ============================================================================== --- trunk/reactos/dll/win32/rsaenh/mpi.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/rsaenh/mpi.c [iso-8859-1] Thu Feb 26 13:29:58 2009 @@ -29,6 +29,9 @@ */
#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" #include "tomcrypt.h"
/* Known optimal configurations @@ -51,6 +54,208 @@ static int mp_invmod_slow (const mp_int * a, mp_int * b, mp_int * c); static int mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c); static int mp_karatsuba_sqr(const mp_int *a, mp_int *b); + +/* grow as required */ +static int mp_grow (mp_int * a, int size) +{ + int i; + mp_digit *tmp; + + /* if the alloc size is smaller alloc more ram */ + if (a->alloc < size) { + /* ensure there are always at least MP_PREC digits extra on top */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* reallocate the array a->dp + * + * We store the return in a temporary variable + * in case the operation failed we don't want + * to overwrite the dp member of a. + */ + tmp = HeapReAlloc(GetProcessHeap(), 0, a->dp, sizeof (mp_digit) * size); + if (tmp == NULL) { + /* reallocation failed but "a" is still valid [can be freed] */ + return MP_MEM; + } + + /* reallocation succeeded so set a->dp */ + a->dp = tmp; + + /* zero excess digits */ + i = a->alloc; + a->alloc = size; + for (; i < a->alloc; i++) { + a->dp[i] = 0; + } + } + return MP_OKAY; +} + +/* b = a/2 */ +static int mp_div_2(const mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* copy */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* source alias */ + tmpa = a->dp + b->used - 1; + + /* dest alias */ + tmpb = b->dp + b->used - 1; + + /* carry */ + r = 0; + for (x = b->used - 1; x >= 0; x--) { + /* get the carry for the next iteration */ + rr = *tmpa & 1; + + /* shift the current digit, add in carry and store */ + *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); + + /* forward carry to next iteration */ + r = rr; + } + + /* zero excess digits */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + mp_clamp (b); + return MP_OKAY; +} + +/* swap the elements of two integers, for cases where you can't simply swap the + * mp_int pointers around + */ +static void +mp_exch (mp_int * a, mp_int * b) +{ + mp_int t; + + t = *a; + *a = *b; + *b = t; +} + +/* init a new mp_int */ +static int mp_init (mp_int * a) +{ + int i; + + /* allocate memory required and clear it */ + a->dp = HeapAlloc(GetProcessHeap(), 0, sizeof (mp_digit) * MP_PREC); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the digits to zero */ + for (i = 0; i < MP_PREC; i++) { + a->dp[i] = 0; + } + + /* set the used to zero, allocated digits to the default precision + * and sign to positive */ + a->used = 0; + a->alloc = MP_PREC; + a->sign = MP_ZPOS; + + return MP_OKAY; +} + +/* init an mp_init for a given size */ +static int mp_init_size (mp_int * a, int size) +{ + int x; + + /* pad size so there are always extra digits */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* alloc mem */ + a->dp = HeapAlloc(GetProcessHeap(), 0, sizeof (mp_digit) * size); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the members */ + a->used = 0; + a->alloc = size; + a->sign = MP_ZPOS; + + /* zero the digits */ + for (x = 0; x < size; x++) { + a->dp[x] = 0; + } + + return MP_OKAY; +} + +/* clear one (frees) */ +static void +mp_clear (mp_int * a) +{ + int i; + + /* only do anything if a hasn't been freed previously */ + if (a->dp != NULL) { + /* first zero the digits */ + for (i = 0; i < a->used; i++) { + a->dp[i] = 0; + } + + /* free ram */ + HeapFree(GetProcessHeap(), 0, a->dp); + + /* reset members to make debugging easier */ + a->dp = NULL; + a->alloc = a->used = 0; + a->sign = MP_ZPOS; + } +} + +/* set to zero */ +static void +mp_zero (mp_int * a) +{ + a->sign = MP_ZPOS; + a->used = 0; + memset (a->dp, 0, sizeof (mp_digit) * a->alloc); +} + +/* b = |a| + * + * Simple function copies the input and fixes the sign to positive + */ +static int +mp_abs (const mp_int * a, mp_int * b) +{ + int res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + /* force the sign of b to positive */ + b->sign = MP_ZPOS; + + return MP_OKAY; +}
/* computes the modular inverse via binary extended euclidean algorithm, * that is c = 1/a mod b @@ -613,7 +818,7 @@ * Simple algorithm which zeroes the int, grows it then just sets one bit * as required. */ -int +static int mp_2expt (mp_int * a, int b) { int res; @@ -631,28 +836,6 @@
/* put the single bit in its place */ a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); - - return MP_OKAY; -} - -/* b = |a| - * - * Simple function copies the input and fixes the sign to positive - */ -int -mp_abs (const mp_int * a, mp_int * b) -{ - int res; - - /* copy a to b */ - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } - - /* force the sign of b to positive */ - b->sign = MP_ZPOS;
return MP_OKAY; } @@ -690,7 +873,7 @@
/* single digit addition */ -int +static int mp_add_d (mp_int * a, mp_digit b, mp_int * c) { int res, ix, oldused; @@ -799,30 +982,6 @@ } }
-/* clear one (frees) */ -void -mp_clear (mp_int * a) -{ - int i; - - /* only do anything if a hasn't been freed previously */ - if (a->dp != NULL) { - /* first zero the digits */ - for (i = 0; i < a->used; i++) { - a->dp[i] = 0; - } - - /* free ram */ - free(a->dp); - - /* reset members to make debugging easier */ - a->dp = NULL; - a->alloc = a->used = 0; - a->sign = MP_ZPOS; - } -} - - void mp_clear_multi(mp_int *mp, ...) { mp_int* next_mp = mp; @@ -1016,6 +1175,333 @@ return r; }
+/* calc a value mod 2**b */ +static int +mp_mod_2d (const mp_int * a, int b, mp_int * c) +{ + int x, res; + + /* if b is <= 0 then zero the int */ + if (b <= 0) { + mp_zero (c); + return MP_OKAY; + } + + /* if the modulus is larger than the value than return */ + if (b > a->used * DIGIT_BIT) { + res = mp_copy (a, c); + return res; + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + + /* zero digits above the last digit of the modulus */ + for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { + c->dp[x] = 0; + } + /* clear the digit that is not completely outside/inside the modulus */ + c->dp[b / DIGIT_BIT] &= (1 << ((mp_digit)b % DIGIT_BIT)) - 1; + mp_clamp (c); + return MP_OKAY; +} + +/* shift right a certain amount of digits */ +static void mp_rshd (mp_int * a, int b) +{ + int x; + + /* if b <= 0 then ignore it */ + if (b <= 0) { + return; + } + + /* if b > used then simply zero it and return */ + if (a->used <= b) { + mp_zero (a); + return; + } + + { + register mp_digit *bottom, *top; + + /* shift the digits down */ + + /* bottom */ + bottom = a->dp; + + /* top [offset into digits] */ + top = a->dp + b; + + /* this is implemented as a sliding window where + * the window is b-digits long and digits from + * the top of the window are copied to the bottom + * + * e.g. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + -------------------/ ----> + */ + for (x = 0; x < (a->used - b); x++) { + *bottom++ = *top++; + } + + /* zero the top digits */ + for (; x < a->used; x++) { + *bottom++ = 0; + } + } + + /* remove excess digits */ + a->used -= b; +} + +/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ +static int mp_div_2d (const mp_int * a, int b, mp_int * c, mp_int * d) +{ + mp_digit D, r, rr; + int x, res; + mp_int t; + + + /* if the shift count is <= 0 then we do no work */ + if (b <= 0) { + res = mp_copy (a, c); + if (d != NULL) { + mp_zero (d); + } + return res; + } + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + /* get the remainder */ + if (d != NULL) { + if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + /* shift by as many digits in the bit count */ + if (b >= DIGIT_BIT) { + mp_rshd (c, b / DIGIT_BIT); + } + + /* shift any bit count < DIGIT_BIT */ + D = (mp_digit) (b % DIGIT_BIT); + if (D != 0) { + register mp_digit *tmpc, mask, shift; + + /* mask */ + mask = (((mp_digit)1) << D) - 1; + + /* shift for lsb */ + shift = DIGIT_BIT - D; + + /* alias */ + tmpc = c->dp + (c->used - 1); + + /* carry */ + r = 0; + for (x = c->used - 1; x >= 0; x--) { + /* get the lower bits of this word in a temp */ + rr = *tmpc & mask; + + /* shift the current word and mix in the carry bits from the previous word */ + *tmpc = (*tmpc >> D) | (r << shift); + --tmpc; + + /* set the carry to the carry bits of the current word found above */ + r = rr; + } + } + mp_clamp (c); + if (d != NULL) { + mp_exch (&t, d); + } + mp_clear (&t); + return MP_OKAY; +} + +/* shift left a certain amount of digits */ +static int mp_lshd (mp_int * a, int b) +{ + int x, res; + + /* if its less than zero return */ + if (b <= 0) { + return MP_OKAY; + } + + /* grow to fit the new digits */ + if (a->alloc < a->used + b) { + if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { + return res; + } + } + + { + register mp_digit *top, *bottom; + + /* increment the used by the shift amount then copy upwards */ + a->used += b; + + /* top */ + top = a->dp + a->used - 1; + + /* base */ + bottom = a->dp + a->used - 1 - b; + + /* much like mp_rshd this is implemented using a sliding window + * except the window goes the otherway around. Copying from + * the bottom to the top. see bn_mp_rshd.c for more info. + */ + for (x = a->used - 1; x >= b; x--) { + *top-- = *bottom--; + } + + /* zero the lower digits */ + top = a->dp; + for (x = 0; x < b; x++) { + *top++ = 0; + } + } + return MP_OKAY; +} + +/* shift left by a certain bit count */ +static int mp_mul_2d (const mp_int * a, int b, mp_int * c) +{ + mp_digit d; + int res; + + /* copy */ + if (a != c) { + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + } + + if (c->alloc < c->used + b/DIGIT_BIT + 1) { + if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + } + + /* shift by as many digits in the bit count */ + if (b >= DIGIT_BIT) { + if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { + return res; + } + } + + /* shift any bit count < DIGIT_BIT */ + d = (mp_digit) (b % DIGIT_BIT); + if (d != 0) { + register mp_digit *tmpc, shift, mask, r, rr; + register int x; + + /* bitmask for carries */ + mask = (((mp_digit)1) << d) - 1; + + /* shift for msbs */ + shift = DIGIT_BIT - d; + + /* alias */ + tmpc = c->dp; + + /* carry */ + r = 0; + for (x = 0; x < c->used; x++) { + /* get the higher bits of the current word */ + rr = (*tmpc >> shift) & mask; + + /* shift the current word and OR in the carry */ + *tmpc = ((*tmpc << d) | r) & MP_MASK; + ++tmpc; + + /* set the carry to the carry bits of the current word */ + r = rr; + } + + /* set final carry */ + if (r != 0) { + c->dp[(c->used)++] = r; + } + } + mp_clamp (c); + return MP_OKAY; +} + +/* multiply by a digit */ +static int +mp_mul_d (const mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit u, *tmpa, *tmpc; + mp_word r; + int ix, res, olduse; + + /* make sure c is big enough to hold a*b */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* get the original destinations used count */ + olduse = c->used; + + /* set the sign */ + c->sign = a->sign; + + /* alias for a->dp [source] */ + tmpa = a->dp; + + /* alias for c->dp [dest] */ + tmpc = c->dp; + + /* zero carry */ + u = 0; + + /* compute columns */ + for (ix = 0; ix < a->used; ix++) { + /* compute product and carry sum for this term */ + r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); + + /* mask off higher bits to get a single digit */ + *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* send carry into next iteration */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + + /* store final carry [if any] */ + *tmpc++ = u; + + /* now zero digits above the top */ + while (ix++ < olduse) { + *tmpc++ = 0; + } + + /* set used count */ + c->used = a->used + 1; + mp_clamp(c); + + return MP_OKAY; +} + /* integer signed division. * c*b + d == a [e.g. a/b, c=quotient, d=remainder] * HAC pp.598 Algorithm 14.20 @@ -1029,7 +1515,7 @@ * The overall algorithm is as described as * 14.20 from HAC but fixed to treat these cases. */ -int mp_div (const mp_int * a, const mp_int * b, mp_int * c, mp_int * d) +static int mp_div (const mp_int * a, const mp_int * b, mp_int * c, mp_int * d) { mp_int q, x, y, t1, t2; int res, n, t, i, norm, neg; @@ -1212,129 +1698,6 @@ return res; }
-/* b = a/2 */ -int mp_div_2(const mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* copy */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - { - register mp_digit r, rr, *tmpa, *tmpb; - - /* source alias */ - tmpa = a->dp + b->used - 1; - - /* dest alias */ - tmpb = b->dp + b->used - 1; - - /* carry */ - r = 0; - for (x = b->used - 1; x >= 0; x--) { - /* get the carry for the next iteration */ - rr = *tmpa & 1; - - /* shift the current digit, add in carry and store */ - *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); - - /* forward carry to next iteration */ - r = rr; - } - - /* zero excess digits */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - mp_clamp (b); - return MP_OKAY; -} - -/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ -int mp_div_2d (const mp_int * a, int b, mp_int * c, mp_int * d) -{ - mp_digit D, r, rr; - int x, res; - mp_int t; - - - /* if the shift count is <= 0 then we do no work */ - if (b <= 0) { - res = mp_copy (a, c); - if (d != NULL) { - mp_zero (d); - } - return res; - } - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - /* get the remainder */ - if (d != NULL) { - if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - mp_clear (&t); - return res; - } - - /* shift by as many digits in the bit count */ - if (b >= DIGIT_BIT) { - mp_rshd (c, b / DIGIT_BIT); - } - - /* shift any bit count < DIGIT_BIT */ - D = (mp_digit) (b % DIGIT_BIT); - if (D != 0) { - register mp_digit *tmpc, mask, shift; - - /* mask */ - mask = (((mp_digit)1) << D) - 1; - - /* shift for lsb */ - shift = DIGIT_BIT - D; - - /* alias */ - tmpc = c->dp + (c->used - 1); - - /* carry */ - r = 0; - for (x = c->used - 1; x >= 0; x--) { - /* get the lower bits of this word in a temp */ - rr = *tmpc & mask; - - /* shift the current word and mix in the carry bits from the previous word */ - *tmpc = (*tmpc >> D) | (r << shift); - --tmpc; - - /* set the carry to the carry bits of the current word found above */ - r = rr; - } - } - mp_clamp (c); - if (d != NULL) { - mp_exch (&t, d); - } - mp_clear (&t); - return MP_OKAY; -} - static int s_is_power_of_two(mp_digit b, int *p) { int x; @@ -1349,7 +1712,7 @@ }
/* single digit division (based on routine from MPI) */ -int mp_div_d (const mp_int * a, mp_digit b, mp_int * c, mp_digit * d) +static int mp_div_d (const mp_int * a, mp_digit b, mp_int * c, mp_digit * d) { mp_int q; mp_word w; @@ -1430,7 +1793,7 @@ * * Input x must be in the range 0 <= x <= (n-1)**2 */ -int +static int mp_dr_reduce (mp_int * x, const mp_int * n, mp_digit k) { int err, i, m; @@ -1489,27 +1852,14 @@ return MP_OKAY; }
-/* determines the setup value */ -void mp_dr_setup(const mp_int *a, mp_digit *d) +/* sets the value of "d" required for mp_dr_reduce */ +static void mp_dr_setup(const mp_int *a, mp_digit *d) { /* the casts are required if DIGIT_BIT is one less than * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] */ *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - ((mp_word)a->dp[0])); -} - -/* swap the elements of two integers, for cases where you can't simply swap the - * mp_int pointers around - */ -void -mp_exch (mp_int * a, mp_int * b) -{ - mp_int t; - - t = *a; - *a = *b; - *b = t; }
/* this is a shell function that calls either the normal or Montgomery @@ -1941,67 +2291,6 @@
/* force result to 32-bits always so it is consistent on non 32-bit platforms */ return res & 0xFFFFFFFFUL; -} - -/* grow as required */ -int mp_grow (mp_int * a, int size) -{ - int i; - mp_digit *tmp; - - /* if the alloc size is smaller alloc more ram */ - if (a->alloc < size) { - /* ensure there are always at least MP_PREC digits extra on top */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* reallocate the array a->dp - * - * We store the return in a temporary variable - * in case the operation failed we don't want - * to overwrite the dp member of a. - */ - tmp = realloc (a->dp, sizeof (mp_digit) * size); - if (tmp == NULL) { - /* reallocation failed but "a" is still valid [can be freed] */ - return MP_MEM; - } - - /* reallocation succeeded so set a->dp */ - a->dp = tmp; - - /* zero excess digits */ - i = a->alloc; - a->alloc = size; - for (; i < a->alloc; i++) { - a->dp[i] = 0; - } - } - return MP_OKAY; -} - -/* init a new mp_int */ -int mp_init (mp_int * a) -{ - int i; - - /* allocate memory required and clear it */ - a->dp = malloc (sizeof (mp_digit) * MP_PREC); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the digits to zero */ - for (i = 0; i < MP_PREC; i++) { - a->dp[i] = 0; - } - - /* set the used to zero, allocated digits to the default precision - * and sign to positive */ - a->used = 0; - a->alloc = MP_PREC; - a->sign = MP_ZPOS; - - return MP_OKAY; }
/* creates "a" then copies b into it */ @@ -2051,33 +2340,6 @@ return res; /* Assumed ok, if error flagged above. */ }
-/* init an mp_init for a given size */ -int mp_init_size (mp_int * a, int size) -{ - int x; - - /* pad size so there are always extra digits */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* alloc mem */ - a->dp = malloc (sizeof (mp_digit) * size); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the members */ - a->used = 0; - a->alloc = size; - a->sign = MP_ZPOS; - - /* zero the digits */ - for (x = 0; x < size; x++) { - a->dp[x] = 0; - } - - return MP_OKAY; -} - /* hac 14.61, pp608 */ int mp_invmod (const mp_int * a, mp_int * b, mp_int * c) { @@ -2533,52 +2795,6 @@ return res; }
-/* shift left a certain amount of digits */ -int mp_lshd (mp_int * a, int b) -{ - int x, res; - - /* if its less than zero return */ - if (b <= 0) { - return MP_OKAY; - } - - /* grow to fit the new digits */ - if (a->alloc < a->used + b) { - if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { - return res; - } - } - - { - register mp_digit *top, *bottom; - - /* increment the used by the shift amount then copy upwards */ - a->used += b; - - /* top */ - top = a->dp + a->used - 1; - - /* base */ - bottom = a->dp + a->used - 1 - b; - - /* much like mp_rshd this is implemented using a sliding window - * except the window goes the otherway around. Copying from - * the bottom to the top. see bn_mp_rshd.c for more info. - */ - for (x = a->used - 1; x >= b; x--) { - *top-- = *bottom--; - } - - /* zero the lower digits */ - top = a->dp; - for (x = 0; x < b; x++) { - *top++ = 0; - } - } - return MP_OKAY; -} - /* c = a mod b, 0 <= c < b */ int mp_mod (const mp_int * a, mp_int * b, mp_int * c) @@ -2606,43 +2822,71 @@ return res; }
-/* calc a value mod 2**b */ -int -mp_mod_2d (const mp_int * a, int b, mp_int * c) -{ - int x, res; - - /* if b is <= 0 then zero the int */ - if (b <= 0) { - mp_zero (c); - return MP_OKAY; - } - - /* if the modulus is larger than the value than return */ - if (b > a->used * DIGIT_BIT) { - res = mp_copy (a, c); - return res; - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - - /* zero digits above the last digit of the modulus */ - for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { - c->dp[x] = 0; - } - /* clear the digit that is not completely outside/inside the modulus */ - c->dp[b / DIGIT_BIT] &= (1 << ((mp_digit)b % DIGIT_BIT)) - 1; - mp_clamp (c); +static int +mp_mod_d (const mp_int * a, mp_digit b, mp_digit * c) +{ + return mp_div_d(a, b, NULL, c); +} + +/* b = a*2 */ +static int mp_mul_2(const mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* grow to accommodate result */ + if (b->alloc < a->used + 1) { + if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* alias for source */ + tmpa = a->dp; + + /* alias for dest */ + tmpb = b->dp; + + /* carry */ + r = 0; + for (x = 0; x < a->used; x++) { + + /* get what will be the *next* carry bit from the + * MSB of the current digit + */ + rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); + + /* now shift up this digit, add in the carry [from the previous] */ + *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; + + /* copy the carry that would be from the source + * digit into the next iteration + */ + r = rr; + } + + /* new leading digit? */ + if (r != 0) { + /* add a MSB which is always 1 at this point */ + *tmpb = 1; + ++(b->used); + } + + /* now zero any excess digits on the destination + * that we didn't write to + */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; return MP_OKAY; -} - -int -mp_mod_d (const mp_int * a, mp_digit b, mp_digit * c) -{ - return mp_div_d(a, b, NULL, c); }
/* @@ -2842,188 +3086,6 @@ return res; }
-/* b = a*2 */ -int mp_mul_2(const mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* grow to accommodate result */ - if (b->alloc < a->used + 1) { - if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - - { - register mp_digit r, rr, *tmpa, *tmpb; - - /* alias for source */ - tmpa = a->dp; - - /* alias for dest */ - tmpb = b->dp; - - /* carry */ - r = 0; - for (x = 0; x < a->used; x++) { - - /* get what will be the *next* carry bit from the - * MSB of the current digit - */ - rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); - - /* now shift up this digit, add in the carry [from the previous] */ - *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; - - /* copy the carry that would be from the source - * digit into the next iteration - */ - r = rr; - } - - /* new leading digit? */ - if (r != 0) { - /* add a MSB which is always 1 at this point */ - *tmpb = 1; - ++(b->used); - } - - /* now zero any excess digits on the destination - * that we didn't write to - */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - return MP_OKAY; -} - -/* shift left by a certain bit count */ -int mp_mul_2d (const mp_int * a, int b, mp_int * c) -{ - mp_digit d; - int res; - - /* copy */ - if (a != c) { - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - } - - if (c->alloc < c->used + b/DIGIT_BIT + 1) { - if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { - return res; - } - } - - /* shift by as many digits in the bit count */ - if (b >= DIGIT_BIT) { - if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { - return res; - } - } - - /* shift any bit count < DIGIT_BIT */ - d = (mp_digit) (b % DIGIT_BIT); - if (d != 0) { - register mp_digit *tmpc, shift, mask, r, rr; - register int x; - - /* bitmask for carries */ - mask = (((mp_digit)1) << d) - 1; - - /* shift for msbs */ - shift = DIGIT_BIT - d; - - /* alias */ - tmpc = c->dp; - - /* carry */ - r = 0; - for (x = 0; x < c->used; x++) { - /* get the higher bits of the current word */ - rr = (*tmpc >> shift) & mask; - - /* shift the current word and OR in the carry */ - *tmpc = ((*tmpc << d) | r) & MP_MASK; - ++tmpc; - - /* set the carry to the carry bits of the current word */ - r = rr; - } - - /* set final carry */ - if (r != 0) { - c->dp[(c->used)++] = r; - } - } - mp_clamp (c); - return MP_OKAY; -} - -/* multiply by a digit */ -int -mp_mul_d (const mp_int * a, mp_digit b, mp_int * c) -{ - mp_digit u, *tmpa, *tmpc; - mp_word r; - int ix, res, olduse; - - /* make sure c is big enough to hold a*b */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* get the original destinations used count */ - olduse = c->used; - - /* set the sign */ - c->sign = a->sign; - - /* alias for a->dp [source] */ - tmpa = a->dp; - - /* alias for c->dp [dest] */ - tmpc = c->dp; - - /* zero carry */ - u = 0; - - /* compute columns */ - for (ix = 0; ix < a->used; ix++) { - /* compute product and carry sum for this term */ - r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); - - /* mask off higher bits to get a single digit */ - *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* send carry into next iteration */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - - /* store final carry [if any] */ - *tmpc++ = u; - - /* now zero digits above the top */ - while (ix++ < olduse) { - *tmpc++ = 0; - } - - /* set used count */ - c->used = a->used + 1; - mp_clamp(c); - - return MP_OKAY; -} - /* d = a * b (mod c) */ int mp_mulmod (const mp_int * a, const mp_int * b, mp_int * c, mp_int * d) @@ -3088,7 +3150,7 @@ * * sets result to 0 if not, 1 if yes */ -int mp_prime_is_divisible (const mp_int * a, int *result) +static int mp_prime_is_divisible (const mp_int * a, int *result) { int err, ix; mp_digit res; @@ -3112,68 +3174,6 @@ return MP_OKAY; }
-/* performs a variable number of rounds of Miller-Rabin - * - * Probability of error after t rounds is no more than - - * - * Sets result to 1 if probably prime, 0 otherwise - */ -int mp_prime_is_prime (mp_int * a, int t, int *result) -{ - mp_int b; - int ix, err, res; - - /* default to no */ - *result = MP_NO; - - /* valid value of t? */ - if (t <= 0 || t > PRIME_SIZE) { - return MP_VAL; - } - - /* is the input equal to one of the primes in the table? */ - for (ix = 0; ix < PRIME_SIZE; ix++) { - if (mp_cmp_d(a, __prime_tab[ix]) == MP_EQ) { - *result = 1; - return MP_OKAY; - } - } - - /* first perform trial division */ - if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { - return err; - } - - /* return if it was trivially divisible */ - if (res == MP_YES) { - return MP_OKAY; - } - - /* now perform the miller-rabin rounds */ - if ((err = mp_init (&b)) != MP_OKAY) { - return err; - } - - for (ix = 0; ix < t; ix++) { - /* set the prime */ - mp_set (&b, __prime_tab[ix]); - - if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { - goto __B; - } - - if (res == MP_NO) { - goto __B; - } - } - - /* passed the test */ - *result = MP_YES; -__B:mp_clear (&b); - return err; -} - /* Miller-Rabin test of "a" to the base of "b" as described in * HAC pp. 139 Algorithm 4.24 * @@ -3181,7 +3181,7 @@ * Randomly the chance of error is no more than 1/4 and often * very much lower. */ -int mp_prime_miller_rabin (mp_int * a, const mp_int * b, int *result) +static int mp_prime_miller_rabin (mp_int * a, const mp_int * b, int *result) { mp_int n1, y, r; int s, j, err; @@ -3253,6 +3253,68 @@ __Y:mp_clear (&y); __R:mp_clear (&r); __N1:mp_clear (&n1); + return err; +} + +/* performs a variable number of rounds of Miller-Rabin + * + * Probability of error after t rounds is no more than + + * + * Sets result to 1 if probably prime, 0 otherwise + */ +static int mp_prime_is_prime (mp_int * a, int t, int *result) +{ + mp_int b; + int ix, err, res; + + /* default to no */ + *result = MP_NO; + + /* valid value of t? */ + if (t <= 0 || t > PRIME_SIZE) { + return MP_VAL; + } + + /* is the input equal to one of the primes in the table? */ + for (ix = 0; ix < PRIME_SIZE; ix++) { + if (mp_cmp_d(a, __prime_tab[ix]) == MP_EQ) { + *result = 1; + return MP_OKAY; + } + } + + /* first perform trial division */ + if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { + return err; + } + + /* return if it was trivially divisible */ + if (res == MP_YES) { + return MP_OKAY; + } + + /* now perform the miller-rabin rounds */ + if ((err = mp_init (&b)) != MP_OKAY) { + return err; + } + + for (ix = 0; ix < t; ix++) { + /* set the prime */ + mp_set (&b, __prime_tab[ix]); + + if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { + goto __B; + } + + if (res == MP_NO) { + goto __B; + } + } + + /* passed the test */ + *result = MP_YES; +__B:mp_clear (&b); return err; }
@@ -3319,7 +3381,7 @@ bsize = (size>>3)+((size&7)?1:0);
/* we need a buffer of bsize bytes */ - tmp = malloc(bsize); + tmp = HeapAlloc(GetProcessHeap(), 0, bsize); if (tmp == NULL) { return MP_MEM; } @@ -3384,7 +3446,7 @@
err = MP_OKAY; error: - free(tmp); + HeapFree(GetProcessHeap(), 0, tmp); return err; }
@@ -3566,57 +3628,6 @@ return mp_div (a, b, a, NULL); }
-/* shift right a certain amount of digits */ -void mp_rshd (mp_int * a, int b) -{ - int x; - - /* if b <= 0 then ignore it */ - if (b <= 0) { - return; - } - - /* if b > used then simply zero it and return */ - if (a->used <= b) { - mp_zero (a); - return; - } - - { - register mp_digit *bottom, *top; - - /* shift the digits down */ - - /* bottom */ - bottom = a->dp; - - /* top [offset into digits] */ - top = a->dp + b; - - /* this is implemented as a sliding window where - * the window is b-digits long and digits from - * the top of the window are copied to the bottom - * - * e.g. - - b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> - /\ | ----> - -------------------/ ----> - */ - for (x = 0; x < (a->used - b); x++) { - *bottom++ = *top++; - } - - /* zero the top digits */ - for (; x < a->used; x++) { - *bottom++ = 0; - } - } - - /* remove excess digits */ - a->used -= b; -} - /* set to a digit */ void mp_set (mp_int * a, mp_digit b) { @@ -3657,7 +3668,7 @@ { mp_digit *tmp; if (a->alloc != a->used && a->used > 0) { - if ((tmp = realloc (a->dp, sizeof (mp_digit) * a->used)) == NULL) { + if ((tmp = HeapReAlloc(GetProcessHeap(), 0, a->dp, sizeof (mp_digit) * a->used)) == NULL) { return MP_MEM; } a->dp = tmp; @@ -3850,15 +3861,6 @@ return (size / 8 + ((size & 7) != 0 ? 1 : 0)); }
-/* set to zero */ -void -mp_zero (mp_int * a) -{ - a->sign = MP_ZPOS; - a->used = 0; - memset (a->dp, 0, sizeof (mp_digit) * a->alloc); -} - /* reverse an array, used for radix code */ static void bn_reverse (unsigned char *s, int len)
Modified: trunk/reactos/dll/win32/rsaenh/rsaenh.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/rsaenh/rsaenh.c?r... ============================================================================== --- trunk/reactos/dll/win32/rsaenh/rsaenh.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/rsaenh/rsaenh.c [iso-8859-1] Thu Feb 26 13:29:58 2009 @@ -34,9 +34,9 @@ #include "winbase.h" #include "winreg.h" #include "wincrypt.h" -#include "objbase.h" #include "handle.h" #include "implglue.h" +#include "objbase.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
@@ -311,24 +311,23 @@ HCRYPTHASH hHash );
-BOOL WINAPI -RSAENH_CPExportKey( - HCRYPTPROV hProv, - HCRYPTKEY hKey, +static BOOL crypt_export_key( + CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey, DWORD dwBlobType, DWORD dwFlags, + BOOL force, BYTE *pbData, DWORD *pdwDataLen );
-BOOL WINAPI -RSAENH_CPImportKey( +static BOOL import_key( HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, + BOOL fStoreKey, HCRYPTKEY *phKey );
@@ -344,7 +343,7 @@ /****************************************************************************** * CSP's handle table (used by all acquired key containers) */ -static HANDLETABLE handle_table; +static struct handle_table handle_table;
/****************************************************************************** * DllMain (RSAENH.@) @@ -755,7 +754,8 @@ * hProv [I] Handle to the provider to which the created key will belong. * aiAlgid [I] The new key shall use the crypto algorithm idenfied by aiAlgid. * dwFlags [I] Upper 16 bits give the key length. - * Lower 16 bits: CRYPT_CREATE_SALT, CRYPT_NO_SALT + * Lower 16 bits: CRYPT_EXPORTABLE, CRYPT_CREATE_SALT, + * CRYPT_NO_SALT * ppCryptKey [O] Pointer to the created key * * RETURNS @@ -836,6 +836,8 @@ pCryptKey->dwModeBits = 0; pCryptKey->dwPermissions = CRYPT_ENCRYPT | CRYPT_DECRYPT | CRYPT_READ | CRYPT_WRITE | CRYPT_MAC; + if (dwFlags & CRYPT_EXPORTABLE) + pCryptKey->dwPermissions |= CRYPT_EXPORT; pCryptKey->dwKeyLen = dwKeyLen >> 3; pCryptKey->dwEffectiveKeyLen = 0; if ((dwFlags & CRYPT_CREATE_SALT) || (dwKeyLen == 40 && !(dwFlags & CRYPT_NO_SALT))) @@ -888,6 +890,37 @@ }
/****************************************************************************** + * map_key_spec_to_key_pair_name [Internal] + * + * Returns the name of the registry value associated with a key spec. + * + * PARAMS + * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE + * + * RETURNS + * Success: Name of registry value. + * Failure: NULL + */ +static LPCSTR map_key_spec_to_key_pair_name(DWORD dwKeySpec) +{ + LPCSTR szValueName; + + switch (dwKeySpec) + { + case AT_KEYEXCHANGE: + szValueName = "KeyExchangeKeyPair"; + break; + case AT_SIGNATURE: + szValueName = "SignatureKeyPair"; + break; + default: + WARN("invalid key spec %d\n", dwKeySpec); + szValueName = NULL; + } + return szValueName; +} + +/****************************************************************************** * store_key_pair [Internal] * * Stores a key pair to the registry @@ -895,27 +928,29 @@ * PARAMS * hCryptKey [I] Handle to the key to be stored * hKey [I] Registry key where the key pair is to be stored - * szValueName [I] Registry value where key pair's value is to be stored + * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE * dwFlags [I] Flags for protecting the key */ -static void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, LPCSTR szValueName, DWORD dwFlags) -{ +static void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags) +{ + LPCSTR szValueName; DATA_BLOB blobIn, blobOut; CRYPTKEY *pKey; DWORD dwLen; BYTE *pbKey;
+ if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec))) + return; if (lookup_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pKey)) { - if (RSAENH_CPExportKey(pKey->hProv, hCryptKey, 0, PRIVATEKEYBLOB, 0, 0, - &dwLen)) + if (crypt_export_key(pKey, 0, PRIVATEKEYBLOB, 0, TRUE, 0, &dwLen)) { pbKey = HeapAlloc(GetProcessHeap(), 0, dwLen); if (pbKey) { - if (RSAENH_CPExportKey(pKey->hProv, hCryptKey, 0, - PRIVATEKEYBLOB, 0, pbKey, &dwLen)) + if (crypt_export_key(pKey, 0, PRIVATEKEYBLOB, 0, TRUE, pbKey, + &dwLen)) { blobIn.pbData = pbKey; blobIn.cbData = dwLen; @@ -931,8 +966,63 @@ HeapFree(GetProcessHeap(), 0, pbKey); } } - release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY); - } + } +} + +/****************************************************************************** + * map_key_spec_to_permissions_name [Internal] + * + * Returns the name of the registry value associated with the permissions for + * a key spec. + * + * PARAMS + * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE + * + * RETURNS + * Success: Name of registry value. + * Failure: NULL + */ +static LPCSTR map_key_spec_to_permissions_name(DWORD dwKeySpec) +{ + LPCSTR szValueName; + + switch (dwKeySpec) + { + case AT_KEYEXCHANGE: + szValueName = "KeyExchangePermissions"; + break; + case AT_SIGNATURE: + szValueName = "SignaturePermissions"; + break; + default: + WARN("invalid key spec %d\n", dwKeySpec); + szValueName = NULL; + } + return szValueName; +} + +/****************************************************************************** + * store_key_permissions [Internal] + * + * Stores a key's permissions to the registry + * + * PARAMS + * hCryptKey [I] Handle to the key whose permissions are to be stored + * hKey [I] Registry key where the key permissions are to be stored + * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE + */ +static void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec) +{ + LPCSTR szValueName; + CRYPTKEY *pKey; + + if (!(szValueName = map_key_spec_to_permissions_name(dwKeySpec))) + return; + if (lookup_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY, + (OBJECTHDR**)&pKey)) + RegSetValueExA(hKey, szValueName, 0, REG_DWORD, + (BYTE *)&pKey->dwPermissions, + sizeof(pKey->dwPermissions)); }
/****************************************************************************** @@ -1051,14 +1141,63 @@ if (create_container_key(pKeyContainer, KEY_WRITE, &hKey)) { store_key_pair(pKeyContainer->hKeyExchangeKeyPair, hKey, - "KeyExchangeKeyPair", dwFlags); + AT_KEYEXCHANGE, dwFlags); store_key_pair(pKeyContainer->hSignatureKeyPair, hKey, - "SignatureKeyPair", dwFlags); + AT_SIGNATURE, dwFlags); RegCloseKey(hKey); } }
/****************************************************************************** + * store_key_container_permissions [Internal] + * + * Stores key container's key permissions in a persistent location. + * + * PARAMS + * pKeyContainer [I] Pointer to the key container whose key permissions are to + * be saved + */ +static void store_key_container_permissions(KEYCONTAINER *pKeyContainer) +{ + HKEY hKey; + DWORD dwFlags; + + /* On WinXP, persistent keys are stored in a file located at: + * $AppData$\Microsoft\Crypto\RSA\$SID$\some_hex_string + */ + + if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET) + dwFlags = CRYPTPROTECT_LOCAL_MACHINE; + else + dwFlags = 0; + + if (create_container_key(pKeyContainer, KEY_WRITE, &hKey)) + { + store_key_permissions(pKeyContainer->hKeyExchangeKeyPair, hKey, + AT_KEYEXCHANGE); + store_key_permissions(pKeyContainer->hSignatureKeyPair, hKey, + AT_SIGNATURE); + RegCloseKey(hKey); + } +} + +/****************************************************************************** + * release_key_container_keys [Internal] + * + * Releases key container's keys. + * + * PARAMS + * pKeyContainer [I] Pointer to the key container whose keys are to be released. + */ +static void release_key_container_keys(KEYCONTAINER *pKeyContainer) +{ + release_handle(&handle_table, pKeyContainer->hKeyExchangeKeyPair, + RSAENH_MAGIC_KEY); + release_handle(&handle_table, pKeyContainer->hSignatureKeyPair, + RSAENH_MAGIC_KEY); +} + +/****************************************************************************** * destroy_key_container [Internal] * * Destructor for key containers. @@ -1071,7 +1210,11 @@ KEYCONTAINER *pKeyContainer = (KEYCONTAINER*)pObjectHdr;
if (!(pKeyContainer->dwFlags & CRYPT_VERIFYCONTEXT)) + { store_key_container_keys(pKeyContainer); + store_key_container_permissions(pKeyContainer); + release_key_container_keys(pKeyContainer); + } HeapFree( GetProcessHeap(), 0, pKeyContainer ); }
@@ -1139,17 +1282,20 @@ * PARAMS * hKeyContainer [I] Crypt provider to use to import the key * hKey [I] Registry key from which to read the key pair - * szValueName [I] Registry value from which to read the key pair's value + * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE * dwFlags [I] Flags for unprotecting the key * phCryptKey [O] Returned key */ -static BOOL read_key_value(HCRYPTPROV hKeyContainer, HKEY hKey, LPCSTR szValueName, DWORD dwFlags, HCRYPTKEY *phCryptKey) -{ +static BOOL read_key_value(HCRYPTPROV hKeyContainer, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags, HCRYPTKEY *phCryptKey) +{ + LPCSTR szValueName; DWORD dwValueType, dwLen; BYTE *pbKey; DATA_BLOB blobIn, blobOut; BOOL ret = FALSE;
+ if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec))) + return FALSE; if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType, NULL, &dwLen) == ERROR_SUCCESS) { @@ -1165,12 +1311,27 @@ if (CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL, dwFlags, &blobOut)) { - ret = RSAENH_CPImportKey(hKeyContainer, blobOut.pbData, blobOut.cbData, 0, 0, - phCryptKey); + ret = import_key(hKeyContainer, blobOut.pbData, blobOut.cbData, 0, 0, + FALSE, phCryptKey); LocalFree(blobOut.pbData); } } HeapFree(GetProcessHeap(), 0, pbKey); + } + } + if (ret) + { + CRYPTKEY *pKey; + + if (lookup_handle(&handle_table, *phCryptKey, RSAENH_MAGIC_KEY, + (OBJECTHDR**)&pKey)) + { + if ((szValueName = map_key_spec_to_permissions_name(dwKeySpec))) + { + dwLen = sizeof(pKey->dwPermissions); + RegQueryValueExA(hKey, szValueName, 0, NULL, + (BYTE *)&pKey->dwPermissions, &dwLen); + } } } return ret; @@ -1213,10 +1374,10 @@ (OBJECTHDR**)&pKeyContainer)) return (HCRYPTPROV)INVALID_HANDLE_VALUE;
- if (read_key_value(hKeyContainer, hKey, "KeyExchangeKeyPair", + if (read_key_value(hKeyContainer, hKey, AT_KEYEXCHANGE, dwProtectFlags, &hCryptKey)) pKeyContainer->hKeyExchangeKeyPair = hCryptKey; - if (read_key_value(hKeyContainer, hKey, "SignatureKeyPair", + if (read_key_value(hKeyContainer, hKey, AT_SIGNATURE, dwProtectFlags, &hCryptKey)) pKeyContainer->hSignatureKeyPair = hCryptKey; } @@ -2204,6 +2365,183 @@ return TRUE; }
+static BOOL crypt_export_simple(CRYPTKEY *pCryptKey, CRYPTKEY *pPubKey, + DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) +{ + BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData; + ALG_ID *pAlgid = (ALG_ID*)(pBlobHeader+1); + DWORD dwDataLen; + + if (!(GET_ALG_CLASS(pCryptKey->aiAlgid)&(ALG_CLASS_DATA_ENCRYPT|ALG_CLASS_MSG_ENCRYPT))) { + SetLastError(NTE_BAD_KEY); /* FIXME: error code? */ + return FALSE; + } + + dwDataLen = sizeof(BLOBHEADER) + sizeof(ALG_ID) + pPubKey->dwBlockLen; + if (pbData) { + if (*pdwDataLen < dwDataLen) { + SetLastError(ERROR_MORE_DATA); + *pdwDataLen = dwDataLen; + return FALSE; + } + + pBlobHeader->bType = SIMPLEBLOB; + pBlobHeader->bVersion = CUR_BLOB_VERSION; + pBlobHeader->reserved = 0; + pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid; + + *pAlgid = pPubKey->aiAlgid; + + if (!pad_data(pCryptKey->abKeyValue, pCryptKey->dwKeyLen, (BYTE*)(pAlgid+1), + pPubKey->dwBlockLen, dwFlags)) + { + return FALSE; + } + + encrypt_block_impl(pPubKey->aiAlgid, PK_PUBLIC, &pPubKey->context, (BYTE*)(pAlgid+1), + (BYTE*)(pAlgid+1), RSAENH_ENCRYPT); + } + *pdwDataLen = dwDataLen; + return TRUE; +} + +static BOOL crypt_export_public_key(CRYPTKEY *pCryptKey, BYTE *pbData, + DWORD *pdwDataLen) +{ + BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData; + RSAPUBKEY *pRSAPubKey = (RSAPUBKEY*)(pBlobHeader+1); + DWORD dwDataLen; + + if ((pCryptKey->aiAlgid != CALG_RSA_KEYX) && (pCryptKey->aiAlgid != CALG_RSA_SIGN)) { + SetLastError(NTE_BAD_KEY); + return FALSE; + } + + dwDataLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + pCryptKey->dwKeyLen; + if (pbData) { + if (*pdwDataLen < dwDataLen) { + SetLastError(ERROR_MORE_DATA); + *pdwDataLen = dwDataLen; + return FALSE; + } + + pBlobHeader->bType = PUBLICKEYBLOB; + pBlobHeader->bVersion = CUR_BLOB_VERSION; + pBlobHeader->reserved = 0; + pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid; + + pRSAPubKey->magic = RSAENH_MAGIC_RSA1; + pRSAPubKey->bitlen = pCryptKey->dwKeyLen << 3; + + export_public_key_impl((BYTE*)(pRSAPubKey+1), &pCryptKey->context, + pCryptKey->dwKeyLen, &pRSAPubKey->pubexp); + } + *pdwDataLen = dwDataLen; + return TRUE; +} + +static BOOL crypt_export_private_key(CRYPTKEY *pCryptKey, BOOL force, + BYTE *pbData, DWORD *pdwDataLen) +{ + BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData; + RSAPUBKEY *pRSAPubKey = (RSAPUBKEY*)(pBlobHeader+1); + DWORD dwDataLen; + + if ((pCryptKey->aiAlgid != CALG_RSA_KEYX) && (pCryptKey->aiAlgid != CALG_RSA_SIGN)) { + SetLastError(NTE_BAD_KEY); + return FALSE; + } + if (!force && !(pCryptKey->dwPermissions & CRYPT_EXPORT)) + { + SetLastError(NTE_BAD_KEY_STATE); + return FALSE; + } + + dwDataLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + + 2 * pCryptKey->dwKeyLen + 5 * ((pCryptKey->dwKeyLen + 1) >> 1); + if (pbData) { + if (*pdwDataLen < dwDataLen) { + SetLastError(ERROR_MORE_DATA); + *pdwDataLen = dwDataLen; + return FALSE; + } + + pBlobHeader->bType = PRIVATEKEYBLOB; + pBlobHeader->bVersion = CUR_BLOB_VERSION; + pBlobHeader->reserved = 0; + pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid; + + pRSAPubKey->magic = RSAENH_MAGIC_RSA2; + pRSAPubKey->bitlen = pCryptKey->dwKeyLen << 3; + + export_private_key_impl((BYTE*)(pRSAPubKey+1), &pCryptKey->context, + pCryptKey->dwKeyLen, &pRSAPubKey->pubexp); + } + *pdwDataLen = dwDataLen; + return TRUE; +} + +/****************************************************************************** + * crypt_export_key [Internal] + * + * Export a key into a binary large object (BLOB). Called by CPExportKey and + * by store_key_pair. + * + * PARAMS + * pCryptKey [I] Key to be exported. + * hPubKey [I] Key used to encrypt sensitive BLOB data. + * dwBlobType [I] SIMPLEBLOB, PUBLICKEYBLOB or PRIVATEKEYBLOB. + * dwFlags [I] Currently none defined. + * force [I] If TRUE, the key is written no matter what the key's + * permissions are. Otherwise the key's permissions are + * checked before exporting. + * pbData [O] Pointer to a buffer where the BLOB will be written to. + * pdwDataLen [I/O] I: Size of buffer at pbData, O: Size of BLOB + * + * RETURNS + * Success: TRUE. + * Failure: FALSE. + */ +static BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey, + DWORD dwBlobType, DWORD dwFlags, BOOL force, + BYTE *pbData, DWORD *pdwDataLen) +{ + CRYPTKEY *pPubKey; + + if (dwFlags & CRYPT_SSL2_FALLBACK) { + if (pCryptKey->aiAlgid != CALG_SSL2_MASTER) { + SetLastError(NTE_BAD_KEY); + return FALSE; + } + } + + switch ((BYTE)dwBlobType) + { + case SIMPLEBLOB: + if (!lookup_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pPubKey)){ + SetLastError(NTE_BAD_PUBLIC_KEY); /* FIXME: error_code? */ + return FALSE; + } + return crypt_export_simple(pCryptKey, pPubKey, dwFlags, pbData, + pdwDataLen); + + case PUBLICKEYBLOB: + if (is_valid_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY)) { + SetLastError(NTE_BAD_KEY); /* FIXME: error code? */ + return FALSE; + } + + return crypt_export_public_key(pCryptKey, pbData, pdwDataLen); + + case PRIVATEKEYBLOB: + return crypt_export_private_key(pCryptKey, force, pbData, pdwDataLen); + + default: + SetLastError(NTE_BAD_TYPE); /* FIXME: error code? */ + return FALSE; + } +} + /****************************************************************************** * CPExportKey (RSAENH.@) * @@ -2222,18 +2560,14 @@ * Success: TRUE. * Failure: FALSE. */ -BOOL WINAPI RSAENH_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubKey, +BOOL WINAPI RSAENH_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) { - CRYPTKEY *pCryptKey, *pPubKey; - BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData; - RSAPUBKEY *pRSAPubKey = (RSAPUBKEY*)(pBlobHeader+1); - ALG_ID *pAlgid = (ALG_ID*)(pBlobHeader+1); - DWORD dwDataLen; - + CRYPTKEY *pCryptKey; + TRACE("(hProv=%08lx, hKey=%08lx, hPubKey=%08lx, dwBlobType=%08x, dwFlags=%08x, pbData=%p," "pdwDataLen=%p)\n", hProv, hKey, hPubKey, dwBlobType, dwFlags, pbData, pdwDataLen); - + if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) { SetLastError(NTE_BAD_UID); @@ -2246,155 +2580,286 @@ return FALSE; }
- if (dwFlags & CRYPT_SSL2_FALLBACK) { - if (pCryptKey->aiAlgid != CALG_SSL2_MASTER) { - SetLastError(NTE_BAD_KEY); - return FALSE; + return crypt_export_key(pCryptKey, hPubKey, dwBlobType, dwFlags, FALSE, + pbData, pdwDataLen); +} + +/****************************************************************************** + * release_and_install_key [Internal] + * + * Release an existing key, if present, and replaces it with a new one. + * + * PARAMS + * hProv [I] Key container into which the key is to be imported. + * src [I] Key which will replace *dest + * dest [I] Points to key to be released and replaced with src + * fStoreKey [I] If TRUE, the newly installed key is stored to the registry. + */ +static void release_and_install_key(HCRYPTPROV hProv, HCRYPTKEY src, + HCRYPTKEY *dest, DWORD fStoreKey) +{ + RSAENH_CPDestroyKey(hProv, *dest); + copy_handle(&handle_table, src, RSAENH_MAGIC_KEY, dest); + if (fStoreKey) + { + KEYCONTAINER *pKeyContainer; + + if (lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER, + (OBJECTHDR**)&pKeyContainer)) + { + store_key_container_keys(pKeyContainer); + store_key_container_permissions(pKeyContainer); } } - - switch ((BYTE)dwBlobType) - { - case SIMPLEBLOB: - if (!lookup_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pPubKey)){ - SetLastError(NTE_BAD_PUBLIC_KEY); /* FIXME: error_code? */ - return FALSE; - } - - if (!(GET_ALG_CLASS(pCryptKey->aiAlgid)&(ALG_CLASS_DATA_ENCRYPT|ALG_CLASS_MSG_ENCRYPT))) { - SetLastError(NTE_BAD_KEY); /* FIXME: error code? */ - return FALSE; - } - - dwDataLen = sizeof(BLOBHEADER) + sizeof(ALG_ID) + pPubKey->dwBlockLen; - if (pbData) { - if (*pdwDataLen < dwDataLen) { - SetLastError(ERROR_MORE_DATA); - *pdwDataLen = dwDataLen; - return FALSE; - } - - pBlobHeader->bType = SIMPLEBLOB; - pBlobHeader->bVersion = CUR_BLOB_VERSION; - pBlobHeader->reserved = 0; - pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid; - - *pAlgid = pPubKey->aiAlgid; - - if (!pad_data(pCryptKey->abKeyValue, pCryptKey->dwKeyLen, (BYTE*)(pAlgid+1), - pPubKey->dwBlockLen, dwFlags)) - { - return FALSE; - } - - encrypt_block_impl(pPubKey->aiAlgid, PK_PUBLIC, &pPubKey->context, (BYTE*)(pAlgid+1), - (BYTE*)(pAlgid+1), RSAENH_ENCRYPT); - } - *pdwDataLen = dwDataLen; - return TRUE; - - case PUBLICKEYBLOB: - if (is_valid_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY)) { - SetLastError(NTE_BAD_KEY); /* FIXME: error code? */ - return FALSE; - } - - if ((pCryptKey->aiAlgid != CALG_RSA_KEYX) && (pCryptKey->aiAlgid != CALG_RSA_SIGN)) { - SetLastError(NTE_BAD_KEY); - return FALSE; - } - - dwDataLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + pCryptKey->dwKeyLen; - if (pbData) { - if (*pdwDataLen < dwDataLen) { - SetLastError(ERROR_MORE_DATA); - *pdwDataLen = dwDataLen; - return FALSE; - } - - pBlobHeader->bType = PUBLICKEYBLOB; - pBlobHeader->bVersion = CUR_BLOB_VERSION; - pBlobHeader->reserved = 0; - pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid; - - pRSAPubKey->magic = RSAENH_MAGIC_RSA1; - pRSAPubKey->bitlen = pCryptKey->dwKeyLen << 3; - - export_public_key_impl((BYTE*)(pRSAPubKey+1), &pCryptKey->context, - pCryptKey->dwKeyLen, &pRSAPubKey->pubexp); - } - *pdwDataLen = dwDataLen; - return TRUE; - - case PRIVATEKEYBLOB: - if ((pCryptKey->aiAlgid != CALG_RSA_KEYX) && (pCryptKey->aiAlgid != CALG_RSA_SIGN)) { - SetLastError(NTE_BAD_KEY); - return FALSE; - } - - dwDataLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + - 2 * pCryptKey->dwKeyLen + 5 * ((pCryptKey->dwKeyLen + 1) >> 1); - if (pbData) { - if (*pdwDataLen < dwDataLen) { - SetLastError(ERROR_MORE_DATA); - *pdwDataLen = dwDataLen; - return FALSE; - } - - pBlobHeader->bType = PRIVATEKEYBLOB; - pBlobHeader->bVersion = CUR_BLOB_VERSION; - pBlobHeader->reserved = 0; - pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid; - - pRSAPubKey->magic = RSAENH_MAGIC_RSA2; - pRSAPubKey->bitlen = pCryptKey->dwKeyLen << 3; - - export_private_key_impl((BYTE*)(pRSAPubKey+1), &pCryptKey->context, - pCryptKey->dwKeyLen, &pRSAPubKey->pubexp); - } - *pdwDataLen = dwDataLen; - return TRUE; - - default: - SetLastError(NTE_BAD_TYPE); /* FIXME: error code? */ - return FALSE; - } -} - -/****************************************************************************** - * CPImportKey (RSAENH.@) - * - * Import a BLOB'ed key into a key container. +} + +/****************************************************************************** + * import_private_key [Internal] + * + * Import a BLOB'ed private key into a key container. + * + * PARAMS + * hProv [I] Key container into which the private key is to be imported. + * pbData [I] Pointer to a buffer which holds the private key BLOB. + * dwDataLen [I] Length of data in buffer at pbData. + * dwFlags [I] One of: + * CRYPT_EXPORTABLE: the imported key is marked exportable + * fStoreKey [I] If TRUE, the imported key is stored to the registry. + * phKey [O] Handle to the imported key. + * + * + * NOTES + * Assumes the caller has already checked the BLOBHEADER at pbData to ensure + * it's a PRIVATEKEYBLOB. + * + * RETURNS + * Success: TRUE. + * Failure: FALSE. + */ +static BOOL import_private_key(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, + DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey) +{ + KEYCONTAINER *pKeyContainer; + CRYPTKEY *pCryptKey; + CONST BLOBHEADER *pBlobHeader = (CONST BLOBHEADER*)pbData; + CONST RSAPUBKEY *pRSAPubKey = (CONST RSAPUBKEY*)(pBlobHeader+1); + BOOL ret; + + if (!lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER, + (OBJECTHDR**)&pKeyContainer)) + { + SetLastError(NTE_BAD_UID); + return FALSE; + } + + if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY)) || + (pRSAPubKey->magic != RSAENH_MAGIC_RSA2) || + (dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + + (2 * pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4)))) + { + SetLastError(NTE_BAD_DATA); + return FALSE; + } + + *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, MAKELONG(0,pRSAPubKey->bitlen), &pCryptKey); + if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE; + setup_key(pCryptKey); + ret = import_private_key_impl((CONST BYTE*)(pRSAPubKey+1), &pCryptKey->context, + pRSAPubKey->bitlen/8, pRSAPubKey->pubexp); + if (ret) { + if (dwFlags & CRYPT_EXPORTABLE) + pCryptKey->dwPermissions |= CRYPT_EXPORT; + switch (pBlobHeader->aiKeyAlg) + { + case AT_SIGNATURE: + case CALG_RSA_SIGN: + TRACE("installing signing key\n"); + release_and_install_key(hProv, *phKey, &pKeyContainer->hSignatureKeyPair, + fStoreKey); + break; + case AT_KEYEXCHANGE: + case CALG_RSA_KEYX: + TRACE("installing key exchange key\n"); + release_and_install_key(hProv, *phKey, &pKeyContainer->hKeyExchangeKeyPair, + fStoreKey); + break; + } + } + return ret; +} + +/****************************************************************************** + * import_public_key [Internal] + * + * Import a BLOB'ed public key into a key container. + * + * PARAMS + * hProv [I] Key container into which the public key is to be imported. + * pbData [I] Pointer to a buffer which holds the public key BLOB. + * dwDataLen [I] Length of data in buffer at pbData. + * dwFlags [I] One of: + * CRYPT_EXPORTABLE: the imported key is marked exportable + * fStoreKey [I] If TRUE, the imported key is stored to the registry. + * phKey [O] Handle to the imported key. + * + * + * NOTES + * Assumes the caller has already checked the BLOBHEADER at pbData to ensure + * it's a PUBLICKEYBLOB. + * + * RETURNS + * Success: TRUE. + * Failure: FALSE. + */ +static BOOL import_public_key(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, + DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey) +{ + KEYCONTAINER *pKeyContainer; + CRYPTKEY *pCryptKey; + CONST BLOBHEADER *pBlobHeader = (CONST BLOBHEADER*)pbData; + CONST RSAPUBKEY *pRSAPubKey = (CONST RSAPUBKEY*)(pBlobHeader+1); + ALG_ID algID; + BOOL ret; + + if (!lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER, + (OBJECTHDR**)&pKeyContainer)) + { + SetLastError(NTE_BAD_UID); + return FALSE; + } + + if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY)) || + (pRSAPubKey->magic != RSAENH_MAGIC_RSA1) || + (dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + (pRSAPubKey->bitlen >> 3))) + { + SetLastError(NTE_BAD_DATA); + return FALSE; + } + + /* Since this is a public key blob, only the public key is + * available, so only signature verification is possible. + */ + algID = pBlobHeader->aiKeyAlg; + *phKey = new_key(hProv, algID, MAKELONG(0,pRSAPubKey->bitlen), &pCryptKey); + if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE; + setup_key(pCryptKey); + ret = import_public_key_impl((CONST BYTE*)(pRSAPubKey+1), &pCryptKey->context, + pRSAPubKey->bitlen >> 3, pRSAPubKey->pubexp); + if (ret) { + if (dwFlags & CRYPT_EXPORTABLE) + pCryptKey->dwPermissions |= CRYPT_EXPORT; + switch (pBlobHeader->aiKeyAlg) + { + case AT_KEYEXCHANGE: + case CALG_RSA_KEYX: + TRACE("installing public key\n"); + release_and_install_key(hProv, *phKey, &pKeyContainer->hKeyExchangeKeyPair, + fStoreKey); + break; + } + } + return ret; +} + +/****************************************************************************** + * import_symmetric_key [Internal] + * + * Import a BLOB'ed symmetric key into a key container. + * + * PARAMS + * hProv [I] Key container into which the symmetric key is to be imported. + * pbData [I] Pointer to a buffer which holds the symmetric key BLOB. + * dwDataLen [I] Length of data in buffer at pbData. + * hPubKey [I] Key used to decrypt sensitive BLOB data. + * dwFlags [I] One of: + * CRYPT_EXPORTABLE: the imported key is marked exportable + * phKey [O] Handle to the imported key. + * + * + * NOTES + * Assumes the caller has already checked the BLOBHEADER at pbData to ensure + * it's a SIMPLEBLOB. + * + * RETURNS + * Success: TRUE. + * Failure: FALSE. + */ +static BOOL import_symmetric_key(HCRYPTPROV hProv, CONST BYTE *pbData, + DWORD dwDataLen, HCRYPTKEY hPubKey, + DWORD dwFlags, HCRYPTKEY *phKey) +{ + CRYPTKEY *pCryptKey, *pPubKey; + CONST BLOBHEADER *pBlobHeader = (CONST BLOBHEADER*)pbData; + CONST ALG_ID *pAlgid = (CONST ALG_ID*)(pBlobHeader+1); + CONST BYTE *pbKeyStream = (CONST BYTE*)(pAlgid + 1); + BYTE *pbDecrypted; + DWORD dwKeyLen; + + if (!lookup_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pPubKey) || + pPubKey->aiAlgid != CALG_RSA_KEYX) + { + SetLastError(NTE_BAD_PUBLIC_KEY); /* FIXME: error code? */ + return FALSE; + } + + if (dwDataLen < sizeof(BLOBHEADER)+sizeof(ALG_ID)+pPubKey->dwBlockLen) + { + SetLastError(NTE_BAD_DATA); /* FIXME: error code */ + return FALSE; + } + + pbDecrypted = HeapAlloc(GetProcessHeap(), 0, pPubKey->dwBlockLen); + if (!pbDecrypted) return FALSE; + encrypt_block_impl(pPubKey->aiAlgid, PK_PRIVATE, &pPubKey->context, pbKeyStream, pbDecrypted, + RSAENH_DECRYPT); + + dwKeyLen = RSAENH_MAX_KEY_SIZE; + if (!unpad_data(pbDecrypted, pPubKey->dwBlockLen, pbDecrypted, &dwKeyLen, dwFlags)) { + HeapFree(GetProcessHeap(), 0, pbDecrypted); + return FALSE; + } + + *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, dwKeyLen<<19, &pCryptKey); + if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) + { + HeapFree(GetProcessHeap(), 0, pbDecrypted); + return FALSE; + } + memcpy(pCryptKey->abKeyValue, pbDecrypted, dwKeyLen); + HeapFree(GetProcessHeap(), 0, pbDecrypted); + setup_key(pCryptKey); + if (dwFlags & CRYPT_EXPORTABLE) + pCryptKey->dwPermissions |= CRYPT_EXPORT; + return TRUE; +} + +/****************************************************************************** + * import_key [Internal] + * + * Import a BLOB'ed key into a key container, optionally storing the key's + * value to the registry. * * PARAMS * hProv [I] Key container into which the key is to be imported. * pbData [I] Pointer to a buffer which holds the BLOB. * dwDataLen [I] Length of data in buffer at pbData. * hPubKey [I] Key used to decrypt sensitive BLOB data. - * dwFlags [I] Currently none defined. + * dwFlags [I] One of: + * CRYPT_EXPORTABLE: the imported key is marked exportable + * fStoreKey [I] If TRUE, the imported key is stored to the registry. * phKey [O] Handle to the imported key. * * RETURNS * Success: TRUE. * Failure: FALSE. */ -BOOL WINAPI RSAENH_CPImportKey(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, - HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey) +static BOOL import_key(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, + HCRYPTKEY hPubKey, DWORD dwFlags, BOOL fStoreKey, + HCRYPTKEY *phKey) { KEYCONTAINER *pKeyContainer; - CRYPTKEY *pCryptKey, *pPubKey; CONST BLOBHEADER *pBlobHeader = (CONST BLOBHEADER*)pbData; - CONST RSAPUBKEY *pRSAPubKey = (CONST RSAPUBKEY*)(pBlobHeader+1); - CONST ALG_ID *pAlgid = (CONST ALG_ID*)(pBlobHeader+1); - CONST BYTE *pbKeyStream = (CONST BYTE*)(pAlgid + 1); - ALG_ID algID; - BYTE *pbDecrypted; - DWORD dwKeyLen; - BOOL ret; - - TRACE("(hProv=%08lx, pbData=%p, dwDataLen=%d, hPubKey=%08lx, dwFlags=%08x, phKey=%p)\n", - hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey); - + if (!lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER, (OBJECTHDR**)&pKeyContainer)) { @@ -2410,116 +2875,55 @@ return FALSE; }
+ /* If this is a verify-only context, the key is not persisted regardless of + * fStoreKey's original value. + */ + fStoreKey = fStoreKey && !(dwFlags & CRYPT_VERIFYCONTEXT); switch (pBlobHeader->bType) { case PRIVATEKEYBLOB: - if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY)) || - (pRSAPubKey->magic != RSAENH_MAGIC_RSA2) || - (dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + - (2 * pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4)))) - { - SetLastError(NTE_BAD_DATA); - return FALSE; - } - - *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, MAKELONG(0,pRSAPubKey->bitlen), &pCryptKey); - if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE; - setup_key(pCryptKey); - ret = import_private_key_impl((CONST BYTE*)(pRSAPubKey+1), &pCryptKey->context, - pRSAPubKey->bitlen/8, pRSAPubKey->pubexp); - if (ret) { - switch (pBlobHeader->aiKeyAlg) - { - case AT_SIGNATURE: - case CALG_RSA_SIGN: - TRACE("installing signing key\n"); - RSAENH_CPDestroyKey(hProv, pKeyContainer->hSignatureKeyPair); - copy_handle(&handle_table, *phKey, RSAENH_MAGIC_KEY, - &pKeyContainer->hSignatureKeyPair); - break; - case AT_KEYEXCHANGE: - case CALG_RSA_KEYX: - TRACE("installing key exchange key\n"); - RSAENH_CPDestroyKey(hProv, pKeyContainer->hKeyExchangeKeyPair); - copy_handle(&handle_table, *phKey, RSAENH_MAGIC_KEY, - &pKeyContainer->hKeyExchangeKeyPair); - break; - } - } - return ret; + return import_private_key(hProv, pbData, dwDataLen, dwFlags, + fStoreKey, phKey);
case PUBLICKEYBLOB: - if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY)) || - (pRSAPubKey->magic != RSAENH_MAGIC_RSA1) || - (dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + (pRSAPubKey->bitlen >> 3))) - { - SetLastError(NTE_BAD_DATA); - return FALSE; - } - - /* Since this is a public key blob, only the public key is - * available, so only signature verification is possible. - */ - algID = pBlobHeader->aiKeyAlg; - *phKey = new_key(hProv, algID, MAKELONG(0,pRSAPubKey->bitlen), &pCryptKey); - if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE; - setup_key(pCryptKey); - ret = import_public_key_impl((CONST BYTE*)(pRSAPubKey+1), &pCryptKey->context, - pRSAPubKey->bitlen >> 3, pRSAPubKey->pubexp); - if (ret) { - switch (pBlobHeader->aiKeyAlg) - { - case AT_KEYEXCHANGE: - case CALG_RSA_KEYX: - TRACE("installing public key\n"); - RSAENH_CPDestroyKey(hProv, pKeyContainer->hKeyExchangeKeyPair); - copy_handle(&handle_table, *phKey, RSAENH_MAGIC_KEY, - &pKeyContainer->hKeyExchangeKeyPair); - break; - } - } - return ret; + return import_public_key(hProv, pbData, dwDataLen, dwFlags, + fStoreKey, phKey);
case SIMPLEBLOB: - if (!lookup_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pPubKey) || - pPubKey->aiAlgid != CALG_RSA_KEYX) - { - SetLastError(NTE_BAD_PUBLIC_KEY); /* FIXME: error code? */ - return FALSE; - } - - if (dwDataLen < sizeof(BLOBHEADER)+sizeof(ALG_ID)+pPubKey->dwBlockLen) - { - SetLastError(NTE_BAD_DATA); /* FIXME: error code */ - return FALSE; - } - - pbDecrypted = HeapAlloc(GetProcessHeap(), 0, pPubKey->dwBlockLen); - if (!pbDecrypted) return FALSE; - encrypt_block_impl(pPubKey->aiAlgid, PK_PRIVATE, &pPubKey->context, pbKeyStream, pbDecrypted, - RSAENH_DECRYPT); - - dwKeyLen = RSAENH_MAX_KEY_SIZE; - if (!unpad_data(pbDecrypted, pPubKey->dwBlockLen, pbDecrypted, &dwKeyLen, dwFlags)) { - HeapFree(GetProcessHeap(), 0, pbDecrypted); - return FALSE; - } - - *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, dwKeyLen<<19, &pCryptKey); - if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) - { - HeapFree(GetProcessHeap(), 0, pbDecrypted); - return FALSE; - } - memcpy(pCryptKey->abKeyValue, pbDecrypted, dwKeyLen); - HeapFree(GetProcessHeap(), 0, pbDecrypted); - setup_key(pCryptKey); - return TRUE; + return import_symmetric_key(hProv, pbData, dwDataLen, hPubKey, + dwFlags, phKey);
default: SetLastError(NTE_BAD_TYPE); /* FIXME: error code? */ return FALSE; } +} + +/****************************************************************************** + * CPImportKey (RSAENH.@) + * + * Import a BLOB'ed key into a key container. + * + * PARAMS + * hProv [I] Key container into which the key is to be imported. + * pbData [I] Pointer to a buffer which holds the BLOB. + * dwDataLen [I] Length of data in buffer at pbData. + * hPubKey [I] Key used to decrypt sensitive BLOB data. + * dwFlags [I] One of: + * CRYPT_EXPORTABLE: the imported key is marked exportable + * phKey [O] Handle to the imported key. + * + * RETURNS + * Success: TRUE. + * Failure: FALSE. + */ +BOOL WINAPI RSAENH_CPImportKey(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, + HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey) +{ + TRACE("(hProv=%08lx, pbData=%p, dwDataLen=%d, hPubKey=%08lx, dwFlags=%08x, phKey=%p)\n", + hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey); + + return import_key(hProv, pbData, dwDataLen, hPubKey, dwFlags, TRUE, phKey); }
/****************************************************************************** @@ -2737,8 +3141,8 @@ finalize_hash(pCryptHash); pCryptHash->dwState = RSAENH_HASHSTATE_FINISHED; } - - return copy_param(pbData, pdwDataLen, (CONST BYTE*)pCryptHash->abHashValue, + + return copy_param(pbData, pdwDataLen, pCryptHash->abHashValue, pCryptHash->dwHashSize);
default: @@ -2814,8 +3218,26 @@ return TRUE;
case KP_PERMISSIONS: - pCryptKey->dwPermissions = *(DWORD*)pbData; + { + DWORD perms = *(DWORD *)pbData; + + if ((perms & CRYPT_EXPORT) && + !(pCryptKey->dwPermissions & CRYPT_EXPORT)) + { + SetLastError(NTE_BAD_DATA); + return FALSE; + } + else if (!(perms & CRYPT_EXPORT) && + (pCryptKey->dwPermissions & CRYPT_EXPORT)) + { + /* Clearing the export permission appears to be ignored, + * see tests. + */ + perms |= CRYPT_EXPORT; + } + pCryptKey->dwPermissions = perms; return TRUE; + }
case KP_IV: memcpy(pCryptKey->abInitVector, pbData, pCryptKey->dwBlockLen); @@ -2950,13 +3372,13 @@ switch (dwParam) { case KP_IV: - return copy_param(pbData, pdwDataLen, (CONST BYTE*)pCryptKey->abInitVector, + return copy_param(pbData, pdwDataLen, pCryptKey->abInitVector, pCryptKey->dwBlockLen);
case KP_SALT: return copy_param(pbData, pdwDataLen, - (CONST BYTE*)&pCryptKey->abKeyValue[pCryptKey->dwKeyLen], pCryptKey->dwSaltLen); - + &pCryptKey->abKeyValue[pCryptKey->dwKeyLen], pCryptKey->dwSaltLen); + case KP_PADDING: dwValue = PKCS5_PADDING; return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwValue, sizeof(DWORD));
Modified: trunk/reactos/dll/win32/rsaenh/tomcrypt.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/rsaenh/tomcrypt.h... ============================================================================== --- trunk/reactos/dll/win32/rsaenh/tomcrypt.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/rsaenh/tomcrypt.h [iso-8859-1] Thu Feb 26 13:29:58 2009 @@ -235,39 +235,20 @@ /* error code to char* string */ char *mp_error_to_string(int code);
-/* ---> init and deinit bignum functions <--- */ -/* init a bignum */ -int mp_init(mp_int *a); - -/* free a bignum */ -void mp_clear(mp_int *a); - /* init a null terminated series of arguments */ int mp_init_multi(mp_int *mp, ...);
/* clear a null terminated series of arguments */ void mp_clear_multi(mp_int *mp, ...);
-/* exchange two ints */ -void mp_exch(mp_int *a, mp_int *b); - /* shrink ram required for a bignum */ int mp_shrink(mp_int *a); - -/* grow an int to a given size */ -int mp_grow(mp_int *a, int size); - -/* init to a given number of digits */ -int mp_init_size(mp_int *a, int size);
/* ---> Basic Manipulations <--- */ #define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) #define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) #define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
-/* set to zero */ -void mp_zero(mp_int *a); - /* set to a digit */ void mp_set(mp_int *a, mp_digit b);
@@ -293,30 +274,6 @@ void mp_clamp(mp_int *a);
/* ---> digit manipulation <--- */ - -/* right shift by "b" digits */ -void mp_rshd(mp_int *a, int b); - -/* left shift by "b" digits */ -int mp_lshd(mp_int *a, int b); - -/* c = a / 2**b */ -int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d); - -/* b = a/2 */ -int mp_div_2(const mp_int *a, mp_int *b); - -/* c = a * 2**b */ -int mp_mul_2d(const mp_int *a, int b, mp_int *c); - -/* b = a*2 */ -int mp_mul_2(const mp_int *a, mp_int *b); - -/* c = a mod 2**d */ -int mp_mod_2d(const mp_int *a, int b, mp_int *c); - -/* computes a = 2**b */ -int mp_2expt(mp_int *a, int b);
/* Counts the number of lsbs which are zero before the first zero bit */ int mp_cnt_lsb(const mp_int *a); @@ -341,9 +298,6 @@ /* b = -a */ int mp_neg(mp_int *a, mp_int *b);
-/* b = |a| */ -int mp_abs(const mp_int *a, mp_int *b); - /* compare a to b */ int mp_cmp(const mp_int *a, const mp_int *b);
@@ -362,9 +316,6 @@ /* b = a*a */ int mp_sqr(const mp_int *a, mp_int *b);
-/* a/b => cb + d == a */ -int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d); - /* c = a mod b, 0 <= c < b */ int mp_mod(const mp_int *a, mp_int *b, mp_int *c);
@@ -373,27 +324,15 @@ /* compare against a single digit */ int mp_cmp_d(const mp_int *a, mp_digit b);
-/* c = a + b */ -int mp_add_d(mp_int *a, mp_digit b, mp_int *c); - /* c = a - b */ int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
-/* c = a * b */ -int mp_mul_d(const mp_int *a, mp_digit b, mp_int *c); - -/* a/b => cb + d == a */ -int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d); - /* a/3 => 3c + d == a */ int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
/* c = a**b */ int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
-/* c = a mod b, 0 <= c < b */ -int mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c); - /* ---> number theory <--- */
/* d = a + b (mod c) */ @@ -459,12 +398,6 @@ /* returns 1 if a is a valid DR modulus */ int mp_dr_is_modulus(mp_int *a);
-/* sets the value of "d" required for mp_dr_reduce */ -void mp_dr_setup(const mp_int *a, mp_digit *d); - -/* reduces a modulo b using the Diminished Radix method */ -int mp_dr_reduce(mp_int *a, const mp_int *b, mp_digit mp); - /* returns true if a can be reduced with mp_reduce_2k */ int mp_reduce_is_2k(mp_int *a);
@@ -482,32 +415,15 @@ /* number of primes */ #define PRIME_SIZE 256
-/* result=1 if a is divisible by one of the first PRIME_SIZE primes */ -int mp_prime_is_divisible(const mp_int *a, int *result); - /* performs one Fermat test of "a" using base "b". * Sets result to 0 if composite or 1 if probable prime */ int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
-/* performs one Miller-Rabin test of "a" using base "b". - * Sets result to 0 if composite or 1 if probable prime - */ -int mp_prime_miller_rabin(mp_int *a, const mp_int *b, int *result); - /* This gives [for a given bit size] the number of trials required * such that Miller-Rabin gives a prob of failure lower than 2^-96 */ int mp_prime_rabin_miller_trials(int size); - -/* performs t rounds of Miller-Rabin on "a" using the first - * t prime bases. Also performs an initial sieve of trial - * division. Determines if "a" is prime with probability - * of error no more than (1/4)**t. - * - * Sets result to 1 if probably prime, 0 otherwise - */ -int mp_prime_is_prime(mp_int *a, int t, int *result);
/* finds the next prime after the number "a" using "t" trials * of Miller-Rabin.
Modified: trunk/reactos/dll/win32/shdocvw/oleobject.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shdocvw/oleobject... ============================================================================== --- trunk/reactos/dll/win32/shdocvw/oleobject.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shdocvw/oleobject.c [iso-8859-1] Thu Feb 26 13:29:58 2009 @@ -868,9 +868,26 @@ const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) { WebBrowser *This = OLECMD_THIS(iface); - FIXME("(%p)->(%s %u %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, + IOleCommandTarget *cmdtrg; + HRESULT hres; + + TRACE("(%p)->(%s %u %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText); - return E_NOTIMPL; + + if(!This->doc_host.document) + return 0x80040104; + + /* NOTE: There are probably some commands that we should handle here + * instead of forwarding to document object. */ + + hres = IUnknown_QueryInterface(This->doc_host.document, &IID_IOleCommandTarget, (void**)&cmdtrg); + if(FAILED(hres)) + return hres; + + hres = IOleCommandTarget_QueryStatus(cmdtrg, pguidCmdGroup, cCmds, prgCmds, pCmdText); + IOleCommandTarget_Release(cmdtrg); + + return hres; }
static HRESULT WINAPI WBOleCommandTarget_Exec(IOleCommandTarget *iface,
Modified: trunk/reactos/dll/win32/shlwapi/shlwapi.rc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shlwapi/shlwapi.r... ============================================================================== --- trunk/reactos/dll/win32/shlwapi/shlwapi.rc [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shlwapi/shlwapi.rc [iso-8859-1] Thu Feb 26 13:29:58 2009 @@ -46,4 +46,5 @@ #include "shlwapi_Sk.rc" #include "shlwapi_Sv.rc" #include "shlwapi_Tr.rc" -#include "shlwapi_Uk.rc"#include "shlwapi_Zh.rc" +#include "shlwapi_Uk.rc" +#include "shlwapi_Zh.rc"