// encryptionexample_directblowfish.c SJ // This uses directly BF and MD5 calls instead of more high level // EVP_ calls. #include #include #include #include #include #include /* Blowfish parameters, bits */ #define keyLen 128 #define blockSize 64 /* in bytes */ #define blockSizeB (blockSize/8) /* max len of messages and ascii key */ #define maxLen 1001 #define mess "Hello, world!" /* helper routines */ unsigned char *hextobin(char *s); char *bintohex(unsigned char *a, int len); unsigned char *asciitobin(char *s); void trim(char *s); void hexdump(unsigned char *a, int len); int main(int argc, char *argv[]) { char akey[maxLen], *skey, *nonhex; unsigned char *binkey; unsigned char ot[maxLen], ct[maxLen], pt[maxLen]; int i, ctlen; BF_KEY k; printf("Give the key hex or passphrase (%dbits=%d hex digits or max %d characters\n : ", keyLen, keyLen/4, maxLen-1); fgets(akey, maxLen-1, stdin); trim(akey); /* remove trailing space */ /* check if key is all hex */ nonhex = akey; while(*nonhex && isxdigit(*nonhex++)); /* check hex key length */ if (! *nonhex && strlen(akey) != keyLen/4) fprintf(stderr, "Wrong hex key length (%d/%d)", strlen(akey), keyLen/4); /* convert to binary 16 bytes */ if (*nonhex) /* non hex */ binkey = asciitobin(akey); else /* hex key */ binkey = hextobin(akey); /* print key in hex */ skey = bintohex(binkey, keyLen/8); printf("key = |%s|\n", skey); free(skey); /* make BF key */ BF_set_key(&k, keyLen/8, binkey); /* "make" message */ strcpy(ot, mess); /* count the ecrypted message length */ ctlen = ((strlen(ot) + blockSizeB - 1) / blockSizeB) * blockSizeB; printf("Original message is:\n"); hexdump(ot, ctlen); /* dump plaintext */ /* encrypt message */ for(i = 0; i < ctlen; i+=blockSize/8) BF_ecb_encrypt(ot+i, ct+i, &k, BF_ENCRYPT); printf("Encrypted message is:\n"); hexdump(ct, ctlen); /* dump ciphertext */ /* decrypt message */ for(i = 0; i < ctlen; i+=blockSize/8) BF_ecb_encrypt(ct+i, pt+i, &k, BF_DECRYPT); printf("Decrypted message is:\n"); hexdump(pt, ctlen); /* dump decrypted text */ free(binkey); return 0; } /* main() */ /* make binary out of hex string, returns new malloc:ed data */ unsigned char *hextobin(char *s) { int i, len; unsigned char *a, tmp[3]; len = strlen(s)/2; a = (char*)malloc(len); for (i = 0; i < len; i++) { strncpy(tmp, s+i*2, 3); tmp[2] = '\0'; a[i] = strtol(tmp, NULL, 16) & 0xFF; } return a; } /* hextobin() */ /* returns new string of length len*2 (+1) */ char *bintohex(unsigned char *a, int len) { int i; char *s; s = (char*)malloc(len*2+1); for (i = 0; i < len; i++) sprintf(s+i*2, "%02x", a[i]); return s; } /* hex dump to stdout */ void hexdump(unsigned char *a, int len) { FILE *p = popen("xxd", "w"); if (!p) { perror("popen"); return; } fwrite(a, 1, len, p); fclose(p); } /* returns new 128 bit key using MD5 of the string s */ unsigned char *asciitobin(char *s) { unsigned char *d = (unsigned char*)malloc(keyLen/8); MD5(s, strlen(s), d); return d; } /* trims end of string by replacing blanks by zeros */ void trim(char *s) { char *e = s + strlen(s) - 1; while (e >= s && isspace(*e)) *e-- = '\0'; }