ReactOS 0.4.17-dev-1005-g171e1de
rsakey.c File Reference
#include "precomp.h"
Include dependency graph for rsakey.c:

Go to the source code of this file.

Macros

#define RSA_DEFAULT_PUBLIC_EXPONENT   (65537)
 
#define SYMCRYPT_MAX_PRIME_RECOVERY_ITERATIONS   (100)
 
#define SYMCRYPT_SCRATCH_BYTES_FOR_PRIME_RECOVERY(_ndMod, _ndPubExp, _nBitsMod)
 

Functions

PSYMCRYPT_RSAKEY SYMCRYPT_CALL SymCryptRsakeyAllocate (_In_ PCSYMCRYPT_RSA_PARAMS pParams, _In_ UINT32 flags)
 
VOID SYMCRYPT_CALL SymCryptRsakeyFree (_Out_ PSYMCRYPT_RSAKEY pkObj)
 
UINT32 SYMCRYPT_CALL SymCryptSizeofRsakeyFromParams (_In_ PCSYMCRYPT_RSA_PARAMS pParams)
 
PSYMCRYPT_RSAKEY SYMCRYPT_CALL SymCryptRsakeyCreate (_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, _In_ PCSYMCRYPT_RSA_PARAMS pParams)
 
VOID SYMCRYPT_CALL SymCryptRsakeyWipe (_Out_ PSYMCRYPT_RSAKEY pkDst)
 
BOOLEAN SYMCRYPT_CALL SymCryptRsakeyHasPrivateKey (_In_ PCSYMCRYPT_RSAKEY pkRsakey)
 
UINT32 SYMCRYPT_CALL SymCryptRsakeySizeofModulus (_In_ PCSYMCRYPT_RSAKEY pkRsakey)
 
UINT32 SYMCRYPT_CALL SymCryptRsakeyModulusBits (_In_ PCSYMCRYPT_RSAKEY pkRsakey)
 
UINT32 SYMCRYPT_CALL SymCryptRsakeySizeofPublicExponent (_In_ PCSYMCRYPT_RSAKEY pRsakey, UINT32 index)
 
UINT32 SYMCRYPT_CALL SymCryptRsakeySizeofPrime (_In_ PCSYMCRYPT_RSAKEY pkRsakey, UINT32 index)
 
UINT32 SYMCRYPT_CALL SymCryptRsakeyGetNumberOfPublicExponents (_In_ PCSYMCRYPT_RSAKEY pkRsakey)
 
UINT32 SYMCRYPT_CALL SymCryptRsakeyGetNumberOfPrimes (_In_ PCSYMCRYPT_RSAKEY pkRsakey)
 
VOID SYMCRYPT_CALL SymCryptRsakeyCreateAllObjects (_Inout_ PSYMCRYPT_RSAKEY pkRsakey)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyCalculatePrivateFields (_Inout_ PSYMCRYPT_RSAKEY pkRsakey, _Out_ PSYMCRYPT_DIVISOR pdTmp, _Out_ PSYMCRYPT_INT piPhi, _Out_ PSYMCRYPT_INT piAcc, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch, UINT32 flags)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyGenerate (_Inout_ PSYMCRYPT_RSAKEY pkRsakey, _In_reads_opt_(nPubExp) PCUINT64 pu64PubExp, UINT32 nPubExp, _In_ UINT32 flags)
 
static SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyCalculatePrimesFromPrivateExponent (_Inout_ PSYMCRYPT_RSAKEY pkRsakey, _In_reads_bytes_(cbPrivateExponent) PCBYTE pbPrivateExponent, SIZE_T cbPrivateExponent, SYMCRYPT_NUMBER_FORMAT numFormat, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, UINT32 cbScratch)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeySetValueInternal (_In_reads_bytes_(cbModulus) PCBYTE pbModulus, SIZE_T cbModulus, _In_reads_(nPubExp) PCUINT64 pu64PubExp, UINT32 nPubExp, _In_reads_bytes_opt_(cbPrivateExponent) PCBYTE pbPrivateExponent, SIZE_T cbPrivateExponent, _In_reads_opt_(nPrimes) PCBYTE *ppPrimes, _In_reads_opt_(nPrimes) SIZE_T *pcbPrimes, UINT32 nPrimes, SYMCRYPT_NUMBER_FORMAT numFormat, UINT32 flags, _Inout_ PSYMCRYPT_RSAKEY pkRsakey)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeySetValue (_In_reads_bytes_(cbModulus) PCBYTE pbModulus, SIZE_T cbModulus, _In_reads_(nPubExp) PCUINT64 pu64PubExp, UINT32 nPubExp, _In_reads_opt_(nPrimes) PCBYTE *ppPrimes, _In_reads_opt_(nPrimes) SIZE_T *pcbPrimes, UINT32 nPrimes, SYMCRYPT_NUMBER_FORMAT numFormat, UINT32 flags, _Inout_ PSYMCRYPT_RSAKEY pkRsakey)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeySetValueFromPrivateExponent (_In_reads_bytes_(cbModulus) PCBYTE pbModulus, SIZE_T cbModulus, UINT64 u64PubExp, _In_reads_bytes_(cbPrivateExponent) PCBYTE pbPrivateExponent, SIZE_T cbPrivateExponent, SYMCRYPT_NUMBER_FORMAT numFormat, UINT32 flags, _Inout_ PSYMCRYPT_RSAKEY pkRsakey)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyGetValue (_In_ PCSYMCRYPT_RSAKEY pkRsakey, _Out_writes_bytes_(cbModulus) PBYTE pbModulus, SIZE_T cbModulus, _Out_writes_opt_(nPubExp) PUINT64 pu64PubExp, UINT32 nPubExp, _Out_writes_opt_(nPrimes) PBYTE *ppPrimes, _In_reads_opt_(nPrimes) SIZE_T *pcbPrimes, UINT32 nPrimes, SYMCRYPT_NUMBER_FORMAT numFormat, UINT32 flags)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyGetCrtValue (_In_ PCSYMCRYPT_RSAKEY pkRsakey, _Out_writes_opt_(nCrtExponents) PBYTE *ppCrtExponents, _In_reads_(nCrtExponents) SIZE_T *pcbCrtExponents, UINT32 nCrtExponents, _Out_writes_bytes_opt_(cbCrtCoefficient) PBYTE pbCrtCoefficient, SIZE_T cbCrtCoefficient, _Out_writes_bytes_opt_(cbPrivateExponent) PBYTE pbPrivateExponent, SIZE_T cbPrivateExponent, SYMCRYPT_NUMBER_FORMAT numFormat, UINT32 flags)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyExtendKeyUsage (_Inout_ PSYMCRYPT_RSAKEY pkRsakey, UINT32 flags)
 

Macro Definition Documentation

◆ RSA_DEFAULT_PUBLIC_EXPONENT

#define RSA_DEFAULT_PUBLIC_EXPONENT   (65537)

Definition at line 9 of file rsakey.c.

◆ SYMCRYPT_MAX_PRIME_RECOVERY_ITERATIONS

#define SYMCRYPT_MAX_PRIME_RECOVERY_ITERATIONS   (100)

Definition at line 797 of file rsakey.c.

◆ SYMCRYPT_SCRATCH_BYTES_FOR_PRIME_RECOVERY

#define SYMCRYPT_SCRATCH_BYTES_FOR_PRIME_RECOVERY (   _ndMod,
  _ndPubExp,
  _nBitsMod 
)
Value:
SymCryptSizeofIntFromDigits( _ndMod ) + /* Space for piPrivExp*/ \
SymCryptSizeofIntFromDigits( _ndPubExp ) + /* Space for piPubExp*/ \
SymCryptSizeofIntFromDigits( _ndMod + _ndPubExp ) + /* Space for piExpProd*/ \
(4*SYMCRYPT_SIZEOF_MODELEMENT_FROM_BITS( _nBitsMod )) + /* Space for peTmpY, peTmpX, peOne, peNegOne */\
SYMCRYPT_MAX( SYMCRYPT_SCRATCH_BYTES_FOR_INT_MUL( _ndMod + _ndPubExp ), /* Space for SymCryptIntMulMixedSize */ \
SYMCRYPT_MAX( SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _ndMod ), /* Space for other SymCryptMod* */ \
SYMCRYPT_MAX( SYMCRYPT_SCRATCH_BYTES_FOR_MODEXP( _ndMod ), /* Space for SymCryptModExp */ \
SYMCRYPT_MAX( SYMCRYPT_SCRATCH_BYTES_FOR_EXTENDED_GCD( _ndMod ), /* Space for SymCryptIntExtendedGcd */ \
SYMCRYPT_MAX( SYMCRYPT_SCRATCH_BYTES_FOR_INT_TO_MODULUS( _ndMod ), /* Space for SymCryptIntToModulus */ \
SYMCRYPT_SCRATCH_BYTES_FOR_INT_DIVMOD( _ndMod, _ndMod ) /* Space for SymCryptIntDivMod */ \
)))))
#define SYMCRYPT_MAX(_a, _b)
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_MUL(_nResultDigits)
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_DIVMOD(_nSrcDigits, _nDivisorDigits)
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_TO_MODULUS(_nDigits)
#define SYMCRYPT_SCRATCH_BYTES_FOR_EXTENDED_GCD(_nDigits)
#define SYMCRYPT_SIZEOF_MODELEMENT_FROM_BITS(_bitsize)
#define SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS(_nDigits)
UINT32 SYMCRYPT_CALL SymCryptSizeofIntFromDigits(UINT32 nDigits)
Definition: a_dispatch.c:134
#define SYMCRYPT_SCRATCH_BYTES_FOR_MODEXP(_nDigits)

Definition at line 799 of file rsakey.c.

Function Documentation

◆ SymCryptRsakeyAllocate()

PSYMCRYPT_RSAKEY SYMCRYPT_CALL SymCryptRsakeyAllocate ( _In_ PCSYMCRYPT_RSA_PARAMS  pParams,
_In_ UINT32  flags 
)

Definition at line 13 of file rsakey.c.

16{
17 PVOID p;
18 SIZE_T cb;
20
22
23 SYMCRYPT_ASSERT( pParams != NULL );
24
26
28
29 if ( p==NULL )
30 {
31 goto cleanup;
32 }
33
34 res = SymCryptRsakeyCreate( p, cb, pParams );
35
37 return res;
38}
#define NULL
Definition: types.h:112
static void cleanup(void)
Definition: main.c:1335
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
GLuint res
Definition: glext.h:9613
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
void *SYMCRYPT_CALL SymCryptCallbackAlloc(SIZE_T size)
Definition: implglue.c:37
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
PSYMCRYPT_RSAKEY SYMCRYPT_CALL SymCryptRsakeyCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, _In_ PCSYMCRYPT_RSA_PARAMS pParams)
Definition: rsakey.c:83
UINT32 SYMCRYPT_CALL SymCryptSizeofRsakeyFromParams(_In_ PCSYMCRYPT_RSA_PARAMS pParams)
Definition: rsakey.c:51
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
SYMCRYPT_RSAKEY * PSYMCRYPT_RSAKEY
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by alloc_rsa_key().

◆ SymCryptRsakeyCalculatePrimesFromPrivateExponent()

static SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyCalculatePrimesFromPrivateExponent ( _Inout_ PSYMCRYPT_RSAKEY  pkRsakey,
_In_reads_bytes_(cbPrivateExponent) PCBYTE  pbPrivateExponent,
SIZE_T  cbPrivateExponent,
SYMCRYPT_NUMBER_FORMAT  numFormat,
_Out_writes_bytes_(cbScratch) PBYTE  pbScratch,
UINT32  cbScratch 
)
static

Definition at line 815 of file rsakey.c.

824{
825 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
826
827 // 3 digit sizes of temporary integers:
828 // - ndMod = pkRsakey->nDigitsOfModulus
829 // - ndPubExp = digits for a UINT64 public exponent
830 // - ndExpProd = ndMod + ndPubExp
831
832 UINT32 ndMod = pkRsakey->nDigitsOfModulus;
833 UINT32 cbMod = SymCryptSizeofIntFromDigits( ndMod );
834
835 UINT32 ndPubExp = SymCryptDigitsFromBits( 64 );
836 UINT32 cbPubExp = SymCryptSizeofIntFromDigits( ndPubExp );
837
838 UINT32 nBitsExpProd = 0; // we compute this later before use
839 UINT32 ndExpProd = ndMod + ndPubExp;
840 UINT32 cbExpProd = SymCryptSizeofIntFromDigits( ndExpProd );
841
842 UINT32 cbModElement = SYMCRYPT_SIZEOF_MODELEMENT_FROM_BITS( pkRsakey->nBitsOfModulus );
843
844 PSYMCRYPT_INT piPrivExp = NULL;
845 PSYMCRYPT_INT piPubExp = NULL;
846 PSYMCRYPT_INT piExpProd = NULL;
847 PSYMCRYPT_MODELEMENT peTmpY = NULL;
848 PSYMCRYPT_MODELEMENT peTmpX = NULL;
849 PSYMCRYPT_MODELEMENT peTmpPtr = NULL;
851 PSYMCRYPT_MODELEMENT peNegOne = NULL;
852
853 PBYTE pbFnScratch = pbScratch;
854 UINT32 cbFnScratch = cbScratch;
855
856 UINT64 low64ExpProd = 0;
857 UINT32 trailingZeros = 0;
858
859 BOOL bFoundNonTrivialRoot = FALSE;
860
861 //
862 // Recover primes from private exponent using probabilistic prime-factor recovery method
863 // See SP800-56B rev2 Appendix C.1 and Boneh 1999
864 //
865 SYMCRYPT_ASSERT( pkRsakey->nPrimes == 2 );
866 SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_PRIME_RECOVERY(ndMod, ndPubExp, pkRsakey->nBitsOfModulus) );
867
868 piPrivExp = SymCryptIntCreate( pbFnScratch, cbMod, ndMod );
869 SYMCRYPT_ASSERT( piPrivExp != NULL );
870 pbFnScratch += cbMod;
871 cbFnScratch -= cbMod;
872 piPubExp = SymCryptIntCreate( pbFnScratch, cbPubExp, ndPubExp );
873 SYMCRYPT_ASSERT( piPubExp != NULL );
874 pbFnScratch += cbPubExp;
875 cbFnScratch -= cbPubExp;
876 piExpProd = SymCryptIntCreate( pbFnScratch, cbExpProd, ndExpProd );
877 SYMCRYPT_ASSERT( piExpProd != NULL );
878 pbFnScratch += cbExpProd;
879 cbFnScratch -= cbExpProd;
880
881 peTmpY = SymCryptModElementCreate( pbFnScratch, cbModElement, pkRsakey->pmModulus );
882 SYMCRYPT_ASSERT( peTmpY != NULL );
883 pbFnScratch += cbModElement;
884 cbFnScratch -= cbModElement;
885 peTmpX = SymCryptModElementCreate( pbFnScratch, cbModElement, pkRsakey->pmModulus );
886 SYMCRYPT_ASSERT( peTmpX != NULL );
887 pbFnScratch += cbModElement;
888 cbFnScratch -= cbModElement;
889 peOne = SymCryptModElementCreate( pbFnScratch, cbModElement, pkRsakey->pmModulus );
890 SYMCRYPT_ASSERT( peOne != NULL );
891 pbFnScratch += cbModElement;
892 cbFnScratch -= cbModElement;
893 peNegOne = SymCryptModElementCreate( pbFnScratch, cbModElement, pkRsakey->pmModulus );
894 SYMCRYPT_ASSERT( peNegOne != NULL );
895 pbFnScratch += cbModElement;
896 cbFnScratch -= cbModElement;
897
898 // Ensure that modulus is odd - this is required for later SymCryptIntExtendedGcd
899 if( (SymCryptIntGetValueLsbits32(SymCryptIntFromModulus( pkRsakey->pmModulus ))& 1)==0 )
900 {
901 scError = SYMCRYPT_INVALID_ARGUMENT;
902 goto cleanup;
903 }
904
905 // Import private exponent
906 scError = SymCryptIntSetValue(pbPrivateExponent, cbPrivateExponent, numFormat, piPrivExp);
907 if( scError != SYMCRYPT_NO_ERROR )
908 {
909 // The integer cannot fit the private exponent (SYMCRYPT_BUFFER_TOO_SMALL),
910 // only if the caller providing a private exponent larger than the public modulus
911 scError = SYMCRYPT_INVALID_ARGUMENT;
912 goto cleanup;
913 }
914
915 // Basic range check
916 if( !SymCryptIntIsLessThan(piPrivExp, SymCryptIntFromModulus(pkRsakey->pmModulus)) )
917 {
918 scError = SYMCRYPT_INVALID_ARGUMENT;
919 goto cleanup;
920 }
921
922 // Given range check, we can guarantee to compute
923 // Private exponent (d) * Public exponent (e)
924 // In piExpProd without overflow
925 SymCryptIntSetValueUint64( pkRsakey->au64PubExp[0], piPubExp );
926
927 // compute upper bound on product bit count based on public data (nBitsOfModulus (public) >= nBitsOfPrivateExponent (private))
928 nBitsExpProd = pkRsakey->nBitsOfModulus + SymCryptIntBitsizeOfValue( piPubExp );
929
930 SymCryptIntMulMixedSize( piPrivExp, piPubExp, piExpProd, pbFnScratch, cbFnScratch );
931
932 // Ensure d*e is odd
933 low64ExpProd = SymCryptIntGetValueLsbits64( piExpProd );
934
935 if( (low64ExpProd & 1) == 0 )
936 {
937 scError = SYMCRYPT_INVALID_ARGUMENT;
938 goto cleanup;
939 }
940
941 // Compute how many trailing zeros in m = d*e - 1
942 //
943 // We are variable time w.r.t. the number of trailing (up to 64) zeroes. An attacker using
944 // sidechannels to determine the number of trailing zeroes of m can glean information about
945 // the private exponent proportionate to the number of trailing zeroes. As we bound this to
946 // 64, at most an attacker can theoretically determine 64-bits of an expected 2048-bits of
947 // private exponent - and they can only do this for 1 in 2^64 keys.
948 //
949 // It would be possible to mask the number of trailing zeroes from sidechannels by always
950 // squaring by 64 times in the inner loop below and using masked operations to select out
951 // any found non-trivial root. We can consider doing this as a hardening measure if this API
952 // does see a lot of usage, but the expectation is that this method will almost never be
953 // used and it is just not enough of a leak for an attacker to even try to measuring.
954 trailingZeros = SymCryptCountTrailingZeros64( low64ExpProd-1 );
955
956 // If there are 64 trailing zeroes then we abort because the prime factor recovery method
957 // could theoretically leak more than 64-bits of the private exponent. The likelihood of any
958 // key which has this many trailing zeroes _ever_ having being generated by a legitimate key
959 // generation process is extremely small given the cost of RSA key generation. This much more
960 // likely indicates faulty inputs or a hardware fault rather than a legitimate keypair we
961 // should try to import.
962 if( trailingZeros == 64 )
963 {
964 scError = SYMCRYPT_INVALID_ARGUMENT;
965 goto cleanup;
966 }
967
968 SymCryptIntDivPow2( piExpProd, trailingZeros, piExpProd ); // r = m >> t
969 SymCryptModElementSetValueUint32( 1, pkRsakey->pmModulus, peOne, pbFnScratch, cbFnScratch );
970 SymCryptModElementSetValueNegUint32( 1, pkRsakey->pmModulus, peNegOne, pbFnScratch, cbFnScratch );
971
973 {
974 // y is random value g in [2,n-2]
975 SymCryptModSetRandom( pkRsakey->pmModulus, peTmpY, 0, pbFnScratch, cbFnScratch );
976
977 // ModExp y = g^r in place
978 // could make this a bit faster and leakier using trailingZeros to reduce nBitsExp, but
979 // not normally a big performance win
981 pkRsakey->pmModulus,
982 peTmpY,
983 piExpProd,
984 nBitsExpProd-1,
985 0,
986 peTmpY,
987 pbFnScratch, cbFnScratch );
988
989 // if y == 1 or y == -1, start over (we found a trivial root of 1)
990 if( SymCryptModElementIsEqual( pkRsakey->pmModulus, peTmpY, peOne ) ||
991 SymCryptModElementIsEqual( pkRsakey->pmModulus, peTmpY, peNegOne ) )
992 {
993 continue;
994 }
995
996 for( UINT32 j=1; j<=trailingZeros; j++ )
997 {
998 // x = y^2
999 SymCryptModSquare( pkRsakey->pmModulus, peTmpY, peTmpX, pbFnScratch, cbFnScratch );
1000
1001 // if x == 1 then y is a non-trivial root of 1 (it is not -1 or 1)
1002 if( SymCryptModElementIsEqual( pkRsakey->pmModulus, peTmpX, peOne) )
1003 {
1004 bFoundNonTrivialRoot = TRUE;
1005 break;
1006 }
1007
1008 // if x == -1, start over
1009 if( SymCryptModElementIsEqual( pkRsakey->pmModulus, peTmpX, peNegOne) )
1010 {
1011 break; // just break out of inner loop; continues outer loop
1012 }
1013
1014 // swap x and y
1015 peTmpPtr = peTmpY;
1016 peTmpY = peTmpX;
1017 peTmpX = peTmpPtr;
1018 }
1019 if( bFoundNonTrivialRoot )
1020 {
1021 break;
1022 }
1023 }
1024
1025 if( !bFoundNonTrivialRoot )
1026 {
1027 // we failed to find a non-trivial root of 1, so we cannot recover prime factors
1028 // it is almost certain that this means that the inputs were wrong
1029 scError = SYMCRYPT_INVALID_ARGUMENT;
1030 goto cleanup;
1031 }
1032
1033 // piPrivExp = y
1034 SymCryptModElementToInt( pkRsakey->pmModulus, peTmpY, piPrivExp, pbFnScratch, cbFnScratch );
1035 // piPrivExp = y-1 (we know this cannot borrow as y^2 is 1, so y != 0)
1036 SymCryptIntSubUint32( piPrivExp, 1, piPrivExp );
1037
1038 // piPrivExp = p0 = GCD(y-1, n)
1040 piPrivExp,
1041 SymCryptIntFromModulus( pkRsakey->pmModulus ),
1043 piPrivExp,
1044 NULL,
1045 NULL,
1046 NULL,
1047 pbFnScratch, cbFnScratch );
1048
1049 // compute the sizes of the primes
1050 pkRsakey->nBitsOfPrimes[0] = SymCryptIntBitsizeOfValue(piPrivExp);
1051 pkRsakey->nBitsOfPrimes[1] = pkRsakey->nBitsOfModulus - pkRsakey->nBitsOfPrimes[0];
1052 for( UINT32 i=0; i<2; i++ )
1053 {
1054 pkRsakey->nDigitsOfPrimes[i] = SymCryptDigitsFromBits(pkRsakey->nBitsOfPrimes[i]);
1055 if( pkRsakey->nBitsOfPrimes[i] < SYMCRYPT_RSAKEY_MIN_BITSIZE_PRIME )
1056 {
1057 scError = SYMCRYPT_WRONG_KEY_SIZE;
1058 goto cleanup;
1059 }
1060 }
1061 pkRsakey->nMaxDigitsOfPrimes = SYMCRYPT_MAX(pkRsakey->nDigitsOfPrimes[0], pkRsakey->nDigitsOfPrimes[1]);
1062
1063 // Create all the objects
1065
1066 scError = SymCryptIntCopyMixedSize( piPrivExp, SymCryptIntFromModulus( pkRsakey->pmPrimes[0] ) );
1067 if( scError != SYMCRYPT_NO_ERROR )
1068 {
1069 // only fails if we computed the wrong bit-size for the primes above
1070 scError = SYMCRYPT_HARDWARE_FAILURE;
1071 goto cleanup;
1072 }
1073
1074 SymCryptIntToModulus( SymCryptIntFromModulus( pkRsakey->pmPrimes[0] ),
1075 pkRsakey->pmPrimes[0],
1076 pkRsakey->nBitsOfModulus, // Average number of operations
1078 pbFnScratch, cbFnScratch );
1079
1080 SymCryptIntDivMod( SymCryptIntFromModulus( pkRsakey->pmModulus ),
1081 SymCryptDivisorFromModulus( pkRsakey->pmPrimes[0] ),
1082 piExpProd, // n / p0 - use piExpProd as Quotient.nDigits must be >= Src.nDigits
1083 piPrivExp, // n % p0 - use piPrivExp as Remainder.nDigits must be >= Divisor.nDigits
1084 pbFnScratch, cbFnScratch );
1085
1086 // Check remainder from dividing n by p0 is 0
1087 if( !SymCryptIntIsEqualUint32( piPrivExp, 0 ) )
1088 {
1089 // Should always be true as p0 is GCD(y-1, n) so is definitionally a divisor of n
1090 // Failure here indicates something wrong in our math, or hardware failure
1091 scError = SYMCRYPT_HARDWARE_FAILURE;
1092 goto cleanup;
1093 }
1094
1095 scError = SymCryptIntCopyMixedSize( piExpProd, SymCryptIntFromModulus( pkRsakey->pmPrimes[1] ) );
1096 if( scError != SYMCRYPT_NO_ERROR )
1097 {
1098 // only fails if we computed the wrong bit-size for the primes above
1099 scError = SYMCRYPT_HARDWARE_FAILURE;
1100 goto cleanup;
1101 }
1102
1103 SymCryptIntToModulus( SymCryptIntFromModulus( pkRsakey->pmPrimes[1] ),
1104 pkRsakey->pmPrimes[1],
1105 pkRsakey->nBitsOfModulus, // Average number of operations
1107 pbFnScratch, cbFnScratch );
1108
1109cleanup:
1110 return scError;
1111}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
BYTE * PBYTE
Definition: pedump.c:66
#define SYMCRYPT_MAX_PRIME_RECOVERY_ITERATIONS
Definition: rsakey.c:797
#define SYMCRYPT_SCRATCH_BYTES_FOR_PRIME_RECOVERY(_ndMod, _ndPubExp, _nBitsMod)
Definition: rsakey.c:799
VOID SYMCRYPT_CALL SymCryptRsakeyCreateAllObjects(_Inout_ PSYMCRYPT_RSAKEY pkRsakey)
Definition: rsakey.c:312
FORCEINLINE UINT32 SymCryptCountTrailingZeros64(UINT64 value)
Definition: sc_lib.h:5045
UINT32 UINT32 UINT32 UINT32 cbScratch
SYMCRYPT_ERROR
Definition: symcrypt.h:227
SYMCRYPT_MODELEMENT * PSYMCRYPT_MODELEMENT
#define SYMCRYPT_RSAKEY_MIN_BITSIZE_PRIME
UINT32 cbModElement
SYMCRYPT_INT * PSYMCRYPT_INT
UINT32 SYMCRYPT_CALL SymCryptIntGetValueLsbits32(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:270
#define SYMCRYPT_FLAG_GCD_INPUTS_NOT_BOTH_EVEN
UINT32 SYMCRYPT_CALL SymCryptIntIsLessThan(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2)
Definition: a_dispatch.c:442
VOID SYMCRYPT_CALL SymCryptIntDivPow2(_In_ PCSYMCRYPT_INT piSrc, SIZE_T exp, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:364
VOID SYMCRYPT_CALL SymCryptIntSetValueUint64(UINT64 u64Src, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:239
PSYMCRYPT_DIVISOR SYMCRYPT_CALL SymCryptDivisorFromModulus(_In_ PSYMCRYPT_MODULUS pmSrc)
Definition: a_dispatch.c:703
UINT32 SymCryptDigitsFromBits(UINT32 nBits)
Definition: a_dispatch.c:111
UINT32 SYMCRYPT_CALL SymCryptModElementIsEqual(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc1, _In_ PCSYMCRYPT_MODELEMENT peSrc2)
Definition: a_dispatch.c:818
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptIntCopyMixedSize(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:214
VOID SYMCRYPT_CALL SymCryptModSetRandom(_In_ PCSYMCRYPT_MODULUS pmMod, _Out_ PSYMCRYPT_MODELEMENT peDst, UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:993
#define SYMCRYPT_FLAG_MODULUS_PARITY_PUBLIC
UINT64 SYMCRYPT_CALL SymCryptIntGetValueLsbits64(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:277
#define SYMCRYPT_FLAG_MODULUS_PRIME
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptIntSetValue(_In_reads_bytes_(cbSrc) PCBYTE pbSrc, SIZE_T cbSrc, SYMCRYPT_NUMBER_FORMAT format, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:248
PSYMCRYPT_MODELEMENT SYMCRYPT_CALL SymCryptModElementCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, _In_ PCSYMCRYPT_MODULUS pmMod)
Definition: a_dispatch.c:665
VOID SYMCRYPT_CALL SymCryptModElementSetValueUint32(UINT32 value, _In_ PCSYMCRYPT_MODULUS pmMod, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:908
VOID SYMCRYPT_CALL SymCryptModElementToInt(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_ PSYMCRYPT_INT piDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:762
UINT32 SYMCRYPT_CALL SymCryptIntSubUint32(_In_ PCSYMCRYPT_INT piSrc1, UINT32 Src2, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:314
VOID SYMCRYPT_CALL SymCryptModSquare(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:881
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptIntFromModulus(_In_ PSYMCRYPT_MODULUS pmSrc)
Definition: a_dispatch.c:720
UINT32 SYMCRYPT_CALL SymCryptIntIsEqualUint32(_In_ PCSYMCRYPT_INT piSrc1, _In_ UINT32 u32Src2)
Definition: a_dispatch.c:424
UINT32 SYMCRYPT_CALL SymCryptIntBitsizeOfValue(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:223
VOID SYMCRYPT_CALL SymCryptIntMulMixedSize(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, _Out_ PSYMCRYPT_INT piDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:485
VOID SYMCRYPT_CALL SymCryptIntToModulus(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_MODULUS pmDst, UINT32 averageOperations, UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:727
VOID SYMCRYPT_CALL SymCryptModExp(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peBase, _In_ PCSYMCRYPT_INT piExp, UINT32 nBitsExp, UINT32 flags, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:961
VOID SYMCRYPT_CALL SymCryptIntDivMod(_In_ PCSYMCRYPT_INT piSrc, _In_ PCSYMCRYPT_DIVISOR pdDivisor, _Out_opt_ PSYMCRYPT_INT piQuotient, _Out_opt_ PSYMCRYPT_INT piRemainder, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:573
VOID SYMCRYPT_CALL SymCryptModElementSetValueNegUint32(UINT32 value, _In_ PCSYMCRYPT_MODULUS pmMod, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:922
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptIntCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, UINT32 nDigits)
Definition: a_dispatch.c:141
VOID SYMCRYPT_CALL SymCryptIntExtendedGcd(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, UINT32 flags, _Out_opt_ PSYMCRYPT_INT piGcd, _Out_opt_ PSYMCRYPT_INT piLcm, _Out_opt_ PSYMCRYPT_INT piInvSrc1ModSrc2, _Out_opt_ PSYMCRYPT_INT piInvSrc2ModSrc1, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: gen_int.c:176
uint32_t UINT32
Definition: typedefs.h:59

Referenced by SymCryptRsakeySetValueInternal().

◆ SymCryptRsakeyCalculatePrivateFields()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyCalculatePrivateFields ( _Inout_ PSYMCRYPT_RSAKEY  pkRsakey,
_Out_ PSYMCRYPT_DIVISOR  pdTmp,
_Out_ PSYMCRYPT_INT  piPhi,
_Out_ PSYMCRYPT_INT  piAcc,
_Out_writes_bytes_(cbScratch) PBYTE  pbScratch,
SIZE_T  cbScratch,
UINT32  flags 
)

Definition at line 357 of file rsakey.c.

367{
368 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
370 PSYMCRYPT_INT piTmpGcd;
371
372 // Use pdTmp as int scratch
374
376
377 if ( ( flags & ~allowedFlags ) != 0 )
378 {
379 scError = SYMCRYPT_INVALID_ARGUMENT;
380 goto cleanup;
381 }
382
383 // We need a 1-digit tmp value to store the GCD in.
384 // Simpler to put it on the stack than to add full scratch size computation support to this function
385 piTmpGcd = SymCryptIntCreate( SYMCRYPT_ASYM_ALIGN_UP( tmpGcdBuf ), sizeof( tmpGcdBuf ) - SYMCRYPT_ASYM_ALIGN_VALUE, SymCryptDigitsFromBits( 64 ) );
386
387 // Run the CRT generation
388 scError = SymCryptCrtGenerateInverses( pkRsakey->nPrimes, pkRsakey->pmPrimes, 0, pkRsakey->peCrtInverses, pbScratch, cbScratch);
389 if (scError!=SYMCRYPT_NO_ERROR)
390 {
391 goto cleanup;
392 }
393
394 // Calculate Phi
395 SymCryptIntSetValueUint32( 1, piPhi );
396 for (UINT32 i=0; i<pkRsakey->nPrimes; i++)
397 {
398 // piScr can have the different number of digits than each prime
399 scError = SymCryptIntCopyMixedSize( SymCryptIntFromModulus( pkRsakey->pmPrimes[i] ), piScr );
400 if (scError!=SYMCRYPT_NO_ERROR)
401 {
402 goto cleanup;
403 }
404 SymCryptIntSubUint32( piScr, 1, piScr ); // p-1
405 SymCryptIntMulMixedSize( piScr, piPhi, piAcc, pbScratch, cbScratch );
406 scError = SymCryptIntCopyMixedSize( piAcc, piPhi );
407 if (scError!=SYMCRYPT_NO_ERROR)
408 {
409 goto cleanup;
410 }
411 }
412
413 // Calculate the private exponents
414 for (UINT32 i=0; i<pkRsakey->nPubExp; i++)
415 {
416 // IntExtendedGcd requirements:
417 // - First argument > 0: piPhi as the product of p-1's
418 // - Second argument: odd, verified below
419 // We also reject public exponent 1, as that is obviously unsafe.
420 if( /* pkRsakey->au64PubExp[i] == 1 || */ (pkRsakey->au64PubExp[i] & 1) != 1)
421 {
422 scError = SYMCRYPT_INVALID_ARGUMENT;
423 goto cleanup;
424 }
425
426 // Calculate D
427 SymCryptIntSetValueUint64( pkRsakey->au64PubExp[i], piScr );
428
429 // Calculate D
431 piPhi,
432 piScr,
434 piTmpGcd, // Gcd
435 NULL, // Lcm
436 NULL, // InvSrc1ModSrc2
437 pkRsakey->piPrivExps[i],
438 pbScratch,
439 cbScratch);
440
441 if( !SymCryptIntIsEqualUint32( piTmpGcd, 1 ) )
442 {
443 scError = SYMCRYPT_INVALID_ARGUMENT;
444 goto cleanup;
445 }
446 }
447
448 //Calculate the private exponents modulo each prime minus 1
449 for (UINT32 i=0; i<pkRsakey->nPrimes; i++)
450 {
451 scError = SymCryptIntCopyMixedSize( SymCryptIntFromModulus(pkRsakey->pmPrimes[i]), SymCryptIntFromDivisor(pdTmp) );
452 if (scError!=SYMCRYPT_NO_ERROR)
453 {
454 goto cleanup;
455 }
456
457 // IntToDivisor requirement:
458 // Each prime has at least SYMCRYPT_RSAKEY_MIN_BITSIZE_PRIME bits --> P-1 > 0
462 pdTmp,
463 pkRsakey->nPubExp,
464 0,
465 pbScratch,
466 cbScratch );
467
468 for (UINT32 j=0; j<pkRsakey->nPubExp; j++)
469 {
471 pkRsakey->piPrivExps[j],
472 pdTmp,
473 NULL,
474 piPhi, // Set it to Phi as each private exponent might have different size
475 pbScratch,
476 cbScratch );
477
478 scError = SymCryptIntCopyMixedSize( piPhi, pkRsakey->piCrtPrivExps[ j*pkRsakey->nPrimes + i ]);
479 if (scError!=SYMCRYPT_NO_ERROR)
480 {
481 goto cleanup;
482 }
483 }
484 }
485
486 // Check that the product of the primes is in fact the modulus
488 {
489 if( pkRsakey->nPrimes != 2 )
490 {
491 scError = SYMCRYPT_INVALID_ARGUMENT;
492 goto cleanup;
493 }
494
496 SymCryptIntFromModulus(pkRsakey->pmPrimes[0]),
497 SymCryptIntFromModulus(pkRsakey->pmPrimes[1]),
498 piAcc,
499 pbScratch, cbScratch );
500
501 if( !SymCryptIntIsEqual( piAcc, SymCryptIntFromModulus( pkRsakey->pmModulus ) ) )
502 {
503 scError = SYMCRYPT_INVALID_ARGUMENT;
504 goto cleanup;
505 }
506 }
507
508cleanup:
509 return scError;
510}
#define SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION
Definition: symcrypt.h:7586
#define SYMCRYPT_ASYM_ALIGN_VALUE
#define SYMCRYPT_ASYM_ALIGN_UP(_p)
#define SYMCRYPT_SIZEOF_INT_FROM_BITS(_bitsize)
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptCrtGenerateInverses(UINT32 nCoprimes, _In_reads_(nCoprimes) PCSYMCRYPT_MODULUS *ppmCoprimes, UINT32 flags, _Out_writes_(nCoprimes) PSYMCRYPT_MODELEMENT *ppeCrtInverses, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: crt.c:90
VOID SYMCRYPT_CALL SymCryptIntToDivisor(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_DIVISOR pdDst, UINT32 totalOperations, UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:560
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptIntFromDivisor(_In_ PSYMCRYPT_DIVISOR pdSrc)
Definition: a_dispatch.c:553
VOID SYMCRYPT_CALL SymCryptIntSetValueUint32(UINT32 u32Src, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:230
UINT32 SYMCRYPT_CALL SymCryptIntIsEqual(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2)
Definition: a_dispatch.c:433
unsigned char BYTE
Definition: xxhash.c:193

Referenced by SymCryptRsakeyGenerate(), and SymCryptRsakeySetValueInternal().

◆ SymCryptRsakeyCreate()

PSYMCRYPT_RSAKEY SYMCRYPT_CALL SymCryptRsakeyCreate ( _Out_writes_bytes_(cbBuffer) PBYTE  pbBuffer,
SIZE_T  cbBuffer,
_In_ PCSYMCRYPT_RSA_PARAMS  pParams 
)

Definition at line 83 of file rsakey.c.

87{
88 PSYMCRYPT_RSAKEY pkObj = NULL;
89
90 PBYTE pbCurr = pbBuffer;
91 SIZE_T cbNeeded;
92 SIZE_T itemSize;
93
94 SYMCRYPT_ASSERT( pParams != NULL );
95
96 cbNeeded = SymCryptSizeofRsakeyFromParams( pParams );
97
99
100 if (( cbBuffer < cbNeeded ) ||
101 ( pParams->nBitsOfModulus < SYMCRYPT_RSAKEY_MIN_BITSIZE_MODULUS ) ||
102 ( pParams->nBitsOfModulus > SYMCRYPT_RSAKEY_MAX_BITSIZE_MODULUS ) ||
103 ( pParams->nPubExp < 1 ) ||
104 ( pParams->nPubExp > SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS ) ||
105 ( pParams->nPrimes == 1 ) ||
106 ( pParams->nPrimes > SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES ) )
107 {
108 goto cleanup;
109 }
111
112 pkObj = (PSYMCRYPT_RSAKEY) pbCurr;
113
114 // Set all the parameters to 0
115 SymCryptWipe( pbBuffer, cbBuffer );
116
117 // Main parameters of the RSAKEY
118 // Everything is 0 until created
119
120 pkObj->cbTotalSize = (UINT32) cbNeeded;
121 // The result should always be within 4 GB, but we check to avoid security bugs
122 SYMCRYPT_ASSERT( pkObj->cbTotalSize == cbNeeded );
123
124 pkObj->hasPrivateKey = FALSE;
125
126 pkObj->nSetBitsOfModulus = pParams->nBitsOfModulus;
127 pkObj->nDigitsOfModulus = SymCryptDigitsFromBits( pkObj->nSetBitsOfModulus ); // The modulus object has always this number of digits
128
129 pkObj->nPrimes = pParams->nPrimes;
130 pkObj->nPubExp = pParams->nPubExp;
131
132 pbCurr += sizeof( SYMCRYPT_RSAKEY );
133
134 // Modulus
135 itemSize = SymCryptSizeofModulusFromDigits( pkObj->nDigitsOfModulus );
136 SYMCRYPT_ASSERT( cbBuffer >= sizeof( SYMCRYPT_RSAKEY ) + itemSize
137 + (pkObj->nPrimes*SymCryptSizeofModulusFromDigits( pkObj->nDigitsOfModulus ))
138 + (pkObj->nPrimes*SYMCRYPT_SIZEOF_MODELEMENT_FROM_BITS( pParams->nBitsOfModulus ))
139 + (pkObj->nPubExp*SymCryptSizeofIntFromDigits( pkObj->nDigitsOfModulus ))
140 + (pkObj->nPubExp*pkObj->nPrimes*SymCryptSizeofIntFromDigits( pkObj->nDigitsOfModulus )) );
141 pkObj->pmModulus = SymCryptModulusCreate(
142 pbCurr,
143 itemSize,
144 pkObj->nDigitsOfModulus );
145 SYMCRYPT_ASSERT( pkObj->pmModulus != NULL );
146 pbCurr += itemSize;
147
148 // For the remaining objects
149 // defer creation until SymCryptRsakeyGenerate or
150 // SymCryptRsakeySetValue
151
152 // Primes
153 for (UINT32 i=0; i<pkObj->nPrimes; i++)
154 {
155 pkObj->pbPrimes[i] = pbCurr;
156 pbCurr += SymCryptSizeofModulusFromDigits( pkObj->nDigitsOfModulus );
157 }
158
159 // CRT Inverses of primes
160 for (UINT32 i=0; i<pkObj->nPrimes; i++)
161 {
162 pkObj->pbCrtInverses[i] = pbCurr;
163 pbCurr += SYMCRYPT_SIZEOF_MODELEMENT_FROM_BITS( pParams->nBitsOfModulus );
164 }
165
166 // Private exponents
167 for (UINT32 i=0; i<pkObj->nPubExp; i++)
168 {
169 pkObj->pbPrivExps[i] = pbCurr;
170 pbCurr += SymCryptSizeofIntFromDigits( pkObj->nDigitsOfModulus );
171 }
172
173 // Private exponents modulo each prime (minus 1)
174 for (UINT32 i=0; i<pkObj->nPubExp*pkObj->nPrimes; i++)
175 {
176 pkObj->pbCrtPrivExps[i] = pbCurr;
177 pbCurr += SymCryptSizeofIntFromDigits( pkObj->nDigitsOfModulus );
178 }
179
180 // Setting the magic
181 SYMCRYPT_SET_MAGIC( pkObj );
182
183cleanup:
184 return pkObj;
185}
#define SYMCRYPT_ASSERT_ASYM_ALIGNED(_p)
Definition: sc_lib.h:1912
SIZE_T cbBuffer
Definition: sc_lib_mldsa.h:405
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
SYMCRYPT_MAGIC_FIELD SYMCRYPT_RSAKEY
#define SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES
#define SYMCRYPT_SET_MAGIC(p)
#define SYMCRYPT_RSAKEY_MAX_BITSIZE_MODULUS
#define SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS
#define SYMCRYPT_RSAKEY_MIN_BITSIZE_MODULUS
PSYMCRYPT_MODULUS SYMCRYPT_CALL SymCryptModulusCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, UINT32 nDigits)
Definition: a_dispatch.c:608
UINT32 SYMCRYPT_CALL SymCryptSizeofModulusFromDigits(UINT32 nDigits)
Definition: a_dispatch.c:601

Referenced by SymCryptRsakeyAllocate().

◆ SymCryptRsakeyCreateAllObjects()

VOID SYMCRYPT_CALL SymCryptRsakeyCreateAllObjects ( _Inout_ PSYMCRYPT_RSAKEY  pkRsakey)

Definition at line 312 of file rsakey.c.

313{
314 // Primes
315 for (UINT32 i=0; i<pkRsakey->nPrimes; i++)
316 {
317 pkRsakey->pmPrimes[i] = SymCryptModulusCreate(
318 pkRsakey->pbPrimes[i],
319 SymCryptSizeofModulusFromDigits( pkRsakey->nDigitsOfPrimes[i] ),
320 pkRsakey->nDigitsOfPrimes[i] );
321 SYMCRYPT_ASSERT( pkRsakey->pmPrimes[i] != NULL );
322 }
323
324 // CRT Inverses of primes
325 for (UINT32 i=0; i<pkRsakey->nPrimes; i++)
326 {
327 pkRsakey->peCrtInverses[i] = SymCryptModElementCreate(
328 pkRsakey->pbCrtInverses[i],
329 SymCryptSizeofModElementFromModulus( pkRsakey->pmPrimes[i] ),
330 pkRsakey->pmPrimes[i] );
331 SYMCRYPT_ASSERT( pkRsakey->peCrtInverses[i] != NULL );
332 }
333
334 // Private exponents
335 for( UINT32 i=0; i<pkRsakey->nPubExp; i++ )
336 {
337 pkRsakey->piPrivExps[i] = SymCryptIntCreate(
338 pkRsakey->pbPrivExps[i],
339 SymCryptSizeofIntFromDigits( pkRsakey->nDigitsOfModulus ),
340 pkRsakey->nDigitsOfModulus );
341 SYMCRYPT_ASSERT( pkRsakey->piPrivExps[i] != NULL );
342 }
343
344 // Private exponents modulo each prime (minus 1)
345 for (UINT32 i=0; i<pkRsakey->nPubExp*pkRsakey->nPrimes; i++)
346 {
347 pkRsakey->piCrtPrivExps[i] = SymCryptIntCreate(
348 pkRsakey->pbCrtPrivExps[i],
349 SymCryptSizeofIntFromDigits( pkRsakey->nDigitsOfPrimes[i] ),
350 pkRsakey->nDigitsOfPrimes[i] );
351 SYMCRYPT_ASSERT( pkRsakey->piCrtPrivExps[i] != NULL );
352 }
353}
UINT32 SYMCRYPT_CALL SymCryptSizeofModElementFromModulus(PCSYMCRYPT_MODULUS pmMod)
Definition: a_dispatch.c:658

Referenced by SymCryptRsakeyCalculatePrimesFromPrivateExponent(), SymCryptRsakeyGenerate(), and SymCryptRsakeySetValueInternal().

◆ SymCryptRsakeyExtendKeyUsage()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyExtendKeyUsage ( _Inout_ PSYMCRYPT_RSAKEY  pkRsakey,
UINT32  flags 
)

Definition at line 1611 of file rsakey.c.

1614{
1615 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
1616
1617 // Ensure caller has specified what algorithm(s) the key will be used with
1619
1620 if ( ( ( flags & ~algorithmFlags ) != 0 ) ||
1621 ( ( flags & algorithmFlags ) == 0) )
1622 {
1623 scError = SYMCRYPT_INVALID_ARGUMENT;
1624 goto cleanup;
1625 }
1626
1627 pkRsakey->fAlgorithmInfo |= flags;
1628
1629cleanup:
1630 return scError;
1631}
#define SYMCRYPT_FLAG_RSAKEY_SIGN
Definition: symcrypt.h:7598
#define SYMCRYPT_FLAG_RSAKEY_ENCRYPT
Definition: symcrypt.h:7599

◆ SymCryptRsakeyFree()

VOID SYMCRYPT_CALL SymCryptRsakeyFree ( _Out_ PSYMCRYPT_RSAKEY  pkObj)

Definition at line 42 of file rsakey.c.

43{
44 SYMCRYPT_CHECK_MAGIC( pkObj );
45 SymCryptRsakeyWipe( pkObj );
46 SymCryptCallbackFree( pkObj );
47}
void SYMCRYPT_CALL SymCryptCallbackFree(void *ptr)
Definition: implglue.c:42
VOID SYMCRYPT_CALL SymCryptRsakeyWipe(_Out_ PSYMCRYPT_RSAKEY pkDst)
Definition: rsakey.c:189
#define SYMCRYPT_CHECK_MAGIC(p)

Referenced by free_key_impl(), and new_key_impl().

◆ SymCryptRsakeyGenerate()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyGenerate ( _Inout_ PSYMCRYPT_RSAKEY  pkRsakey,
_In_reads_opt_(nPubExp) PCUINT64  pu64PubExp,
UINT32  nPubExp,
_In_ UINT32  flags 
)

Definition at line 514 of file rsakey.c.

519{
520 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
521
522 // 3 sizes of temporary elements:
523 // - ndPrimes = number of digit size of each prime (we choose it to be the same for all primes)
524 // - ndMod = pkRsakey->nDigitsOfModulus
525 // - ndLarge = ndPrimes + ndMod
526
527 UINT32 ndPrimes = 0;
528
529 UINT32 cbPrimes = 0;
530 PSYMCRYPT_INT piLow = NULL;
531 PSYMCRYPT_INT piHigh = NULL;
532
533 UINT32 cbDivisor = 0;
534 PSYMCRYPT_DIVISOR pdTmp = NULL;
535
536 UINT32 ndMod = pkRsakey->nDigitsOfModulus;
537 UINT32 cbMod = 0;
538 PSYMCRYPT_INT piPhi = NULL;
539
540 UINT32 ndLarge = 0;
541 UINT32 cbLarge = 0;
542 PSYMCRYPT_INT piAcc = NULL;
543
544 PBYTE pbScratch = NULL;
545 UINT32 cbScratch = 0;
546 PBYTE pbFnScratch = NULL;
547 UINT32 cbFnScratch = 0;
548
549 UINT32 maxTries = 0; // For the prime generation (and the modulus operations ?)
550 UINT32 primeBits = 0;
551
552 const UINT64 defaultExponent = RSA_DEFAULT_PUBLIC_EXPONENT;
553
554 // Ensure caller has specified what algorithm(s) the key will be used with
556 // Ensure only allowed flags are specified
557 UINT32 allowedFlags = SYMCRYPT_FLAG_KEY_NO_FIPS | algorithmFlags;
558
559 if ( ( ( flags & ~allowedFlags ) != 0 ) ||
560 ( ( flags & algorithmFlags ) == 0) )
561 {
562 scError = SYMCRYPT_INVALID_ARGUMENT;
563 goto cleanup;
564 }
565
566 // SymCryptRsaSignVerifyPct requires the generated key to be at least 496 bits to avoid fatal
567 // Require caller to specify NO_FIPS for up to 1024 bits as running FIPS tests on too-small keys
568 // does not make it FIPS certifiable and gives the wrong impression to callers
569 if ( ( (flags & SYMCRYPT_FLAG_KEY_NO_FIPS) == 0 ) &&
570 ( pkRsakey->nSetBitsOfModulus < SYMCRYPT_RSAKEY_FIPS_MIN_BITSIZE_MODULUS ) )
571 {
572 scError = SYMCRYPT_INVALID_ARGUMENT;
573 goto cleanup;
574 }
575
576 // Handle the default exponent case
577 if( pu64PubExp == NULL && nPubExp == 0 )
578 {
579 pu64PubExp = &defaultExponent;
580 nPubExp = 1;
581 }
582
583 // Make sure we have:
584 // - exactly 2 primes
585 // - the right number of public exponents
586 // - exactly 1 public exponent
587 if (pkRsakey->nPrimes != 2 || nPubExp != pkRsakey->nPubExp || nPubExp != 1 )
588 {
589 scError = SYMCRYPT_INVALID_ARGUMENT;
590 goto cleanup;
591 }
592
593 // Copy the public exponent into the key
594 pkRsakey->au64PubExp[0] = pu64PubExp[0];
595
596 // Before doing anything calculate all the needed sizes
597 // The size limits were checked in SymCryptRsakeyCreate which is the only way to create an Rsakey object.
598 pkRsakey->nBitsOfModulus = pkRsakey->nSetBitsOfModulus; // This will be the exact bit size of our modulus
599
600 pkRsakey->nBitsOfPrimes[0] = (pkRsakey->nBitsOfModulus + 1)/2;
601 pkRsakey->nBitsOfPrimes[1] = pkRsakey->nBitsOfModulus/2; // The second prime is one bit smaller for odd-length moduli
602
603 pkRsakey->nDigitsOfPrimes[0] = SymCryptDigitsFromBits(pkRsakey->nBitsOfPrimes[0]);
604 pkRsakey->nDigitsOfPrimes[1] = SymCryptDigitsFromBits(pkRsakey->nBitsOfPrimes[1]);
605
606 pkRsakey->nMaxDigitsOfPrimes = SYMCRYPT_MAX(pkRsakey->nDigitsOfPrimes[0], pkRsakey->nDigitsOfPrimes[1]);
607
608 ndPrimes = pkRsakey->nMaxDigitsOfPrimes;
609 ndLarge = ndPrimes + ndMod;
610
611 primeBits = SYMCRYPT_MAX(pkRsakey->nBitsOfPrimes[0],pkRsakey->nBitsOfPrimes[1]);
612 maxTries = 100 * primeBits;
613
614 // Create all the SymCryptObjects
616
617 // Allocate the temp integers and the scratch space
618 // All sizes are limited by the modulus sizes verified in SymCryptRsakeyCreate
619 cbPrimes = SymCryptSizeofIntFromDigits( ndPrimes );
620 cbMod = SymCryptSizeofIntFromDigits( ndMod );
621 cbLarge = SymCryptSizeofIntFromDigits( ndLarge );
622 cbDivisor = SymCryptSizeofDivisorFromDigits( ndPrimes );
623
624 cbScratch = 2*cbPrimes + cbMod + cbLarge + cbDivisor +
632 ))))));
633
634 pbScratch = (PBYTE)SymCryptCallbackAlloc( cbScratch );
635 if (pbScratch == NULL)
636 {
637 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
638 goto cleanup;
639 }
640
641 pbFnScratch = pbScratch;
642 cbFnScratch = cbScratch;
643
644 // Create temporaries
645 // dcl - this would be easier to review with one statement per line
646 piLow = SymCryptIntCreate( pbFnScratch, cbPrimes, ndPrimes ); pbFnScratch += cbPrimes; cbFnScratch -= cbPrimes;
647 piHigh = SymCryptIntCreate( pbFnScratch, cbPrimes, ndPrimes ); pbFnScratch += cbPrimes; cbFnScratch -= cbPrimes;
648
649 piPhi = SymCryptIntCreate( pbFnScratch, cbMod, ndMod ); pbFnScratch += cbMod; cbFnScratch -= cbMod;
650
651 piAcc = SymCryptIntCreate( pbFnScratch, cbLarge, ndLarge ); pbFnScratch += cbLarge; cbFnScratch -= cbLarge;
652
653 pdTmp = SymCryptDivisorCreate( pbFnScratch, cbDivisor, ndPrimes ); pbFnScratch += cbDivisor; cbFnScratch -= cbDivisor;
654
655 // ***Prime generation limits***
656 //
657 // If nBitsOfModulus is even (main case)
658 // Low limit = 2^{primeBits-1} + 2^{primeBits - 2}
659 // High limit = 2^primeBits - 1
660 //
661 // If nBitsOfModulus is odd we use different
662 // limits for the two primes (until we have an integer sqrt function)
663 //
664 // For the first
665 // Low limit = 2^{primeBits-1} + 2^{primeBits - 2}
666 // High limit = 2^primeBits - 1
667 // For the second
668 // Low limit = 2^{primeBits-2} + 2^{primeBits - 3}
669 // High limit = 2^{primeBits-1} - 1
670 //
671 // Notice that nBitsOfModulus is a public value.
672 //
673 // *** TODO: This works only for 2 primes to give modulus
674 // of exactly nBitsOfModulus bits.
675
676 SymCryptIntSetValueUint32( 3, piLow );
677 SymCryptIntMulPow2( piLow, primeBits - 2, piLow );
678
679 SymCryptIntSetValueUint32( 1, piHigh );
680 SymCryptIntMulPow2( piHigh, primeBits, piHigh );
681 SymCryptIntSubUint32( piHigh, 1, piHigh );
682
683 // Generate primes and at the same time accumulate their product into piPhi
684 SymCryptIntSetValueUint32( 1, piPhi );
685 for (UINT32 i=0; i<pkRsakey->nPrimes; i++)
686 {
687 if ( ((pkRsakey->nBitsOfModulus % 2)==1) && (i>0) )
688 {
689 SymCryptIntDivPow2( piLow, 1, piLow );
690 SymCryptIntDivPow2( piHigh, 1, piHigh );
691 }
692
693 // IntGenerateRandomPrime requirement:
694 // piLow > 3 since nBitsOfModulus is bounded by
695 // SYMCRYPT_RSAKEY_MIN_BITSIZE_MODULUS.
697 piLow,
698 piHigh,
699 pu64PubExp,
700 nPubExp,
701 maxTries,
702 0,
703 SymCryptIntFromModulus( pkRsakey->pmPrimes[i] ),
704 pbFnScratch,
705 cbFnScratch);
706 if (scError!=SYMCRYPT_NO_ERROR)
707 {
708 goto cleanup;
709 }
710
711 // IntToModulus requirement:
712 // piLow > 0 --> pkRsakey->pmPrimes[i] > 0
714 SymCryptIntFromModulus( pkRsakey->pmPrimes[i] ),
715 pkRsakey->pmPrimes[i],
716 pkRsakey->nBitsOfModulus, // Average number of operations
718 pbFnScratch,
719 cbFnScratch );
720
721 SymCryptIntMulMixedSize( SymCryptIntFromModulus( pkRsakey->pmPrimes[i] ), piPhi, piAcc, pbFnScratch, cbFnScratch ); // P_i * Product
722 scError = SymCryptIntCopyMixedSize( piAcc, piPhi ); // Move the result to piPhi
723 if (scError!=SYMCRYPT_NO_ERROR)
724 {
725 goto cleanup;
726 }
727 }
728
729 // IntToModulus requirement:
730 // piPhi product of non-zero primes --> piPhi > 0
731 SymCryptIntCopy( piPhi, SymCryptIntFromModulus( pkRsakey->pmModulus ) );
733 SymCryptIntFromModulus( pkRsakey->pmModulus ),
734 pkRsakey->pmModulus,
735 pkRsakey->nBitsOfModulus, // Average number of operations
737 pbFnScratch,
738 cbFnScratch );
739
740 if ( SymCryptIntBitsizeOfValue( piPhi ) != pkRsakey->nBitsOfModulus)
741 {
742 scError = SYMCRYPT_EXTERNAL_FAILURE; // This should never happen (make it assert)
743 goto cleanup;
744 }
745
746 // Calculate the rest of the fields
747 scError = SymCryptRsakeyCalculatePrivateFields( pkRsakey, pdTmp, piPhi, piAcc, pbFnScratch, cbFnScratch, 0 );
748 if ( scError != SYMCRYPT_NO_ERROR )
749 {
750 goto cleanup;
751 }
752
753 pkRsakey->hasPrivateKey = TRUE;
754
755 pkRsakey->fAlgorithmInfo = flags; // We want to track all of the flags in the Rsakey
756
757 if ( ( flags & SYMCRYPT_FLAG_KEY_NO_FIPS ) == 0 )
758 {
759 // Ensure RSA algorithm selftest is run before first use of RSA algorithm
760 // Per FIPS 140-3 IG, this selftest cannot be a PCT
764
765 // Run SignVerify PCT on generated keypair
766 // Our current understanding is that this PCT is sufficient for both RSA_SIGN and RSA_ENCRYPT
767
768 // Unconditionally set the sign flag to enable SignVerify PCT on encrypt-only keypair
769 pkRsakey->fAlgorithmInfo |= SYMCRYPT_FLAG_RSAKEY_SIGN;
770
773 pkRsakey,
775
776 // Unset the sign flag before returning encrypt-only keypair
777 if ( ( flags & SYMCRYPT_FLAG_RSAKEY_SIGN ) == 0 )
778 {
779 pkRsakey->fAlgorithmInfo ^= SYMCRYPT_FLAG_RSAKEY_SIGN;
780 }
781 }
782
783cleanup:
784 if (pbScratch!=NULL)
785 {
786 SymCryptWipe(pbScratch,cbScratch);
787 SymCryptCallbackFree(pbScratch);
788 }
789
790 return scError;
791}
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsaSignVerifyPct(const SYMCRYPT_RSAKEY *key)
Definition: implglue.c:51
void SYMCRYPT_CALL SymCryptRsaSelftest(void)
Definition: implglue.c:47
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyCalculatePrivateFields(_Inout_ PSYMCRYPT_RSAKEY pkRsakey, _Out_ PSYMCRYPT_DIVISOR pdTmp, _Out_ PSYMCRYPT_INT piPhi, _Out_ PSYMCRYPT_INT piAcc, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch, UINT32 flags)
Definition: rsakey.c:357
#define RSA_DEFAULT_PUBLIC_EXPONENT
Definition: rsakey.c:9
#define SYMCRYPT_RUN_KEY_GEN_PCT(KeySelftestFunction, Key, KeySelftestFlag)
Definition: sc_lib.h:3699
#define SYMCRYPT_RUN_SELFTEST_ONCE(AlgorithmSelftestFunction, AlgorithmSelftestFlag)
Definition: sc_lib.h:3686
#define SYMCRYPT_FLAG_KEY_NO_FIPS
Definition: symcrypt.h:7579
#define SYMCRYPT_RSAKEY_FIPS_MIN_BITSIZE_MODULUS
@ SYMCRYPT_SELFTEST_ALGORITHM_RSA
UINT32 nPubExp
SYMCRYPT_DIVISOR * PSYMCRYPT_DIVISOR
#define SYMCRYPT_PCT_RSA_SIGN
UINT32 SYMCRYPT_CALL SymCryptSizeofDivisorFromDigits(UINT32 nDigits)
Definition: a_dispatch.c:512
VOID SYMCRYPT_CALL SymCryptIntCopy(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:161
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptIntGenerateRandomPrime(_In_ PCSYMCRYPT_INT piLow, _In_ PCSYMCRYPT_INT piHigh, _In_reads_opt_(nPubExp) PCUINT64 pu64PubExp, UINT32 nPubExp, UINT32 nTries, UINT32 flags, _Inout_ PSYMCRYPT_INT piDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: primes.c:170
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_PRIME_GEN(_nDigits)
VOID SYMCRYPT_CALL SymCryptIntMulPow2(_In_ PCSYMCRYPT_INT piSrc, SIZE_T exp, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:354
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_TO_DIVISOR(_nDigits)
#define SYMCRYPT_SCRATCH_BYTES_FOR_CRT_GENERATION(_nDigits)
PSYMCRYPT_DIVISOR SYMCRYPT_CALL SymCryptDivisorCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, UINT32 nDigits)
Definition: a_dispatch.c:519
#define SYMCRYPT_FLAG_DATA_PUBLIC

Referenced by new_key_impl().

◆ SymCryptRsakeyGetCrtValue()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyGetCrtValue ( _In_ PCSYMCRYPT_RSAKEY  pkRsakey,
_Out_writes_opt_(nCrtExponents) PBYTE *  ppCrtExponents,
_In_reads_(nCrtExponents) SIZE_T *  pcbCrtExponents,
UINT32  nCrtExponents,
_Out_writes_bytes_opt_(cbCrtCoefficient) PBYTE  pbCrtCoefficient,
SIZE_T  cbCrtCoefficient,
_Out_writes_bytes_opt_(cbPrivateExponent) PBYTE  pbPrivateExponent,
SIZE_T  cbPrivateExponent,
SYMCRYPT_NUMBER_FORMAT  numFormat,
UINT32  flags 
)

Definition at line 1518 of file rsakey.c.

1529{
1530 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
1531 PBYTE pbScratch = NULL;
1532 SIZE_T cbScratch = 0;
1533
1535
1536 // Check if the arguments are correct
1537 if ( (ppCrtExponents==NULL) && (nCrtExponents!=0) ||
1538 (nCrtExponents != 0 && nCrtExponents != 2 ))
1539 {
1540 scError = SYMCRYPT_INVALID_ARGUMENT;
1541 goto cleanup;
1542 }
1543
1544 // Crt value can only be available we have private key.
1545 if (pkRsakey->hasPrivateKey == FALSE)
1546 {
1547 scError = SYMCRYPT_INVALID_ARGUMENT;
1548 goto cleanup;
1549 }
1550
1551 // Crt exponents
1552 for (UINT32 i=0; i<nCrtExponents; i++)
1553 {
1554 if (ppCrtExponents[i]!=NULL)
1555 {
1556 scError = SymCryptIntGetValue( pkRsakey->piCrtPrivExps[i], ppCrtExponents[i], pcbCrtExponents[i], numFormat );
1557 if (scError != SYMCRYPT_NO_ERROR )
1558 {
1559 goto cleanup;
1560 }
1561 }
1562 }
1563
1564 if (pbCrtCoefficient!=NULL)
1565 {
1566 cbScratch = SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( pkRsakey->nDigitsOfModulus );
1567 pbScratch = SymCryptCallbackAlloc( cbScratch );
1568
1569 if (pbScratch==NULL)
1570 {
1571 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
1572 goto cleanup;
1573 }
1574
1576 pkRsakey->pmPrimes[0],
1577 pkRsakey->peCrtInverses[0],
1578 pbCrtCoefficient,
1579 cbCrtCoefficient,
1580 numFormat,
1581 pbScratch,
1582 cbScratch);
1583 if (scError != SYMCRYPT_NO_ERROR )
1584 {
1585 goto cleanup;
1586 }
1587 }
1588
1589 if (pbPrivateExponent!=NULL)
1590 {
1591 scError = SymCryptIntGetValue( pkRsakey->piPrivExps[0], pbPrivateExponent, cbPrivateExponent, numFormat );
1592 if (scError != SYMCRYPT_NO_ERROR )
1593 {
1594 goto cleanup;
1595 }
1596 }
1597
1598cleanup:
1599
1600 if (pbScratch!=NULL)
1601 {
1602 SymCryptWipe(pbScratch,cbScratch);
1603 SymCryptCallbackFree(pbScratch);
1604 }
1605
1606 return scError;
1607}
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptModElementGetValue(PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_writes_bytes_(cbDst) PBYTE pbDst, SIZE_T cbDst, SYMCRYPT_NUMBER_FORMAT format, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:804
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptIntGetValue(_In_ PCSYMCRYPT_INT piSrc, _Out_writes_bytes_(cbDst) PBYTE pbDst, SIZE_T cbDst, SYMCRYPT_NUMBER_FORMAT format)
Definition: a_dispatch.c:259

Referenced by export_private_key_impl().

◆ SymCryptRsakeyGetNumberOfPrimes()

UINT32 SYMCRYPT_CALL SymCryptRsakeyGetNumberOfPrimes ( _In_ PCSYMCRYPT_RSAKEY  pkRsakey)

Definition at line 305 of file rsakey.c.

306{
307 return pkRsakey->nPrimes;
308}

◆ SymCryptRsakeyGetNumberOfPublicExponents()

UINT32 SYMCRYPT_CALL SymCryptRsakeyGetNumberOfPublicExponents ( _In_ PCSYMCRYPT_RSAKEY  pkRsakey)

Definition at line 298 of file rsakey.c.

299{
300 return pkRsakey->nPubExp;
301}

◆ SymCryptRsakeyGetValue()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyGetValue ( _In_ PCSYMCRYPT_RSAKEY  pkRsakey,
_Out_writes_bytes_(cbModulus) PBYTE  pbModulus,
SIZE_T  cbModulus,
_Out_writes_opt_(nPubExp) PUINT64  pu64PubExp,
UINT32  nPubExp,
_Out_writes_opt_(nPrimes) PBYTE *  ppPrimes,
_In_reads_opt_(nPrimes) SIZE_T *  pcbPrimes,
UINT32  nPrimes,
SYMCRYPT_NUMBER_FORMAT  numFormat,
UINT32  flags 
)

Definition at line 1445 of file rsakey.c.

1456{
1457 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
1458
1460
1461 // Check if private key needed but not there
1462 if ((nPrimes!=0) && (pkRsakey->hasPrivateKey == FALSE))
1463 {
1464 scError = SYMCRYPT_INVALID_ARGUMENT;
1465 goto cleanup;
1466 }
1467
1468 // Modulus
1469 if (pbModulus!=NULL)
1470 {
1471 // We'll get an error if cbModulus is 0 or too small
1472 scError = SymCryptIntGetValue( SymCryptIntFromModulus( pkRsakey->pmModulus ), pbModulus, cbModulus, numFormat );
1473 if (scError != SYMCRYPT_NO_ERROR )
1474 {
1475 goto cleanup;
1476 }
1477 }
1478
1479 // Public exponents
1480 if( pu64PubExp != NULL )
1481 {
1482 if( nPubExp != 1 )
1483 {
1484 scError = SYMCRYPT_INVALID_ARGUMENT;
1485 goto cleanup;
1486 }
1487 pu64PubExp[0] = pkRsakey->au64PubExp[0];
1488 }
1489
1490 // Primes i.e. private key
1491 if( nPrimes != 0 )
1492 {
1493 if( nPrimes != 2 || ppPrimes == NULL || pcbPrimes == NULL )
1494 {
1495 scError = SYMCRYPT_INVALID_ARGUMENT;
1496 goto cleanup;
1497 }
1498
1499 for (UINT32 i=0; i<nPrimes; i++)
1500 {
1501 if (ppPrimes[i]!=NULL)
1502 {
1503 scError = SymCryptIntGetValue( SymCryptIntFromModulus( pkRsakey->pmPrimes[i] ), ppPrimes[i], pcbPrimes[i], numFormat );
1504 if (scError != SYMCRYPT_NO_ERROR )
1505 {
1506 goto cleanup;
1507 }
1508 }
1509 }
1510 }
1511
1512cleanup:
1513 return scError;
1514}
UINT32 nPrimes

Referenced by export_private_key_impl(), and export_public_key_impl().

◆ SymCryptRsakeyHasPrivateKey()

BOOLEAN SYMCRYPT_CALL SymCryptRsakeyHasPrivateKey ( _In_ PCSYMCRYPT_RSAKEY  pkRsakey)

Definition at line 257 of file rsakey.c.

258{
259 return pkRsakey->hasPrivateKey;
260}

Referenced by duplicate_key_impl().

◆ SymCryptRsakeyModulusBits()

UINT32 SYMCRYPT_CALL SymCryptRsakeyModulusBits ( _In_ PCSYMCRYPT_RSAKEY  pkRsakey)

Definition at line 271 of file rsakey.c.

272{
273 return pkRsakey->nBitsOfModulus;
274}

◆ SymCryptRsakeySetValue()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeySetValue ( _In_reads_bytes_(cbModulus) PCBYTE  pbModulus,
SIZE_T  cbModulus,
_In_reads_(nPubExp) PCUINT64  pu64PubExp,
UINT32  nPubExp,
_In_reads_opt_(nPrimes) PCBYTE *  ppPrimes,
_In_reads_opt_(nPrimes) SIZE_T *  pcbPrimes,
UINT32  nPrimes,
SYMCRYPT_NUMBER_FORMAT  numFormat,
UINT32  flags,
_Inout_ PSYMCRYPT_RSAKEY  pkRsakey 
)

Definition at line 1399 of file rsakey.c.

1410{
1412 pbModulus, cbModulus,
1413 pu64PubExp, nPubExp,
1414 NULL, 0,
1415 ppPrimes, pcbPrimes, nPrimes,
1416 numFormat,
1417 flags,
1418 pkRsakey );
1419}
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeySetValueInternal(_In_reads_bytes_(cbModulus) PCBYTE pbModulus, SIZE_T cbModulus, _In_reads_(nPubExp) PCUINT64 pu64PubExp, UINT32 nPubExp, _In_reads_bytes_opt_(cbPrivateExponent) PCBYTE pbPrivateExponent, SIZE_T cbPrivateExponent, _In_reads_opt_(nPrimes) PCBYTE *ppPrimes, _In_reads_opt_(nPrimes) SIZE_T *pcbPrimes, UINT32 nPrimes, SYMCRYPT_NUMBER_FORMAT numFormat, UINT32 flags, _Inout_ PSYMCRYPT_RSAKEY pkRsakey)
Definition: rsakey.c:1115

Referenced by import_private_key_impl(), and import_public_key_impl().

◆ SymCryptRsakeySetValueFromPrivateExponent()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeySetValueFromPrivateExponent ( _In_reads_bytes_(cbModulus) PCBYTE  pbModulus,
SIZE_T  cbModulus,
UINT64  u64PubExp,
_In_reads_bytes_(cbPrivateExponent) PCBYTE  pbPrivateExponent,
SIZE_T  cbPrivateExponent,
SYMCRYPT_NUMBER_FORMAT  numFormat,
UINT32  flags,
_Inout_ PSYMCRYPT_RSAKEY  pkRsakey 
)

Definition at line 1423 of file rsakey.c.

1432{
1434 pbModulus, cbModulus,
1435 &u64PubExp, 1,
1436 pbPrivateExponent, cbPrivateExponent,
1437 NULL, NULL, 0,
1438 numFormat,
1439 flags,
1440 pkRsakey );
1441}

◆ SymCryptRsakeySetValueInternal()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeySetValueInternal ( _In_reads_bytes_(cbModulus) PCBYTE  pbModulus,
SIZE_T  cbModulus,
_In_reads_(nPubExp) PCUINT64  pu64PubExp,
UINT32  nPubExp,
_In_reads_bytes_opt_(cbPrivateExponent) PCBYTE  pbPrivateExponent,
SIZE_T  cbPrivateExponent,
_In_reads_opt_(nPrimes) PCBYTE *  ppPrimes,
_In_reads_opt_(nPrimes) SIZE_T *  pcbPrimes,
UINT32  nPrimes,
SYMCRYPT_NUMBER_FORMAT  numFormat,
UINT32  flags,
_Inout_ PSYMCRYPT_RSAKEY  pkRsakey 
)

Definition at line 1115 of file rsakey.c.

1128{
1129 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
1130
1131 // 3 digit sizes of temporary integers:
1132 // - ndPrimes = max digitsize of prime buffers
1133 // - ndMod = pkRsakey->nDigitsOfModulus
1134 // - ndLarge = ndPrimes + ndMod
1135
1136 UINT32 cbDivisor = 0;
1137 PSYMCRYPT_DIVISOR pdTmp = NULL;
1138
1139 UINT32 ndMod = 0;
1140 UINT32 cbMod = 0;
1141 PSYMCRYPT_INT piPhi = NULL;
1142
1143 UINT32 cbLarge = 0;
1144 PSYMCRYPT_INT piAcc = NULL;
1145
1146 PBYTE pbScratch = NULL;
1147 UINT32 cbScratch = 0;
1148 PBYTE pbFnScratch = NULL;
1149 UINT32 cbFnScratch = 0;
1150
1151 // Ensure caller has specified what algorithm(s) the key will be used with
1153 // Ensure only allowed flags are specified
1155
1156 if ( ( ( flags & ~allowedFlags ) != 0 ) ||
1157 ( ( flags & algorithmFlags ) == 0) )
1158 {
1159 scError = SYMCRYPT_INVALID_ARGUMENT;
1160 goto cleanup;
1161 }
1162
1163 // Check that minimal validation flag only specified with no fips
1164 if ( ( ( flags & SYMCRYPT_FLAG_KEY_NO_FIPS ) == 0 ) &&
1166 {
1167 scError = SYMCRYPT_INVALID_ARGUMENT;
1168 goto cleanup;
1169 }
1170
1171 // Internal requirement that private key is either specified by primes or by private exponent, not both
1172 // This is not exposed to external API surface - if we were to dynamically check, the SYMCRYPT_ERROR
1173 // should indicate internal logic error - for now just assert
1174 SYMCRYPT_ASSERT( (nPrimes==0) || (pbPrivateExponent==NULL) );
1175
1176 // Check if the arguments are correct
1177 if ( (pbModulus==NULL) || (cbModulus==0) || // Modulus is needed
1178 (nPubExp != 1) || (pu64PubExp==NULL) || // Exactly 1 public exponent is needed
1179 ((nPrimes != 2) && (nPrimes != 0)) ||
1180 ((nPrimes == 2) && ((ppPrimes==NULL) || (pcbPrimes==NULL) ||
1181 (ppPrimes[0]==NULL) || (ppPrimes[1]==NULL) ||
1182 (pcbPrimes[0]==0) || (pcbPrimes[1]==0))) )
1183 {
1184 scError = SYMCRYPT_INVALID_ARGUMENT;
1185 goto cleanup;
1186 }
1187
1188 ndMod = pkRsakey->nDigitsOfModulus;
1189
1190 // Calculate scratch spaces
1191 // No integer overflows as all numbers are limited by ndMod which is checked during Create
1192 if ( (pbPrivateExponent != NULL) || (nPrimes > 0) )
1193 {
1194 if( pkRsakey->nPrimes != 2 )
1195 {
1196 // The key was not allocated with space for private key material
1197 // so we cannot set it with private key material
1198 scError = SYMCRYPT_INVALID_ARGUMENT;
1199 goto cleanup;
1200 }
1201
1202 cbMod = SymCryptSizeofIntFromDigits( ndMod );
1203 cbLarge = SymCryptSizeofIntFromDigits( 2 * ndMod ); // 2*ndMod is still < SymCryptDigitsFromBits(SYMCRYPT_INT_MAX_BITS)
1204 cbDivisor = SymCryptSizeofDivisorFromDigits( ndMod );
1205
1206 cbScratch = cbMod + cbLarge + cbDivisor +
1212 ))));
1213
1214 if( pbPrivateExponent != NULL )
1215 {
1216 // We use at least as much scratch space when importing by private exponent, but probably more
1218
1220 SYMCRYPT_SCRATCH_BYTES_FOR_PRIME_RECOVERY(ndMod, 1, pkRsakey->nSetBitsOfModulus) );
1221 }
1222 }
1223 else
1224 {
1226 }
1227
1228 pbScratch = (PBYTE)SymCryptCallbackAlloc( cbScratch );
1229 if (pbScratch == NULL)
1230 {
1231 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
1232 goto cleanup;
1233 }
1234
1235 // Modulus
1236 scError = SymCryptIntSetValue( pbModulus, cbModulus, numFormat, SymCryptIntFromModulus( pkRsakey->pmModulus ) );
1237 if (scError != SYMCRYPT_NO_ERROR)
1238 {
1239 goto cleanup;
1240 }
1241
1242 // Compute actual modulus size, and check that it isn't bigger than the created size
1243 pkRsakey->nBitsOfModulus = SymCryptIntBitsizeOfValue(SymCryptIntFromModulus(pkRsakey->pmModulus));
1244 if (pkRsakey->nBitsOfModulus > pkRsakey->nSetBitsOfModulus)
1245 {
1246 scError = SYMCRYPT_INVALID_ARGUMENT;
1247 goto cleanup;
1248 }
1249
1250 if (pkRsakey->nBitsOfModulus < SYMCRYPT_RSAKEY_MIN_BITSIZE_MODULUS)
1251 {
1252 scError = SYMCRYPT_WRONG_KEY_SIZE;
1253 goto cleanup;
1254 }
1255
1256 // IntToModulus requirement:
1257 // nBitsOfModulus >= SYMCRYPT_RSAKEY_MIN_BITSIZE_MODULUS --> pmModulus > 0
1259 SymCryptIntFromModulus( pkRsakey->pmModulus ),
1260 pkRsakey->pmModulus,
1261 pkRsakey->nBitsOfModulus,
1263 pbScratch,
1264 cbScratch );
1265
1266 // Public exponents
1267 pkRsakey->nPubExp = nPubExp;
1268 for (UINT32 i = 0; i<pkRsakey->nPubExp; i++)
1269 {
1270 pkRsakey->au64PubExp[i] = pu64PubExp[i];
1271 }
1272
1273 // Private key import either by private exponent or primes
1274 if ( (pbPrivateExponent != NULL) || (nPrimes > 0) )
1275 {
1276 if (pbPrivateExponent != NULL)
1277 {
1278 // Private exponent
1280 pkRsakey,
1281 pbPrivateExponent, cbPrivateExponent,
1282 numFormat,
1283 pbScratch, cbScratch );
1284 if (scError != SYMCRYPT_NO_ERROR)
1285 {
1286 goto cleanup;
1287 }
1288
1289 pbFnScratch = pbScratch;
1290 cbFnScratch = cbScratch;
1291
1292 // Create temporary piPhi
1293 piPhi = SymCryptIntCreate( pbFnScratch, cbMod, ndMod ); pbFnScratch += cbMod; cbFnScratch -= cbMod;
1294 }
1295 else //if (nPrimes > 0)
1296 {
1297 // Primes
1298 pbFnScratch = pbScratch;
1299 cbFnScratch = cbScratch;
1300
1301 // Create temporary piPhi
1302 piPhi = SymCryptIntCreate( pbFnScratch, cbMod, ndMod ); pbFnScratch += cbMod; cbFnScratch -= cbMod;
1303
1304 // First fix the tight number of digits of each prime
1305 pkRsakey->nMaxDigitsOfPrimes = 0;
1306 for (UINT32 i=0; i<pkRsakey->nPrimes; i++)
1307 {
1308#pragma warning(suppress: 26007) // "Incorrect Annotation" - cannot phrase array of pointers to arrays in SAL
1309 scError = SymCryptIntSetValue( ppPrimes[i], pcbPrimes[i], numFormat, piPhi );
1310 if (scError != SYMCRYPT_NO_ERROR )
1311 {
1312 goto cleanup;
1313 }
1314
1315 pkRsakey->nBitsOfPrimes[i] = SymCryptIntBitsizeOfValue(piPhi);
1316 pkRsakey->nDigitsOfPrimes[i] = SymCryptDigitsFromBits(pkRsakey->nBitsOfPrimes[i]);
1317
1318 pkRsakey->nMaxDigitsOfPrimes = SYMCRYPT_MAX(pkRsakey->nMaxDigitsOfPrimes, pkRsakey->nDigitsOfPrimes[i]);
1319
1320 if (pkRsakey->nBitsOfPrimes[i] < SYMCRYPT_RSAKEY_MIN_BITSIZE_PRIME)
1321 {
1322 scError = SYMCRYPT_WRONG_KEY_SIZE;
1323 goto cleanup;
1324 }
1325 }
1326
1327 // Create all the objects
1329
1330 // Set the values
1331 for (UINT32 i=0; i<pkRsakey->nPrimes; i++)
1332 {
1333#pragma warning(suppress: 26007) // "Incorrect Annotation" - cannot phrase array of pointers to arrays in SAL
1334 scError = SymCryptIntSetValue( ppPrimes[i], pcbPrimes[i], numFormat, SymCryptIntFromModulus( pkRsakey->pmPrimes[i] ) );
1335 if (scError != SYMCRYPT_NO_ERROR )
1336 {
1337 goto cleanup;
1338 }
1339
1340 // Check that this prime is odd (should we check for primality?)
1341 if ((SymCryptIntGetValueLsbits32(SymCryptIntFromModulus( pkRsakey->pmPrimes[i] ))& 1)==0)
1342 {
1343 scError = SYMCRYPT_INVALID_ARGUMENT;
1344 goto cleanup;
1345 }
1346
1347 // IntToModulus requirement:
1348 // nBitsOfPrimes >= SYMCRYPT_RSAKEY_MIN_BITSIZE_PRIME --> pmPrimes[i] > 0
1350 SymCryptIntFromModulus( pkRsakey->pmPrimes[i] ),
1351 pkRsakey->pmPrimes[i],
1352 pkRsakey->nBitsOfModulus, // Average number of operations
1354 pbFnScratch,
1355 cbFnScratch );
1356 }
1357 }
1358
1359 // Create remaining temporaries
1360 piAcc = SymCryptIntCreate( pbFnScratch, cbLarge, 2 * ndMod ); pbFnScratch += cbLarge; cbFnScratch -= cbLarge;
1361 pdTmp = SymCryptDivisorCreate( pbFnScratch, cbDivisor, ndMod ); pbFnScratch += cbDivisor; cbFnScratch -= cbDivisor;
1362
1363 // Calculate the rest of the fields
1364 scError = SymCryptRsakeyCalculatePrivateFields( pkRsakey, pdTmp, piPhi, piAcc, pbFnScratch, cbFnScratch, flags & SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION );
1365 if (scError != SYMCRYPT_NO_ERROR )
1366 {
1367 goto cleanup;
1368 }
1369
1370 // Everything is set here
1371 pkRsakey->hasPrivateKey = TRUE;
1372 }
1373
1374 pkRsakey->fAlgorithmInfo = flags; // We want to track all of the flags in the Rsakey
1375
1376 if ( ( flags & SYMCRYPT_FLAG_KEY_NO_FIPS ) == 0 )
1377 {
1378 // Ensure RSA algorithm selftest is run before first use of RSA algorithm
1382
1383 // PCT does not need to be run on import - mark it as done
1384 pkRsakey->fAlgorithmInfo |= SYMCRYPT_PCT_RSA_SIGN;
1385 }
1386
1387cleanup:
1388 if (pbScratch!=NULL)
1389 {
1390 SymCryptWipe(pbScratch,cbScratch);
1391 SymCryptCallbackFree(pbScratch);
1392 }
1393
1394 return scError;
1395}
static SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsakeyCalculatePrimesFromPrivateExponent(_Inout_ PSYMCRYPT_RSAKEY pkRsakey, _In_reads_bytes_(cbPrivateExponent) PCBYTE pbPrivateExponent, SIZE_T cbPrivateExponent, SYMCRYPT_NUMBER_FORMAT numFormat, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, UINT32 cbScratch)
Definition: rsakey.c:815

Referenced by SymCryptRsakeySetValue(), and SymCryptRsakeySetValueFromPrivateExponent().

◆ SymCryptRsakeySizeofModulus()

◆ SymCryptRsakeySizeofPrime()

UINT32 SYMCRYPT_CALL SymCryptRsakeySizeofPrime ( _In_ PCSYMCRYPT_RSAKEY  pkRsakey,
UINT32  index 
)

Definition at line 289 of file rsakey.c.

292{
293 return (pkRsakey->nBitsOfPrimes[index] + 7)/8;
294}
GLuint index
Definition: glext.h:6031

Referenced by export_private_key_impl().

◆ SymCryptRsakeySizeofPublicExponent()

UINT32 SYMCRYPT_CALL SymCryptRsakeySizeofPublicExponent ( _In_ PCSYMCRYPT_RSAKEY  pRsakey,
UINT32  index 
)

Definition at line 278 of file rsakey.c.

281{
282 SYMCRYPT_ASSERT( index == 0 );
284 return SymCryptUint64Bytesize( pRsakey->au64PubExp[0] );
285}
UINT32 SymCryptUint64Bytesize(UINT64 value)
Definition: libmain.c:321

◆ SymCryptRsakeyWipe()

VOID SYMCRYPT_CALL SymCryptRsakeyWipe ( _Out_ PSYMCRYPT_RSAKEY  pkDst)

Definition at line 189 of file rsakey.c.

190{
191 // Wipe the whole structure in one go.
192 SymCryptWipe( pkDst, pkDst->cbTotalSize );
193}

Referenced by SymCryptRsakeyFree().

◆ SymCryptSizeofRsakeyFromParams()

UINT32 SYMCRYPT_CALL SymCryptSizeofRsakeyFromParams ( _In_ PCSYMCRYPT_RSA_PARAMS  pParams)

Definition at line 51 of file rsakey.c.

52{
53 UINT32 nModulusDigits;
54 UINT32 res;
55
56 SYMCRYPT_ASSERT( pParams != NULL );
57
58 nModulusDigits = SymCryptDigitsFromBits( pParams->nBitsOfModulus );
59
60 //
61 // From symcrypt_internal.h we have:
62 // - sizeof results are upper bounded by 2^19
63 // - SYMCRYPT_SCRATCH_BYTES results are upper bounded by 2^27 (including RSA and ECURVE)
64 // - nPrimes and nPubExps are bounded by SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES = 2 and
65 // SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS = 1
66 // Thus the following calculation does not overflow the result.
67 //
68 res = sizeof(SYMCRYPT_RSAKEY) +
69 SymCryptSizeofModulusFromDigits( nModulusDigits ) + // For Modulus
70 pParams->nPrimes * SymCryptSizeofModulusFromDigits( nModulusDigits ) + // For Primes
71 pParams->nPrimes * SYMCRYPT_SIZEOF_MODELEMENT_FROM_BITS( pParams->nBitsOfModulus ) + // For CrtInverses
72 pParams->nPubExp * SymCryptSizeofIntFromDigits( nModulusDigits ) + // For PrivExps
73 pParams->nPubExp * pParams->nPrimes * SymCryptSizeofIntFromDigits( nModulusDigits ); // For CrtPrivExps
74
75 // Consistency check with the static macro (optimized away in production)
76 SYMCRYPT_ASSERT( res <= SYMCRYPT_SIZEOF_RSAKEY_FROM_PARAMS( pParams->nBitsOfModulus, pParams->nPrimes, pParams->nPubExp ) );
77
78 return res;
79}
#define SYMCRYPT_SIZEOF_RSAKEY_FROM_PARAMS(modBits, nPrimes, nPubExps)
Definition: symcrypt.h:7292

Referenced by SymCryptRsakeyAllocate(), and SymCryptRsakeyCreate().