Here is the reverse compatibility experiment >>11 between libgcrypt https://gnupg.org/related_software/libgcrypt/ and mit-scheme encryption via medium-mcrypt >>10. First bbs.scm is encrypted with libgcrypt:
$ cat src/testgcrypt.c
#include <stdio.h>
#include <string.h>
#include <gcrypt.h>
void transfer (gcry_cipher_hd_t ctx, FILE *fin, FILE *fout, size_t block) {
unsigned char buf [65536];
size_t want = 65536, got;
size_t k, toadd;
int added = 0;
while ((got = fread (buf, 1, want, fin))) {
if (got == want) {
} else {
toadd = block - (got % block);
for (k = 0; k < toadd; k++) {
buf [got + k] = (unsigned char) toadd;
}
got += toadd;
added = 1;
}
gcry_cipher_encrypt (ctx, buf, got, NULL, 0);
fwrite (buf, 1, got, fout);
}
if (!added) {
for (k = 0; k < block; k++) {
buf [k] = (unsigned char) block;
}
gcry_cipher_encrypt (ctx, buf, block, NULL, 0);
fwrite (buf, 1, block, fout);
}
}
void work (char *keyseed, char *inpath, char *outpath) {
unsigned char key [16];
unsigned char iv [16];
size_t k;
gcry_cipher_hd_t ctx;
FILE *fin, *fout;
gcry_md_hash_buffer (GCRY_MD_MD5, key, keyseed, strlen (keyseed));
printf ("%s ", "key");
for (k = 0; k < 16; k++) {
printf ("%02x", key [k]);
iv [k] = 0;
}
printf ("\n");
gcry_cipher_open (&ctx, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
gcry_cipher_setkey (ctx, key, 16);
gcry_cipher_setiv (ctx, iv, 16);
fin = fopen (inpath, "rb");
fout = fopen (outpath, "wb");
transfer (ctx, fin, fout, 16);
fclose (fin);
fclose (fout);
gcry_cipher_close (ctx);
printf ("%s -> %s\n", inpath, outpath);
}
int main (void) {
if (!gcry_check_version (GCRYPT_VERSION)) {
printf ("%s\n", "libgcrypt version mismatch");
return 1;
}
gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
work ("secret key", "bbs.scm", "bbs.scm.enc");
return 0;
}
This is a quick hack for a test, which is why error checking is skipped.
$ gcc -Wall -o bin/testgcrypt src/testgcrypt.c -lgcrypt
$ bin/testgcrypt
key a7656fafe94dae72b1e1487670148412
bbs.scm -> bbs.scm.enc
$
The libgcrypt output is then decrypted with medium-mcrypt and the same parameters.
$ mit-scheme --load test.scm
[...]
Release 9.1.1 || Microcode 15.3 || Runtime 15.7 || SF 4.41
LIAR/x86-64 4.118 || Edwin 3.116
;Loading "test.scm"... done
1 ]=> (mcrypt-available?)
;Loading "/usr/lib/x86_64-linux-gnu/mit-scheme/lib/prmcrypt.so"... done
;Value: #t
1 ]=> (define key (md5-string "secret key"))
;Loading "/usr/lib/x86_64-linux-gnu/mit-scheme/lib/prmhash.so"... done
;Value: key
1 ]=> (md5-sum->hexadecimal key)
;Value 13: "a7656fafe94dae72b1e1487670148412"
1 ]=> (define aes (medium-mcrypt "rijndael-128" "cbc" 16 16 padadd-pkcs7 paddel-pkcs7))
;Value: aes
1 ]=> (define dec (aes '(file "bbs.scm.enc") '(file "bbs.scm.dec") key #f))
;Value: dec
1 ]=> dec
;Value 14: (file "bbs.scm.dec")
1 ]=> (string=? (md5-file "bbs.scm.dec") (md5-file "bbs.scm"))
;Value: #t
1 ]=>
$ cmp bbs.scm bbs.scm.dec
$
After decryption the original file has been recovered.