1 /* 2 * Copyright (c) 2001-2022, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef _CC_RSA_LOCAL_H 8 #define _CC_RSA_LOCAL_H 9 10 #include "cc_error.h" 11 #include "cc_rsa_types.h" 12 #include "cc_rnd_common.h" 13 14 15 #ifdef __cplusplus 16 extern "C" 17 { 18 #endif 19 20 21 /************************ Defines ******************************/ 22 23 /* the RSA public key user validity TAG */ 24 #define CC_RSA_PUB_KEY_VALIDATION_TAG 0x13579BDF 25 26 /* the RSA private key user validity TAG */ 27 #define CC_RSA_PRIV_KEY_VALIDATION_TAG 0x2468ACE0 28 29 /* the RSA sign Context user validity TAG */ 30 #define CC_RSA_SIGN_CONTEXT_VALIDATION_TAG 0x98765432 31 #define CC_RSA_VERIFY_CONTEXT_VALIDATION_TAG 0x45678901 32 33 34 typedef struct { 35 uint16_t hashResultSize; 36 CCHashOperationMode_t hashMode; 37 }RsaHash_t; 38 39 extern const RsaHash_t RsaHashInfo_t[CC_RSA_HASH_NumOfModes]; 40 extern const uint8_t RsaSupportedHashModes_t[CC_RSA_HASH_NumOfModes]; 41 #ifdef USE_MBEDTLS_CRYPTOCELL 42 extern const mbedtls_md_type_t RsaHash_CC_mbedtls_Info[CC_HASH_NumOfModes]; 43 #endif 44 45 /*************** 46 47 ASN1 types - for BER Parser - used for PKCS#1 Ver 1.5 48 49 ***************/ 50 51 #define ASN1_BOOLEAN 1 52 #define ASN1_INTEGER 2 53 #define ASN1_BIT_STRING 3 54 #define ASN1_OCTET_STRING 4 55 #define ASN1_NULL 5 56 #define ASN1_OBJECT_IDENTIFIER 6 57 #define ASN1_SEQUENCE 16 /* 0x10 */ 58 #define ASN1_SET 17 /* 0x11 */ 59 #define ASN1_PRINTABLE_STRING 19 /* 0x13 */ 60 #define ASN1_TELETEX_STRING 20 /* 0x14 */ 61 #define ASN1_IA5STRING 22 /* 0x16 */ 62 #define ASN1_UTC_TIME 23 /* 0x17 */ 63 64 /********************** 65 structures definition 66 **********************/ 67 #define TEST_MSB_BIT 0x80 68 69 /* Hash algorithm ID (DER code) structure type */ 70 #define HASH_DER_CODE_MAX_SIZE_BYTES 24 71 typedef struct HashDerCode_t { 72 uint32_t algIdSizeBytes; 73 CCHashOperationMode_t hashMode; 74 uint8_t algId[HASH_DER_CODE_MAX_SIZE_BYTES]; 75 }HashDerCode_t; 76 77 /* For security goal the padding string PS in EME-PKCS1-v1_5 encodding method 78 must be at least eight octets long */ 79 #define PS_MIN_LEN 8 80 81 82 /************************ macros ********************************/ 83 84 /************************ Typedefs ****************************/ 85 86 87 /************************ Structs ******************************/ 88 typedef struct CCRsaOaepData_t{ 89 uint8_t MaskDB[CC_RSA_OAEP_ENCODE_MAX_MASKDB_SIZE]; 90 uint8_t SeedMask[CC_RSA_OAEP_ENCODE_MAX_SEEDMASK_SIZE]; 91 #ifdef USE_MBEDTLS_CRYPTOCELL 92 mbedtls_md_context_t hash_ctx; 93 #else 94 CCHashUserContext_t HashUsercontext; 95 #endif 96 CCHashResultBuf_t HashResultBuff; 97 }CC_PAL_COMPILER_TYPE_MAY_ALIAS CCRsaOaepData_t; 98 99 /************************ Public Variables **********************/ 100 101 102 /************************ Public Functions **********************/ 103 104 /*********************************************************************************/ 105 /** 106 * @brief The function implements PKCS#1 v1.5 (9.2) EMSA Encoding 107 * algorithm used in Sign/Verify operations. 108 * 109 * @author reuvenl (9/14/2014) 110 * 111 * @param K - The size of encoded message in octets. 112 * @param hashMode - hash mode ID (enum). 113 * @param pM - The Pointer to the Message M. In case of Sign it is a hash (H). 114 * @param MSize - Denotes the Message size: for Sig/Ver = hashSize, 115 * for Enc/Dec <= K-hashAlgIdSize-PSS_MIN_LEN-3. 116 * @param pOut - The pointer to a buffer which is at least K octets long. 117 * @param bIsRawMode - boolean to indicate if the function is used in Raw mode, 118 * which means that structure T to be signed is passed as 119 * input already (no need to perform hashing) 120 * @param DataIn_ptr - Buffer containing the T structure to be signed (possibly 121 * the DER encoding of ASN.1 DigestInfo structure as 122 * specified in RFC8017 sect. 9.2 notes) 123 * @param DataInSize - Size in bytes of the structure T to be signed 124 * which is passed as input for raw signing mode 125 * 126 * @return CCError_t 127 */ 128 CCError_t RsaEmsaPkcs1v15Encode( 129 uint32_t K, 130 CCHashOperationMode_t hashMode, 131 uint8_t *pM, /*mess.digest*/ 132 uint32_t MSize, 133 uint8_t *pOut, 134 bool bIsRawMode, 135 const uint8_t *DataIn_ptr, 136 size_t DataInSize); 137 138 139 140 /**********************************************************************************************************/ 141 142 CCError_t RsaOaepMGF1( uint16_t hLen, /*size in Bytes*/ 143 uint8_t * Z_ptr, 144 uint16_t ZSize,/*size in Bytes*/ 145 uint32_t L, 146 uint8_t *Mask_ptr, 147 CCPkcs1HashFunc_t hashFunc, 148 uint8_t *T_Buf, /*T_Buf is a buffer used for data manipulation for the function to use instead of allocating the space on stack*/ 149 uint8_t *T_TMP_Buf);/*T_TMP_Buf is a buffer used for data manipulation for the function to use instead of allocating the space on stack*/ 150 151 /**********************************************************************************************************/ 152 /** 153 @brief 154 RsaPssOaepEncode implements the the Encoding operation according to the PKCS#1 as defined 155 in PKCS#1 v2.1 7.1.1 (2) and PKCS#1 v2.0 156 */ 157 CCError_t RsaPssOaepEncode(CCRndContext_t *rndContext_ptr, /* random functions context */ 158 CCPkcs1HashFunc_t hashFunc, /* PKCS1 hash mode enum */ 159 CCPkcs1Mgf_t MGF, /* MGF function type enum */ 160 uint8_t *M_ptr, /* a pointer to the message to be encoded */ 161 uint16_t MSize, /* the message size in bytes */ 162 uint8_t *P_ptr, /* a pointer to the label; can be empty string */ 163 size_t PSize, /* the size of the label in bytes */ 164 uint16_t emLen, /* The value is set before the call */ 165 CCRsaPrimeData_t *PrimeData_ptr,/* temp buffer */ 166 uint8_t *EMInput_ptr, /* encoded message output */ 167 CCPkcs1Version_t PKCS1_ver); 168 169 /**********************************************************************************************************/ 170 /** 171 @brief 172 RsaPssOaepDecode implements the the De operation according to the PKCS#1 as defined 173 in PKCS#1 v2.1 7.1.1 (2) and PKCS#1 v2.0 174 */ 175 CCError_t RsaPssOaepDecode(CCPkcs1HashFunc_t hashFunc, 176 CCPkcs1Mgf_t MGF, 177 uint8_t *EM_ptr, 178 uint16_t EMSize, 179 uint8_t *P_ptr, 180 size_t PSize, 181 CCRsaPrimeData_t *PrimeData_ptr, /*Only for stack memory save*/ 182 uint8_t *M_ptr, 183 size_t *MSize_ptr); 184 185 /**********************************************************************************************************/ 186 /** 187 * @brief 188 * This function does implements the functionality of PKCS1 Ver 2.1 Sign 189 * operation after the Hash operation 190 * 191 * Before using that function a Hash must be completed on the Data. 192 * The function is called after the call to Hash_Finish 193 * 194 * @param[in/out] rndContext_ptr - Pointer to the RND context buffer. 195 * @param[in] Context_ptr - Pointer to a valid context as 196 * given from CC_RsaSign 197 * 198 * @param[out] Output_ptr - A buffer allocated for the output which is at least the size of the MOdulus N 199 * 200 * 201 * @return CCError_t - On success CC_OK is returned, on failure a 202 * value MODULE_* as defined in ... 203 */ 204 CCError_t RsaPssSign21(CCRndContext_t *rndContext_ptr, 205 RSAPrivContext_t *Context_ptr, 206 uint8_t *Output_ptr); 207 208 209 /**********************************************************************************************************/ 210 /** 211 Function Name: RsaPssVerify21 212 Date: 06-12-2004 213 Author: Ohad Shperling 214 215 216 \brief RsaPssVerify21 implements EMSA-PSS-Verify algorithm 217 as defined in PKCS#1 v2.1 Sec 9.1.2 218 219 @param[in] Context_ptr - Pointer to a valid context as 220 given from the VerifyFinish function. 221 222 The field HASH_Result inside the Context_ptr is initialized with the Hashed digested message. 223 The field HASH_Result_Size inside the Context_ptr is initialized with the Hash digested message size 224 225 @return CCError_t - CC_OK,or error 226 */ 227 CCError_t RsaPssVerify21(RSAPubContext_t *Context_ptr); 228 229 /**********************************************************************************************************/ 230 /** 231 * @brief The CC_RsaGenerateVectorInRangeX931 function generates a random vector in range: 232 * MinVect < RandVect < MaxVect, where: 233 * MinVect = sqwRoot(2) * 2^(RndSizeInBits-1), MaxVect = 2^RndSizeInBits. 234 * 235 * Note: 1. MSBit of RandVect must be set to 1. 236 * 2. Words order of output vector is set from LS word to MS 237 * word. 238 * 239 * This function is used in PKI RSA for random generation according to ANS X9.31 standard. 240 * If PKI_RSA is not supported, the function does nothing. 241 * 242 * Functions algorithm:: 243 * 244 * 1. Calls the CC_RndGenerateVector() function for generating random vector 245 * RndVect of size RndSizeInWords, rounded up to bytes. Set index i 246 * to high word i = SizeInWords-1. 247 * 2. Check and adust candidate for msWord inside the random vector 248 * starting from msWord himselv, if msWord > high word of MinVect, 249 * goto step 3, else try next word i--; if no words to try, then goto 250 * step 1. 251 * 3. Set the found msWord to high position in array and generate new 252 * random words instead all checked and rejected words. 253 * 254 * @rndContext_ptr[in/out] - Pointer to the RND context buffer. 255 * @rndSizeWords[in] - The size of random vectore that is required. 256 * @rnd_ptr[out] - The output buffer of size not less, than rndSizeWords. 257 * 258 * @return CCError_t - On success CC_OK is returned, on failure a 259 * value MODULE_* as defined in ... 260 */ 261 CCError_t CC_RsaGenerateVectorInRangeX931(CCRndContext_t *rndContext_ptr, 262 uint32_t rndSizeWords, 263 uint32_t *rnd_ptr); 264 265 /*****************************************************************************/ 266 /** 267 * The function generates vector of non zero octets. 268 * 269 * @author reuvenl (9/14/2014) 270 * 271 * @param [in/out] rndContext_ptr - Pointer to the RND context buffer. 272 * @param pVect - The pointer to output buffer. 273 * @param size - The size of vector in bytes. 274 * 275 * @return CCError_t 276 */ 277 CCError_t RsaGenRndNonZeroVect(CCRndContext_t *rndContext_ptr, uint8_t *pVect, uint32_t size); 278 279 280 /**********************************************************************************************************/ 281 /*! 282 @brief RSA_SignInit initializes the Signing multi-call algorithm as defined in PKCS#1 2.1 standard, including v1.5. 283 284 NOTE: 285 -# In PSS_Sign v2.1 MD5 is not supported, since it is not recommended by the PKCS#1 v2.1. 286 -# According to the said standard, implementation of the function for version v1.5 is based on DER encoding of the algorithm info. 287 288 This function does not do cryptographic processing. Rather, it 289 prepares a context that is used by the Update and Finish functions. 290 291 @return CC_OK on success. 292 @return error on failure 293 */ 294 CIMPORT_C CCError_t CC_RsaSignInit( 295 CCRsaPrivUserContext_t *UserContext_ptr, /*!< [in/out] A pointer to a Context. The value returned here must be passed to the Update and Finish functions. */ 296 CCRsaUserPrivKey_t *UserPrivKey_ptr, /*!< [in] A pointer to the private key data structure. 297 \note The representation (pair or quintuple) and hence the algorithm (CRT or not) is determined by the Private Key data structure. 298 Using of the CC_BuildPrivKey or CC_BuildPrivKeyCRT determines which algorithm is used. */ 299 CCRsaHashOpMode_t rsaHashMode, /*!< [in] The enumerator value, defining the hash function to be used: SHA-1,SHA224/256/384/512, MD5 (MD5 allowed only in v1.5). 300 The hash functions recommended by PKCS#1 v2.1 are: 256/384/512. Also allowed "After" HASH modes for said functions. */ 301 CCPkcs1Mgf_t MGF, /*!< [in] The mask generation function. PKCS#1 v2.1 defines MGF1, so the only value allowed here is CC_PKCS1_MGF1. */ 302 size_t SaltLen, /*!< [in] The Length of the Salt buffer (relevant for PKCS#1 Ver 2.1 only, typically lengths is 0 or hLen). FIPS 186-4 requires, 303 that SaltLen <= hlen. If SaltLen > KeySize - hLen - 2, the function returns an error. */ 304 CCPkcs1Version_t PKCS1_ver /*!< [in] Ver 1.5 or 2.1, according to the functionality required. */ 305 ); 306 307 /**********************************************************************************************************/ 308 /*! 309 @brief CC_RsaSignUpdate processes the data to be signed in a given context. 310 311 @note CC_RsaSignUpdate can be called multiple times with data 312 313 @return CC_OK on success. 314 @return Error on failure 315 */ 316 CIMPORT_C CCError_t CC_RsaSignUpdate( 317 CCRsaPrivUserContext_t *UserContext_ptr, /*!< [in] A pointer to a valid context, as returned by CC_RsaSignInit. */ 318 uint8_t *DataIn_ptr, /*!< [in] A pointer to the data to sign. */ 319 size_t DataInSize /*!< [in] The size, in bytes, of the data to sign. */ 320 ); 321 322 /**********************************************************************************************************/ 323 /*! 324 @brief CC_RsaSignFinish calculates the signature on the data passed to one or more calls to CC_RsaSignUpdate, 325 and releases the context. 326 327 @return CC_OK on success. 328 @return Error on failure:\n 329 CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR,\n 330 CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR,\n 331 CC_RSA_INVALID_OUTPUT_POINTER_ERROR,\n 332 CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE,\n 333 CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR,\n 334 CC_RSA_PKCS1_VER_ARG_ERROR 335 */ 336 337 CIMPORT_C CCError_t CC_RsaSignFinish( 338 CCRndContext_t *rndContext_ptr, /*!< [in/out] Pointer to the RND context buffer. */ 339 CCRsaPrivUserContext_t *UserContext_ptr, /*!< [in/out] A pointer to the Context initialized by the SignInit function and used by the SignUpdate function. */ 340 uint8_t *Output_ptr, /*!< [out] A pointer to the signature. 341 The buffer must be at least PrivKey_ptr->N.len bytes long (that is, the size of the modulus, in bytes). */ 342 size_t *OutputSize_ptr, /*!< [in/out] A pointer to the Signature Size value - 343 the input value is the signature buffer size allocated, the output value is the signature size used. 344 The buffer must be at least PrivKey_ptr->N.len bytes long (that is, the size of the modulus, in bytes). */ 345 bool bIsRawMode, /*!< [in] This flag is true for those cases where we need to sign only (without encoding T) */ 346 const uint8_t *DataIn_ptr, /*!< [in] Pointer to the raw data to be signed in raw mode. Relevant only when bIsRawMode is true */ 347 size_t DataInSize /*!< [in] Size in bytes of the raw input data pointed by DataIn_ptr */ 348 ); 349 350 /**********************************************************************************************************/ 351 /*! 352 @brief RSA_VerifyInit initializes the Verify multi-call algorithm as defined in PKCS#1 v1.5 and 2.1 353 354 note: 355 -# In PSS_Sign v2.1 MD5 is not supported, since it is not recommended by the PKCS#1 v2.1. 356 -# According to the said standard, implementation of the function for version v1.5 is based on DER encoding of the algorithm info. 357 358 @return CC_OK on success. 359 @return Error on failure 360 */ 361 CIMPORT_C CCError_t CC_RsaVerifyInit( 362 CCRsaPubUserContext_t *UserContext_ptr, /*!< [in] A pointer to the public Context structure of the User. */ 363 CCRsaUserPubKey_t *UserPubKey_ptr, /*!< [in] A pointer to the public key data structure. */ 364 CCRsaHashOpMode_t rsaHashMode, /*!< [in] The hash function to be used. Currently available HASH functions: SHA1/SHA-256/384/512/MD5 (MD5 - allowed only for PKCS#1 v1.5). 365 Also allowed "After HASH" modes for said functions. */ 366 CCPkcs1Mgf_t MGF, /*!< [in] The mask generation function, relevant only for PKCS#1 v2.1. The currently allowed value for v2.1 is CC_PKCS1_MGF1. */ 367 size_t SaltLen, /*!< [in] The Length of the Salt buffer. Relevant for PKCS#1 Ver 2.1 only. Typical lengths are 0 and hashLen (20 for SHA1). 368 The maximum length allowed is NSize - hLen - 2. 369 If the salt length is not available in this process, the user can use the define: CC_RSA_VERIFY_SALT_LENGTH_UNKNOWN. 370 Security Note: This mode is not FIPS approved and it is recommended not to use this flag and provide the Salt length 371 on each verification. */ 372 CCPkcs1Version_t PKCS1_ver /*!< [in] Ver 1.5 or 2.1, according to the functionality required. */ 373 ); 374 375 /**********************************************************************************************************/ 376 /*! 377 @brief RSA_VerifyUpdate processes the data to be verified in a given context, according to PKCS1 v1.5 and 2.1 378 @brief RSA_VerifyUpdate can be called multiple times with data 379 380 @return CC_OK on success. 381 @return Error on failure 382 */ 383 384 CIMPORT_C CCError_t CC_RsaVerifyUpdate( 385 CCRsaPubUserContext_t *UserContext_ptr, /*!< [in] A pointer to the public Context structure of the User. */ 386 uint8_t *DataIn_ptr, /*!< [in] A pointer to the data whose signature is to be verified. */ 387 size_t DataInSize /*!< [in] The size, in bytes, of the data whose signature is to be verified. */ 388 ); 389 390 /**********************************************************************************************************/ 391 /*! 392 @brief RSA_VerifyFinish implements the Finish Phase of the Verify algorithm as defined in PKCS#1 v2.1 or PKCS#1 v1.5 393 394 @return CC_OK on success. 395 @return Error on failure 396 */ 397 398 CIMPORT_C CCError_t CC_RsaVerifyFinish( 399 CCRsaPubUserContext_t *UserContext_ptr, /*!< [in] A pointer to the public Context structure of the User. */ 400 uint8_t *Sig_ptr, /*!< [in] A pointer to the signature to be verified. 401 The length of the signature is PubKey_ptr->N.len bytes (that is, the size of the modulus, in bytes). */ 402 bool bIsRawMode, /*!< [in] Boolean indicating whether the input is a an already encoded T structure (possibly as specified by RFC8017 sect 9.2) 403 In that case, no hashing is performed */ 404 const uint8_t *DataIn_ptr, /*!< [in] Pointer containing the already encoded T structure to be verified as input in raw mode */ 405 size_t DataInSize /*!< [in] Size in bytes of the structure T passed as raw input */ 406 ); 407 408 #ifdef __cplusplus 409 } 410 #endif 411 412 #endif 413 414