/** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int ltc_md2_init(ltc_md2_ctx *ctx) { LTC_ARGCHK(ctx != NULL); /* LTC_MD2 uses a zero'ed state... */ CC_XZEROMEM(ctx->X, sizeof(ctx->X)); CC_XZEROMEM(ctx->chksum, sizeof(ctx->chksum)); CC_XZEROMEM(ctx->buf, sizeof(ctx->buf)); ctx->curlen = 0; return CRYPT_OK; }
/** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (16 bytes) @return CRYPT_OK if successful */ int ltc_md2_done(ltc_md2_ctx *ctx, unsigned char *out) { unsigned long i, k; LTC_ARGCHK(ctx != NULL); LTC_ARGCHK(out != NULL); if (ctx->curlen >= sizeof(ctx->buf)) { return CRYPT_INVALID_ARG; } /* pad the message */ k = 16 - ctx->curlen; for (i = ctx->curlen; i < 16; i++) { ctx->buf[i] = (unsigned char)k; } /* hash and update */ md2_compress(ctx); md2_update_chksum(ctx); /* hash checksum */ CC_XMEMCPY(ctx->buf, ctx->chksum, 16); md2_compress(ctx); /* output is lower 16 bytes of X */ CC_XMEMCPY(out, ctx->X, 16); #ifdef LTC_CLEAN_STACK CC_XZEROMEM(ctx, sizeof(hash_state)); #endif return CRYPT_OK; }
static void ccRSACryptorClear(CCRSACryptorRef theKey) { CCRSACryptor *key = (CCRSACryptor *) theKey; if(!key) return; CC_XZEROMEM(key, sizeof(CCRSACryptor)); CC_XFREE(key, sizeof(CCRSACryptor)); }
CCCryptorStatus CCRSACryptorDecodePayloadPKCS1( CCRSACryptorRef publicKey, const void *cipherText, size_t cipherTextLen, void *plainText, size_t *plainTextLen) { int tcReturn; int stat = 0; CCRSACryptor *publicCryptor = publicKey; uint8_t *message; unsigned long messageLen, modulusLen; CCCryptorStatus retval = kCCSuccess; modulusLen = CCRSAGetKeySize(publicKey); messageLen = modulusLen / 8; if((message = CC_XMALLOC(messageLen)) == NULL) return kCCMemoryFailure; tcReturn = rsa_exptmod(cipherText, cipherTextLen, message, messageLen, publicCryptor->keyType, &publicCryptor->key); if(tcReturn) { retval = kCCDecodeError; goto out; } tcReturn = pkcs_1_v1_5_decode(message, messageLen, LTC_PKCS_1_EME, modulusLen, plainText, plainTextLen, &stat); if(tcReturn) { retval = kCCDecodeError; goto out; } if(!stat) { retval = kCCDecodeError; goto out; } out: CC_XZEROMEM(message, messageLen); CC_XFREE(message, messageLen); return retval; }
static bool ccRSApairwiseConsistencyCheck(CCRSACryptorRef privateKey, CCRSACryptorRef publicKey) { CCCryptorStatus status = kCCSuccess; size_t theDataLen = MAXKEYTEST, resultLen, recoveryLen; uint8_t theData[MAXKEYTEST]; uint8_t theResult[MAXKEYTEST]; uint8_t theRecovered[MAXKEYTEST]; /* the RSA keysize had better be equal - we convert keysizes to bytes since we need to work with the appropriate size data buffers for tests. */ theDataLen = CCRSAGetKeySize(privateKey) / 8; if(theDataLen > MAXKEYTEST || theDataLen != (size_t) (CCRSAGetKeySize(publicKey) / 8)) { return false; } /* Fill the input buffer for the test */ CC_XMEMSET(theData, 0x0a, theDataLen); /* Encrypt the buffer with the private key then be sure the output isn't the same as the input */ resultLen = theDataLen; status = CCRSACryptorCrypt(privateKey, theData, theDataLen, theResult, &resultLen); if (kCCSuccess != status) { return false; } if(CC_XMEMCMP(theData, theResult, theDataLen) == 0) { return false; } /* Decrypt the buffer with the public key and be sure the output matches the original input */ recoveryLen = theDataLen; status = CCRSACryptorCrypt(publicKey, theResult, resultLen, theRecovered, &recoveryLen); if (kCCSuccess != status) { return false; } if(recoveryLen != theDataLen) { return false; } if(CC_XMEMCMP(theData, theRecovered, theDataLen) != 0) { return false; } /* Cleanup and leave */ CC_XZEROMEM(theData, MAXKEYTEST); CC_XZEROMEM(theResult, MAXKEYTEST); CC_XZEROMEM(theRecovered, MAXKEYTEST); return true; }