2  * Copyright (c) 2000-2001,2011-2012,2014 Apple Inc. All Rights Reserved. 
   4  * The contents of this file constitute Original Code as defined in and are 
   5  * subject to the Apple Public Source License Version 1.2 (the 'License'). 
   6  * You may not use this file except in compliance with the License. Please obtain 
   7  * a copy of the License at http://www.apple.com/publicsource and read it before 
  10  * This Original Code and all software distributed under the License are 
  11  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 
  12  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 
  13  * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
  14  * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 
  15  * specific language governing rights and limitations under the License. 
  20  * FEESignatureObject.cpp - implementations of FEE-style raw sign/verify classes 
  24 #ifdef  CRYPTKIT_CSP_ENABLE 
  26 #include "FEESignatureObject.h" 
  27 #include <security_cryptkit/feePublicKey.h> 
  28 #include <security_cryptkit/feeDigitalSignature.h> 
  29 #include <security_cryptkit/falloc.h> 
  32 #include <security_utilities/debugging.h> 
  34 #define feeSigObjDebug(args...)         secinfo("feeSig", ##args) 
  36 CryptKit::FEESigner::~FEESigner() 
  38         if(mWeMallocdFeeKey
) { 
  39                 assert(mFeeKey 
!= NULL
); 
  40                 feePubKeyFree(mFeeKey
); 
  45  * padding from context 
  47 void CryptKit::FEESigner::sigFormatFromContext( 
  48                                          const Context  
&context
) 
  50     CSSM_PADDING padding 
= context
.getInt(CSSM_ATTRIBUTE_PADDING
); 
  52         case CSSM_PADDING_SIGRAW
: 
  60  * obtain key from context, validate, convert to native FEE key 
  62 void CryptKit::FEESigner::keyFromContext( 
  63         const Context   
&context
) 
  65         if(initFlag() && (mFeeKey 
!= NULL
)) { 
  66                 /* reusing context, OK */ 
  70         CSSM_KEYCLASS   keyClass
; 
  73                 /* signing with private key */ 
  74                 keyClass 
= CSSM_KEYCLASS_PRIVATE_KEY
; 
  75                 keyUse   
= CSSM_KEYUSE_SIGN
; 
  78                 /* verifying with public key */ 
  79                 keyClass 
= CSSM_KEYCLASS_PUBLIC_KEY
; 
  80                 keyUse   
= CSSM_KEYUSE_VERIFY
; 
  83                 mFeeKey 
= contextToFeeKey(context
, 
  93 void CryptKit::FEESigner::signerInit( 
  94         const Context   
&context
, 
  97         setIsSigning(isSigning
); 
  98         keyFromContext(context
); 
  99     sigFormatFromContext(context
); 
 104  * Note that, unlike the implementation in security_cryptkit/feePublicKey.c, we ignore 
 105  * the Pm which used to be used as salt for the digest. That made staged verification 
 106  * impossible and I do not believe it increased security.  
 108 void CryptKit::FEERawSigner::sign( 
 112         size_t                  *sigLen
)        /* IN/OUT */ 
 116         unsigned char   *feeSig
; 
 117         unsigned                feeSigLen
=0; 
 119         if(mFeeKey 
== NULL
) { 
 120                 throwCryptKit(FR_BadPubKey
, "FEERawSigner::sign (no key)"); 
 122         fsig 
= feeSigNewWithKey(mFeeKey
, mRandFcn
, mRandRef
); 
 124                 throwCryptKit(FR_BadPubKey
, "FEERawSigner::sign"); 
 126         frtn 
= feeSigSign(fsig
, 
 127                 (unsigned char *)data
, 
 130         if(frtn 
== FR_Success
) { 
 131                 frtn 
= feeSigData(fsig
, &feeSig
, &feeSigLen
); 
 135                 throwCryptKit(frtn
, "FEERawSigner::sign"); 
 138         /* copy out to caller and ffree */ 
 139         if(*sigLen 
< feeSigLen
) { 
 140                 feeSigObjDebug("FEERawSigner sign overflow\n"); 
 142                 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
); 
 144         memmove(sig
, feeSig
, feeSigLen
); 
 149 void CryptKit::FEERawSigner::verify( 
 158         if(mFeeKey 
== NULL
) { 
 159                 throwCryptKit(FR_BadPubKey
, "FEERawSigner::verify (no key)"); 
 161         frtn 
= feeSigParse((unsigned char *)sig
, sigLen
, &fsig
); 
 163                 throwCryptKit(frtn
, "feeSigParse"); 
 165         frtn 
= feeSigVerify(fsig
, 
 166                 (unsigned char *)data
, 
 167                 (unsigned int)dataLen
, 
 171                 throwCryptKit(frtn
, NULL
); 
 175 size_t CryptKit::FEERawSigner::maxSigSize() 
 180         frtn 
= feeSigSize(mFeeKey
, &rtn
); 
 182                 throwCryptKit(frtn
, "feeSigSize"); 
 187 /* ECDSA - this is really easy. */ 
 189 void CryptKit::FEEECDSASigner::sign( 
 193         size_t                  *sigLen
)        /* IN/OUT */ 
 195         unsigned char   *feeSig
; 
 199         if(mFeeKey 
== NULL
) { 
 200                 throwCryptKit(FR_BadPubKey
, "FEERawSigner::sign (no key)"); 
 202         frtn 
= feeECDSASign(mFeeKey
, 
 204                 (unsigned char *)data
,   // data to be signed 
 205                 (unsigned int)dataLen
,                          // in bytes 
 211                 throwCryptKit(frtn
, "feeECDSASign"); 
 213         /* copy out to caller and ffree */ 
 214         if(*sigLen 
< feeSigLen
) { 
 215                 feeSigObjDebug("feeECDSASign overflow\n"); 
 217                 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
); 
 219         memmove(sig
, feeSig
, feeSigLen
); 
 225 void CryptKit::FEEECDSASigner::verify( 
 233         if(mFeeKey 
== NULL
) { 
 234                 throwCryptKit(FR_BadPubKey
, "FEERawSigner::verify (no key)"); 
 236         frtn 
= feeECDSAVerify( 
 237         (unsigned char *)sig
, 
 239                 (unsigned char *)data
, 
 240                 (unsigned int)dataLen
, 
 244                 throwCryptKit(frtn
, NULL
); 
 248 size_t CryptKit::FEEECDSASigner::maxSigSize() 
 253         frtn 
= feeECDSASigSize(mFeeKey
, &rtn
); 
 255                 throwCryptKit(frtn
, "feeECDSASigSize"); 
 260 #endif  /* CRYPTKIT_CSP_ENABLE */