From ecde8099ccb3f2e20466b65026bcdb7e30e3161f Mon Sep 17 00:00:00 2001 From: Robin Syihab Date: Thu, 9 Sep 2021 18:31:36 +0700 Subject: [PATCH] Bump version to 0.3.0. * [Fix] cannot correctly decrypt encrypted words inside Rust module. * [Changed] Use LITCRYPT_ENCRYPT_KEY environment variable as mandatory requirement for setting encryption key, hard-coded secret key is not supported anymore. --- Cargo.lock | 11 +++------ Cargo.toml | 3 +-- LICENSE | 2 +- README.md | 15 ++++++------ examples/simple.rs | 2 +- src/litcrypt.rs | 57 +++++++++++----------------------------------- 6 files changed, 27 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a0bb977..f5d91ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "autocfg" version = "1.0.1" @@ -15,18 +17,11 @@ dependencies = [ "num-traits", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "litcrypt" -version = "0.2.1" +version = "0.3.0" dependencies = [ "expectest", - "lazy_static", "proc-macro2", "quote", ] diff --git a/Cargo.toml b/Cargo.toml index 6efcceb..8eac49b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "litcrypt" authors = ['Robin Syihab (r@ansvia.com)'] -version = "0.2.1" +version = "0.3.0" description = "Let's encrypt your string statically during compile time" license = "Apache-2.0" repository = "https://github.com/anvie/litcrypt.rs" @@ -18,6 +18,5 @@ expectest = { version = "0.12.0", features = [] } [dependencies] quote = "1.0.8" proc-macro2 = "1.0.24" -lazy_static = "1.4.0" diff --git a/LICENSE b/LICENSE index da679e2..ca8238c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2018 Robin Syihab +Copyright 2018-2021 Robin Syihab Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 2fc54eb..8fa56ce 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ text literal using simple "XOR" algorithm. LITCRYPT let's you hide your static string literal in the binary from naughty eyes seamlessly and protect your valuable app from illegal cracking activity. -LITCRYPT works by encrypting string literal during compile time and the encrypted +LITCRYPT works by encrypting string literal during compilation time and the encrypted string remain encrypted in both disk and memory during runtime until it will be used. USAGE @@ -17,7 +17,7 @@ Dependencies: ```rust [dependencies] -litcrypt = "0.2" +litcrypt = "0.3" ``` Example: @@ -26,7 +26,7 @@ Example: #[macro_use] extern crate litcrypt; -use_litcrypt!("MY-SECRET-SPELL"); +use_litcrypt!(); fn main(){ println!("his name is: {}", lc!("Voldemort")); @@ -37,21 +37,22 @@ fn main(){ use `lc!` macro function. The first parameter is your secret key used for encrypt your literal string. This key is also encrypted and will not visible under static analyzer. -You can also override the key using environment variable `LITCRYPT_ENCRYPT_KEY` +Please take note that you need to set your encryption key using environment variable +`LITCRYPT_ENCRYPT_KEY` before compile: e.g: $ export LITCRYPT_ENCRYPT_KEY="myverysuperdupermegaultrasecretkey" -Litcrypt will encrypt every string you have written inside `lc!` statically. +Litcrypt will encrypt each string written inside `lc!` statically. -Check the output binary using `strings` command, e.g: +Check the output binary using `strings` command to verify: $ strings target/debug/my_valuable_app | grep Voldemort If the output is blank then your valuable string in your app is safe from static analyzer tool like Hexeditor etc. -For working example code see `./examples` directory, and test it using: +For working example code see `./examples` directory, and test using: $ cargo run --example simple diff --git a/examples/simple.rs b/examples/simple.rs index f826977..cd3df38 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -5,7 +5,7 @@ #[macro_use] extern crate litcrypt; -use_litcrypt!("MY-SECRET-SPELL"); +use_litcrypt!(); fn main() { // uncomment this for plain (non pre-compile-encrypted string) diff --git a/src/litcrypt.rs b/src/litcrypt.rs index d4ece33..b7bb58b 100644 --- a/src/litcrypt.rs +++ b/src/litcrypt.rs @@ -56,8 +56,6 @@ //! ```bash //! ❯ cargo run --example simple //! ``` -#[macro_use] -extern crate lazy_static; extern crate proc_macro; extern crate proc_macro2; extern crate quote; @@ -71,37 +69,22 @@ use proc_macro2::Literal; use quote::quote; use std::env; -use std::sync::{Arc, Mutex}; - mod xor; -lazy_static! { - static ref MAGIC_SPELL: Arc>> = Arc::new(Mutex::new(None)); +#[inline(always)] +fn get_magic_spell() -> String { + env::var("LITCRYPT_ENCRYPT_KEY").unwrap_or_else(|_| { + panic!("LITCRYPT_ENCRYPT_KEY environment variable not set.") + }) } /// Sets the encryption key used for encrypting subsequence strings wrapped in a [`lc!`] macro. /// /// This key is also encrypted an will not visible in a static analyzer. #[proc_macro] -pub fn use_litcrypt(tokens: TokenStream) -> TokenStream { - let magic_spell = env::var("LITCRYPT_ENCRYPT_KEY").ok().or_else(|| { - tokens - .into_iter() - .find(|a| matches!(a, TokenTree::Literal(_))) - .map(|a| match a { - TokenTree::Literal(lit) => { - let s = lit.to_string(); - String::from(&s[1..s.len() - 1]) - } - _ => "default-secret-word".to_string(), - }) - }); +pub fn use_litcrypt(_tokens: TokenStream) -> TokenStream { + let magic_spell = get_magic_spell(); - { - let mut m_spell = MAGIC_SPELL.lock().unwrap(); - *m_spell = magic_spell.clone(); - } - // env::set_var("LITCRYPT_ENCRYPT_KEY", magic_spell.as_ref().map(|a| a.to_string()).unwrap()); let encdec_func = quote! { pub mod litcrypt_internal { // This XOR code taken from https://github.com/zummenix/xor-rs @@ -163,15 +146,8 @@ pub fn use_litcrypt(tokens: TokenStream) -> TokenStream { } } }; - let result = if let Some(ekey) = magic_spell { - let ekey = xor::xor(ekey.as_bytes(), b"l33t"); - let ekey = Literal::byte_string(&ekey); - quote! { - static LITCRYPT_ENCRYPT_KEY: &'static [u8] = #ekey; - #encdec_func - } - } else { - let ekey = xor::xor(b"default-secret-word", b"l33t"); + let result = { + let ekey = xor::xor(magic_spell.as_bytes(), b"l33t"); let ekey = Literal::byte_string(&ekey); quote! { static LITCRYPT_ENCRYPT_KEY: &'static [u8] = #ekey; @@ -183,24 +159,17 @@ pub fn use_litcrypt(tokens: TokenStream) -> TokenStream { /// Encrypts the resp. string with the key set before, via calling [`use_litcrypt!`]. #[proc_macro] -pub fn lc(_item: TokenStream) -> TokenStream { +pub fn lc(tokens: TokenStream) -> TokenStream { let mut something = String::from(""); - for tok in _item { + for tok in tokens { something = match tok { TokenTree::Literal(lit) => lit.to_string(), _ => "".to_owned(), } } something = String::from(&something[1..something.len() - 1]); - let ekey = { - let m_spell = MAGIC_SPELL.lock().unwrap(); - (*m_spell).clone() - }; - let encrypt_key = match ekey { - Some(ref a) => a.as_bytes(), - None => b"default-secret-word", - }; - let encrypt_key = xor::xor(encrypt_key, b"l33t"); + let magic_spell = get_magic_spell(); + let encrypt_key = xor::xor(magic_spell.as_bytes(), b"l33t"); let encrypted = xor::xor(&something.as_bytes(), &encrypt_key); let encrypted = Literal::byte_string(&encrypted);