Skip to content

Instantly share code, notes, and snippets.

@shekohex
Last active October 7, 2019 19:58
Show Gist options
  • Save shekohex/397d9822e3d0bcfc2ce838b967fac350 to your computer and use it in GitHub Desktop.
Save shekohex/397d9822e3d0bcfc2ce838b967fac350 to your computer and use it in GitHub Desktop.
RC5.c -- Reference implementation of RC5-32/12/16 in C for Decrypt CO3 Packets
/*
* RC5REF.C -- Reference implementation of RC5-32/12/16 in C.
* Copyright (C) 1995 RSA Data Security, Inc.
* reWritten By Shady Khalifa @shekohex 2018
* see this pdf for more info about RC5: https://goo.gl/U5G44K
*/
#include <stdio.h>
#include <stdlib.h>
typedef unsigned int WORD; // Should be 32-bit = 4 bytes
#define w 32 // word size in bits
#define r 12 // number of rounds
#define b 16 // number of bytes in key
#define c 04 // number words in key = ceil(8*b/w)
#define t 26 // size of table S = 2*(r+l) words
WORD S[t]; // expanded key table
WORD P = 0xB7E15163, Q = 0x9E3779B9; // magic constants
// Rotation operators, x must be unsigned, to get logical right shift
#define ROTL(x, y) (((x) << (y & (w - 1))) | ((x) >> (w - (y & (w - 1))))) // Rotate Left
#define ROTR(x, y) (((x) >> (y & (w - 1))) | ((x) << (w - (y & (w - 1))))) // Rotate Right
// 2 WORD input pt (plain text) / output ct (encrypted text)
void RC5_Encrypt(WORD *pt, WORD *ct) {
WORD i,
A = pt[0] + S[0],
B = pt[1] + S[1];
for (i = 1; i <= r; i++) {
A = ROTL(A ^ B, B) + S[2 * i + 0];
B = ROTL(B ^ A, A) + S[2 * i + 1];
}
ct[0] = A, ct[1] = B;
}
// 2 WORD input ct (encrypted text) / output pt (plain text)
void RC5_Decrypt(WORD *ct, WORD *pt) {
WORD i,
A = ct[0],
B = ct[1];
for (i = r; i > 0; i--) {
B = ROTR(B - S[2 * i + 1], A) ^ A;
A = ROTR(A - S[2 * i + 0], B) ^ B;
}
pt[0] = A - S[0], pt[1] = B - S[1];
}
// secret input key K[0...b-1]
void RC5_Setup(unsigned char *K) {
WORD i, j, k, A, B,
u = w / 8, L[c];
// Initialize L, then S, then mix key into S
for (i = b - 1, L[c - 1] = 0; i != -1; i--) {
L[i / u] = (L[i / u] << 8) + K[i];
}
for (S[0] = P, i=1; i < t; i++) S[i] = S[i - 1] + Q;
// 3 * t > 3 * c
for (A = B = i = j = k = 0; k < 3 * t; k++) {
A = S[i] = ROTL(S[i] + (A + B), 0000003);
B = L[j] = ROTL(L[j] + (A + B), (A + B));
i = (i + 1) % t;
j = (j + 1) % c;
}
}
void main() {
WORD i, j;
// Is that key is correct?
//Seed: 0x54 0x54 0x54 0x54
unsigned char key[b] = {
0x8B, 0x10, 0x2F, 0x3A,
0x93, 0x0D, 0x39, 0x57,
0xC9, 0x02, 0xDB, 0x37,
0x1B, 0x74, 0x90, 0x36 };
//Seed: 0x00 0x00 0x00 0x00
unsigned char key_old[b] = {
0x26, 0x27, 0xF6, 0x85,
0x97, 0x15, 0xAD, 0x1D,
0xD2, 0x94, 0xDD, 0xC4,
0x76, 0x19, 0x39, 0x31 };
if (sizeof(WORD) != 4) {
printf("RC5 error: WORD has %d bytes, it should be 4 bytes.\n", sizeof(WORD));
exit(1);
}
// Encrypted Packet [body], without Headers e.g the length, and also with out the seed.
// Packet Id: 1542
// Total Lenght 312
// Seed: 4 bytes
// Header: 4 Bytes
WORD ct[304] = {
0x91, 0x72, 0x8D, 0x2D, 0x9A, 0xFD, 0x86, 0xEA, 0x25, 0xF0, 0x3C,
0xF2, 0xED, 0xEC, 0x22, 0x81, 0x40, 0xC7, 0x35, 0x85, 0x40, 0x40,
0x52, 0xC3, 0x09, 0x57, 0x1A, 0xBF, 0xD7, 0x4E, 0xB7, 0xD1, 0x33,
0xC2, 0x39, 0x58, 0xF9, 0x73, 0x10, 0xF2, 0x3E, 0xBB, 0x19, 0xDD,
0x30, 0xA6, 0x38, 0x5E, 0x35, 0xF4, 0xF3, 0xFF, 0x7B, 0x27, 0x61,
0x0C, 0xDF, 0x41, 0x43, 0xDA, 0xC5, 0x15, 0x32, 0x37, 0xB6, 0x5F,
0x7A, 0xAA, 0xBB, 0xDF, 0x27, 0x4F, 0x0A, 0x7B, 0xE1, 0x90, 0xC2,
0xED, 0x02, 0x4A, 0xCB, 0xE9, 0xB6, 0x39, 0xF9, 0x73, 0x10, 0xF2,
0x3E, 0xBB, 0x19, 0xDD, 0x30, 0xA6, 0x38, 0x5E, 0xF9, 0x73, 0x10,
0xF2, 0x3E, 0xBB, 0x19, 0xDD, 0x30, 0xA6, 0x38, 0x5E, 0xC0, 0xB3,
0x0E, 0x8A, 0x5B, 0xD6, 0xEE, 0xBB, 0x9A, 0xE7, 0x9B, 0x56, 0xAF,
0x77, 0x64, 0x01, 0x72, 0xC9, 0xEE, 0x8D, 0x14, 0xBF, 0x2B, 0x44,
0x92, 0x1B, 0x31, 0xC6, 0xBD, 0xA1, 0x46, 0x39, 0xB2, 0xBE, 0xE2,
0x6C, 0x50, 0xA4, 0xAA, 0x7A, 0xA6, 0x6D, 0x30, 0xCA, 0x24, 0xF5,
0xB1, 0xD1, 0xDE, 0x60, 0x91, 0x83, 0xC6, 0x51, 0xC6, 0x04, 0x29,
0xE3, 0x6B, 0x17, 0x45, 0xD2, 0x0E, 0xDA, 0xB5, 0x38, 0x63, 0x49,
0x9D, 0xA1, 0xC5, 0xD4, 0x76, 0x5E, 0x49, 0xC1, 0x74, 0x45, 0x4D,
0x4D, 0x69, 0xE5, 0x75, 0xFD, 0xA9, 0xF5, 0xA7, 0x6E, 0x4D, 0xC7,
0xF3, 0xBD, 0xBD, 0xF6, 0x8C, 0x4C, 0x54, 0x3D, 0x65, 0x26, 0x80,
0x2A, 0x13, 0x49, 0x07, 0xEE, 0x00, 0x3D, 0x4C, 0xB9, 0xFC, 0xFB,
0xCE, 0x55, 0x9E, 0x37, 0xF6, 0xC4, 0xC9, 0x26, 0xF9, 0x73, 0x10,
0xF2, 0x3E, 0xBB, 0x19, 0xDD, 0x30, 0xA6, 0x38, 0x5E, 0xD4, 0x18,
0x0E, 0x7F, 0x58, 0xFE, 0xBF, 0x8D, 0x95, 0x45, 0xB5, 0x66, 0xCA,
0x62, 0x36, 0xA6, 0x09, 0x6A, 0xBC, 0xF5, 0xBD, 0x02, 0x08, 0x5E,
0x67, 0x95, 0x4C, 0xCB, 0xBC, 0x08, 0x6B, 0x8C, 0xA6, 0xDA, 0x12,
0xB2, 0x75, 0xE5, 0x27, 0xF3, 0x05, 0x32, 0x59, 0xEC, 0xAA, 0x20,
0x8C, 0x3D, 0x58, 0x90, 0x87, 0x46, 0x43, 0xF0, 0xB5, 0x75, 0xFE,
0x46, 0x10, 0x9D, 0xF4, 0x1E, 0x32, 0x2D, };
// TODO: Read the row packet form a file !
// Setupt the RC5 Table from that key, then print it *the key*
RC5_Setup(key);
printf(" key = ");
for (j = 0; j < b; j++) printf("%.2X ", key[j]); // As Hex
int ct_len = sizeof(ct) / sizeof(WORD);
// The Decrypted Pakcet Body
WORD pt[ct_len];
int n = ct_len / 2;
for (i = 0; i < n; i++) {
int index = i * 2;
WORD ct_slice[2], pt_slice[2] = { 0x00, 0x00 };
ct_slice[0] = ct[index];
ct_slice[1] = ct[index + 1];
RC5_Decrypt(ct_slice, pt_slice);
pt[index] = pt_slice[0];
pt[index + 1] = pt_slice[1];
printf("\n#%.3d PlainText(%.3d, %.3d): %.8X %.8X\t", index, index, index + 1, pt[index], pt[index + 1]);
printf(" CipherText(%.3d, %.3d): %.8X %.8X\n", index, index + 1, ct[index], ct[index + 1]);
}
int written = 0;
FILE *f = fopen("packet.data", "wb");
written = fwrite(pt, sizeof(WORD), sizeof(pt), f);
if (written == 0) {
printf("Error during writing to file !");
exit(1);
}
fclose(f);
exit(0);
}
@shekohex
Copy link
Author

It's still buggy, but it mostly not works as intended to be
of course the implementation itself of RC5 is working as supposed to be, you can test it , but we think the key is wrong.

so any ideas ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment