/** (PKCS #1 v2.0) decrypt then OAEP depad @param in The ciphertext @param inlen The length of the ciphertext (octets) @param out [out] The plaintext @param outlen [in/out] The max size and resulting size of the plaintext (octets) @param lparam The system "lparam" value @param lparamlen The length of the lparam value (octets) @param hash_idx The index of the hash desired @param stat [out] Result of the decryption, 1==valid, 0==invalid @param key The corresponding private RSA key @return CRYPT_OK if succcessul (even if invalid) */ int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, int hash_idx, int *stat, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; unsigned char *tmp; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(stat != NULL); /* default to invalid */ *stat = 0; /* valid hash ? */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* get modulus len in bits */ modulus_bitlen = mp_count_bits(&(key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size(&(key->N)); if (modulus_bytelen != inlen) { return CRYPT_INVALID_PACKET; } /* allocate ram */ tmp = XMALLOC(inlen); if (tmp == NULL) { return CRYPT_MEM; } /* rsa decode the packet */ x = inlen; if ((err = rsa_exptmod(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) { XFREE(tmp); return err; } /* now OAEP decode the packet */ err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx, out, outlen, stat); XFREE(tmp); return err; }
/** (PKCS #1, v2.0) de-sign then PSS depad @param sig The signature data @param siglen The length of the signature data (octets) @param hash The hash of the message that was signed @param hashlen The length of the hash of the message that was signed (octets) @param hash_idx The index of the desired hash @param saltlen The length of the salt used during signature @param stat [out] The result of the signature comparison, 1==valid, 0==invalid @param key The public RSA key corresponding to the key that performed the signature @return CRYPT_OK on success (even if the signature is invalid) */ int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int hash_idx, unsigned long saltlen, int *stat, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; unsigned char *tmpbuf; LTC_ARGCHK(hash != NULL); LTC_ARGCHK(sig != NULL); LTC_ARGCHK(stat != NULL); LTC_ARGCHK(key != NULL); /* default to invalid */ *stat = 0; /* valid hash ? */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* get modulus len in bits */ modulus_bitlen = mp_count_bits(&(key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size(&(key->N)); if (modulus_bytelen != siglen) { return CRYPT_INVALID_PACKET; } /* allocate temp buffer for decoded sig */ tmpbuf = XMALLOC(siglen); if (tmpbuf == NULL) { return CRYPT_MEM; } /* RSA decode it */ x = siglen; if ((err = rsa_exptmod(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) { XFREE(tmpbuf); return err; } /* PSS decode it */ err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat); XFREE(tmpbuf); return err; }
void packet_client_billinginfo(unsigned char* buff, int len) { unsigned char rsa_out[1024]; unsigned char depad_out[1024]; unsigned char outbuff[4096]; unsigned long x, y; int err; int chunk_size; int outpos = 0; //bytes_out(buff, len); /* first two bytes are unknown */ buff += 2; len -= 2; /* key is made up of blocks which are padded then crypted. They come on the wire as 2 bytes size (net order) then data */ while (len > 0) { chunk_size = (buff[0] << 8) | buff[1]; buff += 2; len -= 2; x = sizeof(rsa_out); if ((err = rsa_exptmod(buff, chunk_size, rsa_out, &x, PK_PRIVATE, &key)) != CRYPT_OK) { printf("rsa_exptmod failed: %s\n", error_to_string(err)); return; } y = sizeof(depad_out); if ((err = rsa_depad(rsa_out, x, depad_out, &y)) != CRYPT_OK) { printf("rsa_depad failed: %s\n", error_to_string(err)); return; } memcpy(&outbuff[outpos], depad_out, y); outpos += y; //printf("packet_client_billinginfo has %lu bytes\n", y); buff += chunk_size; len -= chunk_size; } buff = outbuff; printf("Billing Info:\n"); printf(" Account Name: %s\n", dump_str(&buff)); printf(" Password: %s\n", dump_str(&buff)); printf(" Cardholder's Name: %s\n", dump_str(&buff)); printf(" CreditCard Number: %s\n", dump_str(&buff)); printf(" Expiration Date: %s/", dump_str(&buff)); printf("%s\n", dump_str(&buff)); printf(" Billing cycle: %s\n", dump_str(&buff)); }
void packet_client_setenckey(unsigned char* buff, int len) { unsigned char rsa_out[4096]; unsigned char depad_out[4096]; unsigned char tmp_symkey[SYMKEY_SIZE+4]; unsigned long x, y; int err; int chunk_size; int symkeysize; int outpos = 0; /* first two bytes are unknown */ buff += 2; len -= 2; /* key is made up of blocks which are padded then crypted. They come on the wire as 2 bytes size (net order) then data */ while (len > 0) { chunk_size = (buff[0] << 8) | buff[1]; buff += 2; len -= 2; x = sizeof(rsa_out); if ((err = rsa_exptmod(buff, chunk_size, rsa_out, &x, PK_PRIVATE, &key)) != CRYPT_OK) { printf("rsa_exptmod failed: %s\n", error_to_string(err)); return; } y = sizeof(depad_out); if ((err = rsa_depad(rsa_out, x, depad_out, &y)) != CRYPT_OK) { printf("rsa_depad failed: %s\n", error_to_string(err)); return; } memcpy(&tmp_symkey[outpos], depad_out, y); outpos += y; // printf("packet_client_setenckey has %lu bytes\n", y); buff += chunk_size; len -= chunk_size; } /* first 4 bytes are WORD keysize twice (net order) */ symkeysize = my_ntohs(tmp_symkey); //(tmp_symkey[0] << 8) | tmp_symkey[1]; setup_sbox_from_key(&tmp_symkey[4], symkeysize); printf("Client sent symmetric key (%d bytes)...\n", symkeysize); }
/** (PKCS #1, v2.0) PSS pad then sign @param in The hash to sign @param inlen The length of the hash to sign (octets) @param out [out] The signature @param outlen [in/out] The max size and resulting size of the signature @param prng An active PRNG state @param prng_idx The index of the PRNG desired @param hash_idx The index of the hash desired @param saltlen The length of the salt desired (octets) @param key The private RSA key to use @return CRYPT_OK if successful */ int rsa_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int prng_idx, int hash_idx, unsigned long saltlen, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* valid prng and hash ? */ if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { return err; } if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* get modulus len in bits */ modulus_bitlen = mp_count_bits(&(key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size(&(key->N)); if (modulus_bytelen > *outlen) { return CRYPT_BUFFER_OVERFLOW; } /* PSS pad the key */ x = *outlen; if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx, hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) { return err; } /* RSA encode it */ return rsa_exptmod(out, x, out, outlen, PK_PRIVATE, key); }
/** (PKCS #1 v2.0) OAEP pad then encrypt @param in The plaintext @param inlen The length of the plaintext (octets) @param out [out] The ciphertext @param outlen [in/out] The max size and resulting size of the ciphertext @param lparam The system "lparam" for the encryption @param lparamlen The length of lparam (octets) @param prng An active PRNG @param prng_idx The index of the desired prng @param hash_idx The index of the desired hash @param key The RSA key to encrypt to @return CRYPT_OK if successful */ int rsa_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, prng_state *prng, int prng_idx, int hash_idx, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* valid prng and hash ? */ if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { return err; } if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* get modulus len in bits */ modulus_bitlen = mp_count_bits(&(key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size(&(key->N)); if (modulus_bytelen > *outlen) { return CRYPT_BUFFER_OVERFLOW; } /* OAEP pad the key */ x = *outlen; if ((err = pkcs_1_oaep_encode(in, inlen, lparam, lparamlen, modulus_bitlen, prng, prng_idx, hash_idx, out, &x)) != CRYPT_OK) { return err; } /* rsa exptmod the OAEP pad */ return rsa_exptmod(out, x, out, outlen, PK_PUBLIC, key); }
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; }