diff options
-rw-r--r-- | envelope.cpp | 60 | ||||
-rw-r--r-- | envelope/.gitignore | 1 | ||||
-rw-r--r-- | envelope/Makefile | 7 | ||||
-rwxr-xr-x | envelope/envelope | bin | 116616 -> 116616 bytes | |||
-rw-r--r-- | envelope/main.cpp | 1 | ||||
-rwxr-xr-x | envelope/testsuite.sh | 30 | ||||
-rw-r--r-- | rsa.cpp | 7 |
7 files changed, 88 insertions, 18 deletions
diff --git a/envelope.cpp b/envelope.cpp index 5270dae..c881815 100644 --- a/envelope.cpp +++ b/envelope.cpp @@ -1,9 +1,12 @@ +#include <stdexcept> #include <cassert> #include "aes.h" #include "base64.h" //TODO: remove #include "envelope.h" #include "rng.h" +#undef DEBUG + using namespace std; namespace Envelope{ @@ -24,28 +27,39 @@ namespace Envelope{ do { for(int i=0;i<keylen;i++)*(uint32_t*)&aeskey[4*i]=crng.get(); } while(!safeKey(aeskey)); - // cerr<<"decrkey="<<Base64::encode(aeskey)<<endl; +#ifdef DEBUG + cerr<<"decrkey="<<Base64::encode(aeskey)<<endl; +#endif string payload(AES::encrypt(data,aeskey,AES::AES_256_CBC)); - // cerr<<"payload="<<Base64::encode(payload)<<endl; +#ifdef DEBUG + cerr<<"payload="<<Base64::encode(payload)<<endl; +#endif Bigint rsadata; for(int i=0;i<(int)aeskey.size();i++){ if(i!=0)rsadata<<=8; rsadata+=(uint8_t)aeskey[i]; } - // cerr<<"rsadata="<<rsadata<<endl; +#ifdef DEBUG + cerr<<"rsadata="<<rsadata<<endl; + cerr<<"pubkey = {"<<pubkey.mod<<" , "<<pubkey.exp<<'}'<<endl; +#endif Bigint res(RSA::encrypt(rsadata,pubkey)); - // cerr<<"rsaencr="<<res<<endl; +#ifdef DEBUG + cerr<<"rsaencr="<<res<<endl; +#endif - vector<uint8_t> bytes; //bytes in little-endian order + vector<uint8_t> bytes; //bytes in little-endian order (so, reverse!) while(res!=0){ bytes.push_back(res.lowdigits()&0xff); res>>=8; } - // cerr<<"encrkey="<<Base64::encode(string(bytes.rbegin(),bytes.rend()))<<endl; +#ifdef DEBUG + cerr<<"encrkey="<<Base64::encode(string(bytes.rbegin(),bytes.rend()))<<endl; +#endif payload.reserve(payload.size()+bytes.size()+2); - for(int i=bytes.size()-1;i>=0;i--)payload.push_back(bytes[i]); //append in big-endian order + for(int i=bytes.size()-1;i>=0;i--)payload.push_back(bytes[i]); //append in big-endian order again payload.push_back(bytes.size()>>8); payload.push_back((uint8_t)bytes.size()&0xff); @@ -53,38 +67,54 @@ namespace Envelope{ } string decrypt(const string &data,const RSA::Key &privkey){ - // cerr<<"=== DECRYPT ==="<<endl; +#ifdef DEBUG + cerr<<"=== DECRYPT ==="<<endl; +#endif if(data.size()<2)throw invalid_argument("Envelope data length invalid"); int encrkeylen=((uint16_t)(uint8_t)data[data.size()-2]<<8)+(uint8_t)data.back(); assert(encrkeylen<(1<<16)); - // cerr<<"encrkeylen="<<encrkeylen<<endl; +#ifdef DEBUG + cerr<<"encrkeylen="<<encrkeylen<<endl; +#endif if((int)data.size()<encrkeylen+2)throw invalid_argument("Envelope key format invalid"); string encrkey(encrkeylen,'\0'); //in big-endian for(int i=0;i<encrkeylen;i++){ encrkey[i]=data[data.size()-2-encrkeylen+i]; } - // cerr<<"encrkey="<<Base64::encode(encrkey)<<endl; +#ifdef DEBUG + cerr<<"encrkey="<<Base64::encode(encrkey)<<endl; +#endif Bigint rsadata; for(int i=0;i<encrkeylen;i++){ if(i!=0)rsadata<<=8; rsadata+=(uint8_t)encrkey[i]; } - // cerr<<"rsaencr="<<rsadata<<endl; +#ifdef DEBUG + cerr<<"rsaencr="<<rsadata<<endl; + cerr<<"privkey = {"<<privkey.mod<<" , "<<privkey.exp<<'}'<<endl; +#endif Bigint res(RSA::decrypt(rsadata,privkey)); - // cerr<<"rsadata="<<res<<endl; +#ifdef DEBUG + cerr<<"rsadata="<<res<<endl; +#endif vector<uint8_t> bytes; //bytes in little-endian order - while(res!=0){ + for(int i=0;i<32;i++){ //32 is the number of bytes in a 256-bit AES key (256/8=32) bytes.push_back(res.lowdigits()&0xff); res>>=8; } + assert(res==0); string decrkey(bytes.size(),'\0'); for(int i=0;i<(int)bytes.size();i++)decrkey[bytes.size()-1-i]=bytes[i]; - // cerr<<"decrkey="<<Base64::encode(decrkey)<<endl; +#ifdef DEBUG + cerr<<"decrkey="<<Base64::encode(decrkey)<<endl; +#endif - // cerr<<"payload="<<Base64::encode(data.substr(0,data.size()-2-encrkeylen))<<endl; +#ifdef DEBUG + cerr<<"payload="<<Base64::encode(data.substr(0,data.size()-2-encrkeylen))<<endl; +#endif return AES::decrypt(data.substr(0,data.size()-2-encrkeylen),decrkey,AES::AES_256_CBC); } diff --git a/envelope/.gitignore b/envelope/.gitignore new file mode 100644 index 0000000..68a39b8 --- /dev/null +++ b/envelope/.gitignore @@ -0,0 +1 @@ +.input.testsuite diff --git a/envelope/Makefile b/envelope/Makefile index 06b0419..19e92ed 100644 --- a/envelope/Makefile +++ b/envelope/Makefile @@ -13,9 +13,12 @@ endif BIN = envelope -.PHONY: all clean remake +.PHONY: all clean remake makelib -all: $(BIN) +makelib: + make -C .. + +all: makelib $(BIN) clean: rm -rf $(BIN) *.o *.dSYM diff --git a/envelope/envelope b/envelope/envelope Binary files differindex 50b479f..5582c01 100755 --- a/envelope/envelope +++ b/envelope/envelope diff --git a/envelope/main.cpp b/envelope/main.cpp index 49b41ff..f0e544e 100644 --- a/envelope/main.cpp +++ b/envelope/main.cpp @@ -1,5 +1,6 @@ #include <iostream> #include <cstdlib> +#include <cstring> #include "../base64.h" #include "../envelope.h" diff --git a/envelope/testsuite.sh b/envelope/testsuite.sh new file mode 100755 index 0000000..f713cda --- /dev/null +++ b/envelope/testsuite.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +make -C .. +make + +set -o pipefail + +function dotest() { + len="$1" + keylen="$2" + printf "\x1B[31;1mlen=$len keylen=$keylen\x1B[0m\n" + fname=".input.testsuite" + head -c "$len" </dev/urandom >"$fname" + keys="$(./envelope -k "$keylen")" + pubkey="$(echo "$keys" | head -1 | tr -d $'\n')" + privkey="$(echo "$keys" | tail -1 | tr -d $'\n')" + if ! diff "$fname" <(./envelope -e "$pubkey" <"$fname" | ./envelope -d "$privkey"); then + printf "\x1B[31;1m -- ERROR --\x1B[0m\n" + echo "pubkey = $pubkey" + echo "privkey = $privkey" + echo "data = $(base64 <"$fname")" + exit 1 + fi +} + +for keylen in 512 1024 2048; do + for len in 1 10 15 16 17 12345; do + dotest "$len" "$keylen" + done +done @@ -1,4 +1,5 @@ #include <algorithm> +#include <stdexcept> #include <cstdint> #include <cassert> #include "base64.h" @@ -26,7 +27,11 @@ namespace RSA{ pubkey.mod=privkey.mod=pq.first*pq.second; pubkey.exp=65537; Bigint x; - assert(egcd((pq.first-Bigint::one)*(pq.second-Bigint::one),pubkey.exp,x,privkey.exp)==1); + Bigint phi((pq.first-Bigint::one)*(pq.second-Bigint::one)); + assert(egcd(phi,pubkey.exp,x,privkey.exp)==1); + privkey.exp=privkey.exp.divmod(phi).second; + // cerr<<"pubkey = {"<<pubkey.mod<<" , "<<pubkey.exp<<'}'<<endl; + // cerr<<"privkey = {"<<privkey.mod<<" , "<<privkey.exp<<'}'<<endl; return make_pair(pubkey,privkey); } |