Skip to content

Commit 365b5fc

Browse files
committed
crypto primitives
1 parent 06b6697 commit 365b5fc

File tree

5 files changed

+126
-23
lines changed

5 files changed

+126
-23
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.*.swp
22
*~
3+
incrypt-plugin.so
34
/man1
45
/crypt
56
/tst

Makefile

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ REPO := incrypt::$(CURDIR)/crypt
1313

1414
.PHONY: all man test clean
1515

16-
all: man
16+
all: incrypt-plugin.so man
1717

1818
ifndef NODOC
1919
man: man1/git-incrypt.1
@@ -24,6 +24,15 @@ man:
2424
testman:
2525
endif
2626

27+
incrypt-plugin.so: git/incrypt-plugin.so
28+
cp $< $@
29+
30+
git/incrypt-plugin.so: git/incrypt-plugin.c git/config.mak
31+
$(MAKE) -C $(@D) DEVELOPER:=1 $(@F)
32+
33+
git/%.c: %.c
34+
cp $< $@
35+
2736
man1/%.1: git/Documentation/%.1
2837
mkdir -p man1
2938
cp $< $@
@@ -37,7 +46,7 @@ git/Documentation/%.adoc: %.adoc
3746
git/config.mak: config.mak
3847
cp $< $@
3948

40-
test: testman
49+
test: incrypt-plugin.so testman
4150
rm -rf crypt tst
4251
mkdir crypt
4352
git -C crypt init --bare -b _
@@ -72,5 +81,5 @@ install: man
7281

7382
clean:
7483
$(MAKE) -C git clean
75-
rm -rf man1 crypt tst \
84+
rm -rf incrypt-plugin.so man1 crypt tst \
7685
git/config.mak git/*incrypt* git/Documentation/*incrypt*

config.mak

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1+
CFLAGS += -fPIC
2+
3+
OBJECTS += incrypt-plugin.o
4+
15
MAN1_TXT += git-incrypt.adoc
6+
7+
incrypt-plugin.so: incrypt-plugin.o GIT-LDFLAGS $(GITLIBS)
8+
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) -shared $(filter %.o,$^) $(LIBS) $(LIB_4_CRYPTO)

git-incrypt

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,17 @@ import hashlib
3030
import base64
3131
import argparse
3232
import enum
33+
import ctypes
3334
import pygit2
34-
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
35-
from cryptography.hazmat.primitives import padding
36-
from cryptography.hazmat.backends import default_backend
35+
36+
plugin = ctypes.cdll.LoadLibrary(os.path.join(os.path.dirname(__file__),
37+
'incrypt-plugin.so'))
38+
plugin.encryptdata.argtypes = [
39+
ctypes.c_void_p, ctypes.c_size_t,
40+
ctypes.c_void_p, ctypes.POINTER(ctypes.c_size_t), ctypes.c_void_p]
41+
plugin.decryptdata.argtypes = [
42+
ctypes.c_void_p, ctypes.c_size_t,
43+
ctypes.c_void_p, ctypes.POINTER(ctypes.c_size_t), ctypes.c_void_p]
3744

3845
if not hasattr(pygit2.enums, 'FileMode'):
3946
class FileMode(enum.IntFlag):
@@ -65,29 +72,24 @@ decrypt the repository using
6572
'''
6673

6774

68-
def cipher(key):
69-
'return cipher to be used'
70-
return Cipher(algorithms.AES(key[0:32]), modes.CBC(key[32:48]),
71-
backend=default_backend())
72-
73-
74-
def pad():
75-
'return patting to be used'
76-
return padding.PKCS7(algorithms.AES.block_size)
77-
78-
7975
def encryptdata(data: bytes, key: bytes) -> (bytes, bytes):
8076
'encrypt raw data'
81-
e = cipher(key).encryptor()
82-
p = pad().padder()
83-
return e.update(p.update(data) + p.finalize()) + e.finalize()
77+
output = ctypes.create_string_buffer(len(data) + 16)
78+
poutput = ctypes.c_void_p(ctypes.addressof(output))
79+
outlen = ctypes.c_size_t(0)
80+
poutlen = ctypes.pointer(outlen)
81+
plugin.encryptdata(data, len(data), poutput, poutlen, key)
82+
return output.raw[:poutlen.contents.value]
8483

8584

8685
def decryptdata(ciphertext: bytes, key: bytes) -> bytes:
8786
'decrypt raw data'
88-
d = cipher(key).decryptor()
89-
u = pad().unpadder()
90-
return u.update(d.update(ciphertext) + d.finalize()) + u.finalize()
87+
output = ctypes.create_string_buffer(len(ciphertext) + 16)
88+
poutput = ctypes.c_void_p(ctypes.addressof(output))
89+
outlen = ctypes.c_size_t(0)
90+
poutlen = ctypes.pointer(outlen)
91+
plugin.decryptdata(ciphertext, len(ciphertext), poutput, poutlen, key)
92+
return output.raw[:poutlen.contents.value]
9193

9294

9395
def encryptrefname(ref, key):

incrypt-plugin.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8 -*- */
2+
3+
#include <stdio.h>
4+
#include <string.h>
5+
#include <openssl/err.h>
6+
#include <openssl/evp.h>
7+
8+
int encryptdata(const unsigned char* input, size_t inputlen,
9+
unsigned char* output, size_t* outputlen,
10+
const unsigned char* key);
11+
int decryptdata(const unsigned char* input, size_t inputlen,
12+
unsigned char* output, size_t* outputlen,
13+
const unsigned char* key);
14+
void cmd_main(void);
15+
16+
static void handle_openssl_error(const char *message) {
17+
fprintf(stderr, "%s\n", message);
18+
ERR_print_errors_fp(stderr);
19+
}
20+
21+
int encryptdata(const unsigned char* input, size_t inputlen,
22+
unsigned char* output, size_t* outputlen,
23+
const unsigned char* key) {
24+
const EVP_CIPHER *cipher_type = EVP_aes_256_cbc();
25+
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
26+
int outlen;
27+
if (ctx == NULL) {
28+
handle_openssl_error("EVP_CIPHER_CTX_new failed");
29+
return -1;
30+
}
31+
if (EVP_EncryptInit_ex(ctx, cipher_type, NULL, key, key+32) != 1) {
32+
handle_openssl_error("EVP_EncryptInit_ex failed");
33+
EVP_CIPHER_CTX_free(ctx);
34+
return -1;
35+
}
36+
if (EVP_EncryptUpdate(ctx, output, &outlen, input, inputlen) != 1) {
37+
handle_openssl_error("EVP_EncryptUpdate failed");
38+
EVP_CIPHER_CTX_free(ctx);
39+
return -1;
40+
}
41+
*outputlen = outlen;
42+
if (EVP_EncryptFinal_ex(ctx, output + *outputlen, &outlen) != 1) {
43+
handle_openssl_error("EVP_EncryptFinal_ex failed");
44+
EVP_CIPHER_CTX_free(ctx);
45+
return -1;
46+
}
47+
*outputlen += outlen;
48+
EVP_CIPHER_CTX_free(ctx);
49+
return 0;
50+
}
51+
52+
int decryptdata(const unsigned char* input, size_t inputlen,
53+
unsigned char* output, size_t* outputlen,
54+
const unsigned char* key) {
55+
const EVP_CIPHER *cipher_type = EVP_aes_256_cbc();
56+
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
57+
int outlen;
58+
if (ctx == NULL) {
59+
handle_openssl_error("EVP_CIPHER_CTX_new failed");
60+
return -1;
61+
}
62+
if (EVP_DecryptInit_ex(ctx, cipher_type, NULL, key, key+32) != 1) {
63+
handle_openssl_error("EVP_DecryptInit_ex failed");
64+
EVP_CIPHER_CTX_free(ctx);
65+
return -1;
66+
}
67+
if (EVP_DecryptUpdate(ctx, output, &outlen, input, inputlen) != 1) {
68+
handle_openssl_error("EVP_DecryptUpdate failed");
69+
EVP_CIPHER_CTX_free(ctx);
70+
return -1;
71+
}
72+
*outputlen = outlen;
73+
if (EVP_DecryptFinal_ex(ctx, output + *outputlen, &outlen) != 1) {
74+
handle_openssl_error("EVP_DecryptFinal_ex failed");
75+
EVP_CIPHER_CTX_free(ctx);
76+
return -1;
77+
}
78+
*outputlen += outlen;
79+
EVP_CIPHER_CTX_free(ctx);
80+
return 0;
81+
}
82+
83+
void cmd_main(void) {
84+
}

0 commit comments

Comments
 (0)