aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--envelope.cpp60
-rw-r--r--envelope/.gitignore1
-rw-r--r--envelope/Makefile7
-rwxr-xr-xenvelope/envelopebin116616 -> 116616 bytes
-rw-r--r--envelope/main.cpp1
-rwxr-xr-xenvelope/testsuite.sh30
-rw-r--r--rsa.cpp7
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
index 50b479f..5582c01 100755
--- a/envelope/envelope
+++ b/envelope/envelope
Binary files differ
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
diff --git a/rsa.cpp b/rsa.cpp
index 09ea1bc..94c9782 100644
--- a/rsa.cpp
+++ b/rsa.cpp
@@ -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);
}