| @@ -1,217 +0,0 @@ | |||
| #include <openssl/rsa.h> | |||
| #include <openssl/pem.h> | |||
| #include <openssl/sha.h> | |||
| #include <openssl/rand.h> | |||
| #include <string.h> | |||
| #include <assert.h> | |||
| #include "lc6_crypto.h" | |||
| int lc6crypto_seeded = 0; | |||
| libchat_user* lc6crypto_genuserkey(libchat_user *user) { | |||
| BIGNUM *bn; | |||
| RSA *rsa; | |||
| BIO *pub; | |||
| BIO *priv; | |||
| size_t publen; | |||
| size_t privlen; | |||
| assert(user); | |||
| bn = BN_new(); | |||
| BN_set_word(bn, RSA_F4); | |||
| rsa = RSA_new(); | |||
| RSA_generate_key_ex(rsa, 2048, bn, NULL); | |||
| priv = BIO_new(BIO_s_mem()); | |||
| pub = BIO_new(BIO_s_mem()); | |||
| PEM_write_bio_RSAPrivateKey(priv, rsa, NULL, NULL, 0, NULL, NULL); | |||
| PEM_write_bio_RSAPublicKey(pub, rsa); | |||
| RSA_free(rsa); | |||
| privlen = BIO_pending(priv); | |||
| publen = BIO_pending(pub); | |||
| user->priv_key = malloc(privlen); | |||
| user->pub_key = malloc(publen); | |||
| BIO_read(priv, user->priv_key, privlen); | |||
| BIO_read(pub, user->pub_key, publen); | |||
| user->priv_key[privlen-1] = '\0'; | |||
| user->pub_key[publen-1] = '\0'; | |||
| BIO_free_all(priv); | |||
| BIO_free_all(pub); | |||
| BN_free(bn); | |||
| return user; | |||
| } | |||
| RSA * __lc6crypto_createRSA(unsigned char *key, int public) | |||
| { | |||
| RSA *rsa= NULL; | |||
| BIO *keybio = NULL; | |||
| keybio = BIO_new_mem_buf(key, -1); | |||
| assert(keybio); | |||
| if(public) { | |||
| PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL); | |||
| } | |||
| else { | |||
| PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL); | |||
| } | |||
| assert(rsa); | |||
| return rsa; | |||
| } | |||
| int lc6crypto_public_encrypt( | |||
| unsigned char *data, | |||
| int data_len, | |||
| unsigned char *key, | |||
| unsigned char *enc_data) | |||
| { | |||
| RSA *rsa = __lc6crypto_createRSA(key,1); | |||
| int result = RSA_public_encrypt(data_len, data, enc_data, rsa, RSA_PKCS1_OAEP_PADDING); | |||
| return result; | |||
| } | |||
| int lc6crypto_private_decrypt( | |||
| unsigned char *enc_data, | |||
| int enc_len, | |||
| unsigned char *key, | |||
| unsigned char *data) | |||
| { | |||
| RSA *rsa = __lc6crypto_createRSA(key,0); | |||
| int result = RSA_private_decrypt(enc_len, enc_data, data, rsa, RSA_PKCS1_OAEP_PADDING); | |||
| return result; | |||
| } | |||
| int lc6crypto_private_encrypt( | |||
| unsigned char *data, | |||
| int data_len, | |||
| unsigned char *key, | |||
| unsigned char *enc_data) | |||
| { | |||
| RSA *rsa = __lc6crypto_createRSA(key,0); | |||
| int result = RSA_private_encrypt(data_len, data, enc_data, rsa, RSA_PKCS1_OAEP_PADDING); | |||
| return result; | |||
| } | |||
| int lc6crypto_public_decrypt( | |||
| unsigned char *enc_data, | |||
| int enc_len, | |||
| unsigned char *key, | |||
| unsigned char *data) | |||
| { | |||
| RSA *rsa = __lc6crypto_createRSA(key,1); | |||
| int result = RSA_public_decrypt(enc_len, enc_data, data, rsa, RSA_PKCS1_OAEP_PADDING); | |||
| return result; | |||
| } | |||
| void lc6crypto_sha256( | |||
| unsigned char *data, | |||
| int data_len, | |||
| unsigned char *hash) | |||
| { | |||
| SHA256_CTX sha256; | |||
| SHA256_Init(&sha256); | |||
| SHA256_Update(&sha256, data, data_len); | |||
| SHA256_Final(hash, &sha256); | |||
| } | |||
| int lc6crypto_encrypt( | |||
| unsigned char *data, | |||
| int data_len, | |||
| unsigned char *encrypted, | |||
| unsigned char *key, | |||
| unsigned char *iv) | |||
| { | |||
| EVP_CIPHER_CTX *ctx; | |||
| int encrypted_len = 0; | |||
| int len = 0; | |||
| if(!(ctx = EVP_CIPHER_CTX_new())) | |||
| return -1; | |||
| if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) { | |||
| EVP_CIPHER_CTX_free(ctx); | |||
| return -1; | |||
| } | |||
| if(1 != EVP_EncryptUpdate(ctx, encrypted, &len, data, data_len)) { | |||
| EVP_CIPHER_CTX_free(ctx); | |||
| return -1; | |||
| } | |||
| encrypted_len += len; | |||
| if(1 != EVP_EncryptFinal_ex(ctx, encrypted + len, &len)) { | |||
| EVP_CIPHER_CTX_free(ctx); | |||
| return -1; | |||
| } | |||
| encrypted_len += len; | |||
| EVP_CIPHER_CTX_free(ctx); | |||
| return encrypted_len; | |||
| } | |||
| int lc6crypto_decrypt( | |||
| unsigned char *encrypted, | |||
| int encrypted_len, | |||
| unsigned char *data, | |||
| unsigned char *key, | |||
| unsigned char *iv) | |||
| { | |||
| EVP_CIPHER_CTX *ctx; | |||
| int data_len = 0; | |||
| int len = 0; | |||
| if(!(ctx = EVP_CIPHER_CTX_new())) | |||
| return -1; | |||
| if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) { | |||
| EVP_CIPHER_CTX_free(ctx); | |||
| return -1; | |||
| } | |||
| if(1 != EVP_DecryptUpdate(ctx, data, &len, encrypted, encrypted_len)) { | |||
| EVP_CIPHER_CTX_free(ctx); | |||
| return -1; | |||
| } | |||
| data_len += len; | |||
| if(1 != EVP_DecryptFinal_ex(ctx, encrypted + len, &len)) { | |||
| EVP_CIPHER_CTX_free(ctx); | |||
| return -1; | |||
| } | |||
| data_len += len; | |||
| EVP_CIPHER_CTX_free(ctx); | |||
| return data_len; | |||
| } | |||
| int lc6crypto_random(unsigned char *data, int data_len) { | |||
| if ( ! lc6crypto_seeded ) { | |||
| RAND_poll(); | |||
| lc6crypto_seeded=1; | |||
| } | |||
| if ( RAND_bytes(data, data_len) != 1 ) | |||
| return -1; | |||
| return data_len; | |||
| } | |||