]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/lib/ckutilities.c
   1 /* Copyright (c) 1998,2011-2012,2014 Apple Inc.  All Rights Reserved. 
   3  * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT 
   4  * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE 
   5  * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE 
   6  * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, 
   7  * INC.  ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL 
   8  * EXPOSE YOU TO LIABILITY. 
   9  *************************************************************************** 
  11  * ckutilities.c - general C routines 
  16  *      Changed to compile with C++. 
  18  *      Mods for variable size giantDigit. 
  19  *      Rewrote serializeGiant(), deserializeGiant() to conform to IEEE P1363. 
  21  *      Added FR_WrongSignatureType, FR_BadKeyBlob to frtnStrings. 
  22  *      Added initCryptKit(). 
  26  *      Added non-FEE_DEBUG version of printGiantHex() 
  28  *      Addd serializeGiant(), deserializeGiant; Deleted data_to_giant() 
  30  *      Added byteRepTo{int,key,giant}(). 
  32  *      Broke out from Blaine Garst's original NSCryptors.m 
  35 #include "ckutilities.h" 
  39 #include "feeFunctions.h" 
  42 #include "curveParams.h" 
  56         const char      *frtnString
; 
  59 static const frtnItem frtnStrings
[] = { 
  61         { FR_Success
,                           "Success"                                       }, 
  62         { FR_BadPubKey
,                         "Bad Public Key"                        }, 
  63         { FR_BadPubKeyString
,           "Bad Public Key String"         }, 
  64         { FR_IncompatibleKey
,           "Incompatible key format"       }, 
  65         { FR_IllegalDepth
,                      "Illegal Depth"                         }, 
  66         { FR_BadUsageName
,                      "Bad Usage Name"                        }, 
  67         { FR_BadSignatureFormat
,        "Bad Signature Format"          }, 
  68         { FR_InvalidSignature
,          "Invalid Signature"                     }, 
  69         { FR_IllegalArg
,                        "Illegal Argument"                      }, 
  70         { FR_BadCipherText
,                     "Bad Ciphertext Format"         }, 
  71         { FR_Unimplemented
,                     "Unimplemented Function"        }, 
  72         { FR_BadCipherFile
,                     "Bad CipherFile Format"         }, 
  73         { FR_BadEnc64
,                          "Bad enc64 Format"                      }, 
  74         { FR_WrongSignatureType
,        "Wrong Signature Type"          }, 
  75         { FR_BadKeyBlob
,                        "Bad Key Blob"                          }, 
  76         { FR_IllegalCurve
,                      "Bad curve type"                        }, 
  77         { FR_Internal
,                          "Internal Library Error"        }, 
  78         { FR_Memory
,                            "Out of Memory"                         }, 
  79         { FR_ShortPrivData
,                     "Insufficient Seed Data"        }, 
  81         { (feeReturn
) 0,                        NULL                                            
}, 
  85  * One-time only init of CryptKit library. 
  87 void initCryptKit(void) 
  94 void terminateCryptKit(void) 
  99  * Create a giant, initialized with specified char[] data. 
 101 giant 
giant_with_data(const unsigned char *d
, int len
) { 
 102     int numDigits 
= BYTES_TO_GIANT_DIGITS(len
); 
 105     result 
= newGiant(numDigits
); 
 106     deserializeGiant(d
, result
, len
); 
 111  * Obtain a malloc'd memory chunk init'd with specified giant's data. 
 112  * Resulting bytes are portable. Size of malloc'd memory is always zero 
 113  * mod GIANT_BYTES_PER_DIGIT. 
 115  * Calling this function for a giant obtained by giant_with_data() yields 
 116  * the original data, with extra byte(s) of leading zeros if the original 
 117  * was not zero mod GIANT_BYTES_PER_DIGIT. 
 119 unsigned char *mem_from_giant(giant g
, 
 120         unsigned *memLen
)               /* RETURNED size of malloc'd region */ 
 123         unsigned numDigits 
= (g
->sign 
< 0) ? -g
->sign 
: g
->sign
; 
 125         *memLen 
= numDigits 
* GIANT_BYTES_PER_DIGIT
; 
 126         cp 
= (unsigned char*) fmalloc(*memLen
); 
 127         serializeGiant(g
, cp
, *memLen
); 
 131 extern const char *feeReturnString(feeReturn frtn
) 
 133         const frtnItem 
*fi 
= frtnStrings
; 
 135         while(fi
->frtnString
) { 
 136                 if(fi
->frtn 
== frtn
) { 
 137                         return fi
->frtnString
; 
 141         return "Unknown Status"; 
 145 void printGiant(const giant x
) 
 149         printf("sign=%d cap=%d n[]=", x
->sign
, x
->capacity
); 
 150         for(i
=0; i
<abs(x
->sign
); i
++) { 
 151                 printf("%lu:", (unsigned long)x
->n
[i
]); 
 156 void printGiantHex(const giant x
) 
 160         printf("sign=%d cap=%d n[]=", x
->sign
, x
->capacity
); 
 161         for(i
=0; i
<abs(x
->sign
); i
++) { 
 162                 printf("%lx:", (unsigned long)x
->n
[i
]); 
 169  *   sign=8 cap=16 n[]=29787 + 3452 * w^1 + 55260 * w^2  + ... 
 171 void printGiantExp(const giant x
) 
 174         int size 
= abs(x
->sign
); 
 176         printf("sign=%d cap=%d n[]=", x
->sign
, x
->capacity
); 
 177         for(i
=0; i
<size
; i
++) { 
 178                 printf("%lu ", (unsigned long)x
->n
[i
]); 
 180                         printf("* w^%d ", i
); 
 189 void printKey(const key k
) 
 191         printf("  twist %d\n", k
->twist
); 
 196 void printCurveParams(const curveParams 
*p
) 
 201         switch(p
->primeType
) { 
 215         switch(p
->curveType
) { 
 217                         ct 
= "FCT_Montgomery"; 
 219                 case FCT_Weierstrass
: 
 220                         ct 
= "FCT_Weierstrass"; 
 229         printf("  q %d   k %d   primeType %s  curveType %s\n", 
 231         printf("  minBytes %d  maxDigits %d\n", p
->minBytes
, p
->maxDigits
); 
 238         printf("  basePrime   : "); 
 239         printGiant(p
->basePrime
); 
 240         printf("  x1Plus      : "); 
 241         printGiant(p
->x1Plus
); 
 242         printf("  x1Minus     : "); 
 243         printGiant(p
->x1Minus
); 
 244         printf("  cOrderPlus  : "); 
 245         printGiant(p
->cOrderPlus
); 
 246         printf("  cOrderMinus : "); 
 247         printGiant(p
->cOrderMinus
); 
 248         printf("  x1OrderPlus : "); 
 249         printGiant(p
->x1OrderPlus
); 
 250         printf("  x1OrderMinus: "); 
 251         printGiant(p
->x1OrderMinus
); 
 254 void printGiant(const giant x
) {} 
 255 void printGiantHex(const giant x
) {} 
 256 void printGiantExp(const giant x
) {} 
 257 void printKey(const key k
) {} 
 258 void printCurveParams(const curveParams 
*p
) {} 
 260 #endif  /* FEE_DEBUG */ 
 263  * serialize, deserialize giants's n[] to/from byte stream. 
 264  * First byte of byte stream is the MS byte of the resulting giant, 
 265  * regardless of the size of giantDigit. 
 267  * No assumption is made about the alignment of cp. 
 269  * As of 7 Apr 1998, these routines are in compliance with IEEE P1363, 
 270  * section 5.5.1, for the representation of a large integer as a byte 
 273 void serializeGiant(giant g
, 
 278         unsigned        numDigits 
= BYTES_TO_GIANT_DIGITS(numBytes
); 
 282         int             size 
= abs(g
->sign
); 
 287         if(numBytes 
> (g
->capacity 
* GIANT_BYTES_PER_DIGIT
)) { 
 288                 CKRaise("serializeGiant: CAPACITY EXCEEDED!\n"); 
 292          * note we might be asked to write more than the valid number 
 293          * if bytes in the giant in the case if truncated sign due to 
 294          * zero M.S. digit(s).... 
 298          * zero out unused digits so we can infer sign during deserialize 
 300         for(digitDex
=size
; digitDex
<numDigits
; digitDex
++) { 
 305          * Emit bytes starting from l.s. byte. L.s. byte of the outgoing 
 306          * data stream is *last*. L.s. digit of giant's digits is *first*. 
 309         ptr 
= &cp
[numBytes 
- 1]; 
 311             /* one loop per giant digit */ 
 312             digit 
= g
->n
[digitDex
++]; 
 313             for(digitByte
=0; digitByte
<GIANT_BYTES_PER_DIGIT
; digitByte
++) { 
 314                 /* one loop per byte in the digit */ 
 315                 *ptr
-- = (unsigned char)digit
; 
 316                         if(--numBytes 
== 0) { 
 321         } while(numBytes 
!= 0); 
 326  * Resulting sign here is always positive; leading zeroes are reflected 
 327  * in an altered g->sign. 
 329 void deserializeGiant(const unsigned char *cp
, 
 337         const unsigned char     *ptr
; 
 343         numDigits 
= (numBytes 
+ GIANT_BYTES_PER_DIGIT 
- 1) / 
 344                         GIANT_BYTES_PER_DIGIT
; 
 345         if(numBytes 
> (g
->capacity 
* GIANT_BYTES_PER_DIGIT
)) { 
 346                 CKRaise("deserializeGiant: CAPACITY EXCEEDED!\n"); 
 350          * Start at l.s. byte. That's the end of the cp[] array and 
 351          * the beginning of the giantDigit array. 
 354         ptr 
= &cp
[numBytes 
- 1]; 
 356             /* one loop per digit */ 
 358             for(digitByte
=0; digitByte
<GIANT_BYTES_PER_DIGIT
; digitByte
++) { 
 359                 /* one loop per byte in the digit */ 
 360                 digit 
|= (*ptr
-- << (8 * digitByte
)); 
 361                 /* FIXME - shouldn't we update g->n before this break? */ 
 362                 if(--numBytes 
== 0) { 
 366             g
->n
[digitDex
++] = digit
; 
 367         } while (numBytes 
!= 0); 
 370          * Infer sign from non-zero n[] elements