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?…
==============================================================================
--- 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?…
==============================================================================
--- 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?…
==============================================================================
--- 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.…
==============================================================================
--- 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/oleobjec…
==============================================================================
--- 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.…
==============================================================================
--- 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"