Changeset 8a64320e in mainline for uspace/lib/crypto
- Timestamp:
- 2015-04-23T23:40:14Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- dcba819
- Parents:
- 09044cb
- Location:
- uspace/lib/crypto
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/crypto/aes.c
r09044cb r8a64320e 28 28 29 29 /** @file aes.c 30 * 30 * 31 31 * Implementation of AES-128 symmetric cipher cryptographic algorithm. 32 * 32 * 33 33 * Based on FIPS 197. 34 34 */ … … 37 37 #include <errno.h> 38 38 #include <mem.h> 39 40 39 #include "crypto.h" 41 40 42 41 /* Number of elements in rows/columns in AES arrays. */ 43 #define ELEMS 442 #define ELEMS 4 44 43 45 44 /* Number of elements (words) in cipher. */ 46 #define CIPHER_ELEMS 445 #define CIPHER_ELEMS 4 47 46 48 47 /* Length of AES block. */ 49 #define BLOCK_LEN 1648 #define BLOCK_LEN 16 50 49 51 50 /* Number of iterations in AES algorithm. */ 52 #define ROUNDS 10 53 54 /* 55 * Irreducible polynomial used in AES algorithm. 56 * 51 #define ROUNDS 10 52 53 /** Irreducible polynomial used in AES algorithm. 54 * 57 55 * NOTE: x^8 + x^4 + x^3 + x + 1. 58 */ 59 #define AES_IP 0x1B 60 61 /* Precomputed values for AES sub_byte transformation. */ 56 * 57 */ 58 #define AES_IP 0x1b 59 60 /** Precomputed values for AES sub_byte transformation. */ 62 61 static const uint8_t sbox[BLOCK_LEN][BLOCK_LEN] = { 63 62 { 64 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 63 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 65 64 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 66 65 }, 67 66 { 68 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 67 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 69 68 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 70 69 }, … … 74 73 }, 75 74 { 76 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 75 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 77 76 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 78 77 }, 79 78 { 80 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 79 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 81 80 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 82 81 }, 83 82 { 84 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 83 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 85 84 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf 86 85 }, 87 86 { 88 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 87 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 89 88 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 90 89 }, 91 90 { 92 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 91 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 93 92 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 94 93 }, 95 94 { 96 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 95 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 97 96 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 98 97 }, 99 98 { 100 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 99 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 101 100 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb 102 101 }, 103 102 { 104 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 103 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 105 104 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 106 105 }, 107 106 { 108 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 107 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 109 108 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 110 109 }, 111 110 { 112 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 111 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 113 112 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a 114 113 }, 115 114 { 116 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 115 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 117 116 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e 118 117 }, 119 118 { 120 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 119 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 121 120 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf 122 121 }, 123 122 { 124 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 123 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 125 124 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 126 125 } 127 126 }; 128 127 129 /* Precomputed values for AES inv_sub_byte transformation. */128 /** Precomputed values for AES inv_sub_byte transformation. */ 130 129 static uint8_t inv_sbox[BLOCK_LEN][BLOCK_LEN] = { 131 130 { 132 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 131 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 133 132 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb 134 133 }, 135 134 { 136 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 135 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 137 136 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb 138 137 }, 139 138 { 140 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 139 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 141 140 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e 142 141 }, 143 142 { 144 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 143 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 145 144 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 146 145 }, 147 146 { 148 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 147 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 149 148 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 150 149 }, 151 150 { 152 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 151 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 153 152 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 154 153 }, 155 154 { 156 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 155 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 157 156 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 158 157 }, 159 158 { 160 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 159 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 161 160 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b 162 161 }, 163 162 { 164 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 163 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 165 164 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 166 165 }, 167 166 { 168 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 167 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 169 168 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e 170 169 }, 171 170 { 172 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 171 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 173 172 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b 174 173 }, 175 174 { 176 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 175 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 177 176 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 178 177 }, 179 178 { 180 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 179 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 181 180 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f 182 181 }, 183 182 { 184 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 183 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 185 184 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef 186 185 }, 187 186 { 188 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 187 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 189 188 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 190 189 }, 191 190 { 192 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 191 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 193 192 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d 194 193 } 195 194 }; 196 195 197 /* Precomputed values of powers of 2 in GF(2^8) left shifted by 24b. */196 /** Precomputed values of powers of 2 in GF(2^8) left shifted by 24b. */ 198 197 static const uint32_t r_con_array[] = { 199 0x01000000, 0x02000000, 0x04000000, 0x08000000,198 0x01000000, 0x02000000, 0x04000000, 0x08000000, 200 199 0x10000000, 0x20000000, 0x40000000, 0x80000000, 201 0x1 B000000, 0x36000000200 0x1b000000, 0x36000000 202 201 }; 203 202 204 /** 205 * Perform substitution transformation on given byte. 206 * 203 /** Perform substitution transformation on given byte. 204 * 207 205 * @param byte Input byte. 208 * @param inv Flag indicating whether to use inverse table.209 * 206 * @param inv Flag indicating whether to use inverse table. 207 * 210 208 * @return Substituted value. 209 * 211 210 */ 212 211 static uint8_t sub_byte(uint8_t byte, bool inv) … … 215 214 uint8_t j = byte & 0xF; 216 215 217 if (!inv) {216 if (!inv) 218 217 return sbox[i][j]; 219 } else { 220 return inv_sbox[i][j]; 221 } 222 } 223 224 /** 225 * Perform substitution transformation on state table. 226 * 218 219 return inv_sbox[i][j]; 220 } 221 222 /** Perform substitution transformation on state table. 223 * 227 224 * @param state State table to be modified. 228 * @param inv Flag indicating whether to use inverse table. 225 * @param inv Flag indicating whether to use inverse table. 226 * 229 227 */ 230 228 static void sub_bytes(uint8_t state[ELEMS][ELEMS], bool inv) … … 232 230 uint8_t val; 233 231 234 for (size_t i = 0; i < ELEMS; i++) {235 for (size_t j = 0; j < ELEMS; j++) {232 for (size_t i = 0; i < ELEMS; i++) { 233 for (size_t j = 0; j < ELEMS; j++) { 236 234 val = state[i][j]; 237 235 state[i][j] = sub_byte(val, inv); … … 240 238 } 241 239 242 /** 243 * Perform shift rows transformation on state table. 244 * 240 /** Perform shift rows transformation on state table. 241 * 245 242 * @param state State table to be modified. 243 * 246 244 */ 247 245 static void shift_rows(uint8_t state[ELEMS][ELEMS]) … … 249 247 uint8_t temp[ELEMS]; 250 248 251 for (size_t i = 1; i < ELEMS; i++) {249 for (size_t i = 1; i < ELEMS; i++) { 252 250 memcpy(temp, state[i], i); 253 251 memcpy(state[i], state[i] + i, ELEMS - i); … … 256 254 } 257 255 258 /** 259 * Perform inverted shift rows transformation on state table. 260 * 256 /** Perform inverted shift rows transformation on state table. 257 * 261 258 * @param state State table to be modified. 259 * 262 260 */ 263 261 static void inv_shift_rows(uint8_t state[ELEMS][ELEMS]) … … 265 263 uint8_t temp[ELEMS]; 266 264 267 for (size_t i = 1; i < ELEMS; i++) {265 for (size_t i = 1; i < ELEMS; i++) { 268 266 memcpy(temp, state[i], ELEMS - i); 269 267 memcpy(state[i], state[i] + ELEMS - i, i); … … 272 270 } 273 271 274 /** 275 * Multiplication in GF(2^8). 276 * 272 /** Multiplication in GF(2^8). 273 * 277 274 * @param x First factor. 278 275 * @param y Second factor. 279 * 276 * 280 277 * @return Multiplication of given factors in GF(2^8). 281 */ 282 static uint8_t galois_mult(uint8_t x, uint8_t y) { 283 uint8_t result = 0; 284 uint8_t F_bitH; 285 286 for(size_t i = 0; i < 8; i++) { 287 if (y & 1) 278 * 279 */ 280 static uint8_t galois_mult(uint8_t x, uint8_t y) 281 { 282 uint8_t result = 0; 283 uint8_t f_bith; 284 285 for (size_t i = 0; i < 8; i++) { 286 if (y & 1) 288 287 result ^= x; 289 F_bitH = (x & 0x80); 290 x <<= 1; 291 if (F_bitH) 292 x ^= AES_IP; 293 y >>= 1; 294 } 295 296 return result; 297 } 298 299 /** 300 * Perform mix columns transformation on state table. 301 * 288 289 f_bith = (x & 0x80); 290 x <<= 1; 291 292 if (f_bith) 293 x ^= AES_IP; 294 295 y >>= 1; 296 } 297 298 return result; 299 } 300 301 /** Perform mix columns transformation on state table. 302 * 302 303 * @param state State table to be modified. 304 * 303 305 */ 304 306 static void mix_columns(uint8_t state[ELEMS][ELEMS]) … … 307 309 memcpy(orig_state, state, BLOCK_LEN); 308 310 309 for(size_t j = 0; j < ELEMS; j++) { 310 state[0][j] = 311 galois_mult(0x2, orig_state[0][j]) ^ 312 galois_mult(0x3, orig_state[1][j]) ^ 313 orig_state[2][j] ^ 314 orig_state[3][j]; 315 state[1][j] = 316 orig_state[0][j] ^ 317 galois_mult(0x2, orig_state[1][j]) ^ 318 galois_mult(0x3, orig_state[2][j]) ^ 319 orig_state[3][j]; 320 state[2][j] = 321 orig_state[0][j] ^ 322 orig_state[1][j] ^ 323 galois_mult(0x2, orig_state[2][j]) ^ 324 galois_mult(0x3, orig_state[3][j]); 325 state[3][j] = 326 galois_mult(0x3, orig_state[0][j]) ^ 327 orig_state[1][j] ^ 328 orig_state[2][j] ^ 329 galois_mult(0x2, orig_state[3][j]); 330 } 331 } 332 333 /** 334 * Perform inverted mix columns transformation on state table. 335 * 311 for (size_t j = 0; j < ELEMS; j++) { 312 state[0][j] = 313 galois_mult(0x2, orig_state[0][j]) ^ 314 galois_mult(0x3, orig_state[1][j]) ^ 315 orig_state[2][j] ^ 316 orig_state[3][j]; 317 state[1][j] = 318 orig_state[0][j] ^ 319 galois_mult(0x2, orig_state[1][j]) ^ 320 galois_mult(0x3, orig_state[2][j]) ^ 321 orig_state[3][j]; 322 state[2][j] = 323 orig_state[0][j] ^ 324 orig_state[1][j] ^ 325 galois_mult(0x2, orig_state[2][j]) ^ 326 galois_mult(0x3, orig_state[3][j]); 327 state[3][j] = 328 galois_mult(0x3, orig_state[0][j]) ^ 329 orig_state[1][j] ^ 330 orig_state[2][j] ^ 331 galois_mult(0x2, orig_state[3][j]); 332 } 333 } 334 335 /** Perform inverted mix columns transformation on state table. 336 * 336 337 * @param state State table to be modified. 338 * 337 339 */ 338 340 static void inv_mix_columns(uint8_t state[ELEMS][ELEMS]) … … 341 343 memcpy(orig_state, state, BLOCK_LEN); 342 344 343 for(size_t j = 0; j < ELEMS; j++) { 344 state[0][j] = 345 galois_mult(0x0E, orig_state[0][j]) ^ 346 galois_mult(0x0B, orig_state[1][j]) ^ 347 galois_mult(0x0D, orig_state[2][j]) ^ 348 galois_mult(0x09, orig_state[3][j]); 349 state[1][j] = 350 galois_mult(0x09, orig_state[0][j]) ^ 351 galois_mult(0x0E, orig_state[1][j]) ^ 352 galois_mult(0x0B, orig_state[2][j]) ^ 353 galois_mult(0x0D, orig_state[3][j]); 354 state[2][j] = 355 galois_mult(0x0D, orig_state[0][j]) ^ 356 galois_mult(0x09, orig_state[1][j]) ^ 357 galois_mult(0x0E, orig_state[2][j]) ^ 358 galois_mult(0x0B, orig_state[3][j]); 359 state[3][j] = 360 galois_mult(0x0B, orig_state[0][j]) ^ 361 galois_mult(0x0D, orig_state[1][j]) ^ 362 galois_mult(0x09, orig_state[2][j]) ^ 363 galois_mult(0x0E, orig_state[3][j]); 364 } 365 } 366 367 /** 368 * Perform round key transformation on state table. 369 * 370 * @param state State table to be modified. 345 for (size_t j = 0; j < ELEMS; j++) { 346 state[0][j] = 347 galois_mult(0x0e, orig_state[0][j]) ^ 348 galois_mult(0x0b, orig_state[1][j]) ^ 349 galois_mult(0x0d, orig_state[2][j]) ^ 350 galois_mult(0x09, orig_state[3][j]); 351 state[1][j] = 352 galois_mult(0x09, orig_state[0][j]) ^ 353 galois_mult(0x0e, orig_state[1][j]) ^ 354 galois_mult(0x0b, orig_state[2][j]) ^ 355 galois_mult(0x0d, orig_state[3][j]); 356 state[2][j] = 357 galois_mult(0x0d, orig_state[0][j]) ^ 358 galois_mult(0x09, orig_state[1][j]) ^ 359 galois_mult(0x0e, orig_state[2][j]) ^ 360 galois_mult(0x0b, orig_state[3][j]); 361 state[3][j] = 362 galois_mult(0x0b, orig_state[0][j]) ^ 363 galois_mult(0x0d, orig_state[1][j]) ^ 364 galois_mult(0x09, orig_state[2][j]) ^ 365 galois_mult(0x0e, orig_state[3][j]); 366 } 367 } 368 369 /** Perform round key transformation on state table. 370 * 371 * @param state State table to be modified. 371 372 * @param round_key Round key to be applied on state table. 373 * 372 374 */ 373 375 static void add_round_key(uint8_t state[ELEMS][ELEMS], uint32_t *round_key) … … 375 377 uint8_t byte_round; 376 378 uint8_t shift; 377 uint32_t mask = 0x FF;378 379 for (size_t j = 0; j < ELEMS; j++) {380 for (size_t i = 0; i < ELEMS; i++) {381 shift = 24 - 8 *i;379 uint32_t mask = 0xff; 380 381 for (size_t j = 0; j < ELEMS; j++) { 382 for (size_t i = 0; i < ELEMS; i++) { 383 shift = 24 - 8 * i; 382 384 byte_round = (round_key[j] & (mask << shift)) >> shift; 383 385 state[i][j] = state[i][j] ^ byte_round; … … 386 388 } 387 389 388 /** 389 * Perform substitution transformation on given word. 390 * 390 /** Perform substitution transformation on given word. 391 * 391 392 * @param byte Input word. 392 * 393 * 393 394 * @return Substituted word. 395 * 394 396 */ 395 397 static uint32_t sub_word(uint32_t word) … … 398 400 uint8_t *start = (uint8_t *) &temp; 399 401 400 for(size_t i = 0; i < 4; i++) { 401 *(start+i) = sub_byte(*(start+i), false); 402 } 402 for (size_t i = 0; i < 4; i++) 403 *(start + i) = sub_byte(*(start + i), false); 403 404 404 405 return temp; 405 406 } 406 407 407 /** 408 * Perform left rotation by one byte on given word. 409 * 408 /** Perform left rotation by one byte on given word. 409 * 410 410 * @param byte Input word. 411 * 411 * 412 412 * @return Rotated word. 413 * 413 414 */ 414 415 static uint32_t rot_word(uint32_t word) … … 417 418 } 418 419 419 /** 420 * Key expansion procedure for AES algorithm. 421 * 422 * @param key Input key. 420 /** Key expansion procedure for AES algorithm. 421 * 422 * @param key Input key. 423 423 * @param key_exp Result key expansion. 424 * 424 425 */ 425 426 static void key_expansion(uint8_t *key, uint32_t *key_exp) … … 427 428 uint32_t temp; 428 429 429 for (size_t i = 0; i < CIPHER_ELEMS; i++) {430 key_exp[i] = 431 (key[4*i] << 24) +432 (key[4*i+1] << 16) +433 (key[4*i+2] << 8) +434 (key[4*i+3]);435 } 436 437 for (size_t i = CIPHER_ELEMS; i < ELEMS * (ROUNDS + 1); i++) {438 temp = key_exp[i -1];439 440 if ((i % CIPHER_ELEMS) == 0) {441 temp = sub_word(rot_word(temp)) ^ 442 r_con_array[i/CIPHER_ELEMS - 1];430 for (size_t i = 0; i < CIPHER_ELEMS; i++) { 431 key_exp[i] = 432 (key[4 * i] << 24) + 433 (key[4 * i + 1] << 16) + 434 (key[4 * i + 2] << 8) + 435 (key[4 * i + 3]); 436 } 437 438 for (size_t i = CIPHER_ELEMS; i < ELEMS * (ROUNDS + 1); i++) { 439 temp = key_exp[i - 1]; 440 441 if ((i % CIPHER_ELEMS) == 0) { 442 temp = sub_word(rot_word(temp)) ^ 443 r_con_array[i / CIPHER_ELEMS - 1]; 443 444 } 444 445 … … 447 448 } 448 449 449 /** 450 * AES-128 encryption algorithm. 451 * 452 * @param key Input key. 453 * @param input Input data sequence to be encrypted. 450 /** AES-128 encryption algorithm. 451 * 452 * @param key Input key. 453 * @param input Input data sequence to be encrypted. 454 454 * @param output Encrypted data sequence. 455 * 456 * @return EINVAL when input or key not specified, ENOMEM when pointer for 457 * output is not allocated, otherwise EOK. 455 * 456 * @return EINVAL when input or key not specified, 457 * ENOMEM when pointer for output is not allocated, 458 * otherwise EOK. 459 * 458 460 */ 459 461 int aes_encrypt(uint8_t *key, uint8_t *input, uint8_t *output) 460 462 { 461 if (!key || !input)463 if ((!key) || (!input)) 462 464 return EINVAL; 463 465 464 if (!output)466 if (!output) 465 467 return ENOMEM; 466 468 467 469 /* Create key expansion. */ 468 uint32_t key_exp[ELEMS * (ROUNDS +1)];470 uint32_t key_exp[ELEMS * (ROUNDS + 1)]; 469 471 key_expansion(key, key_exp); 470 472 471 473 /* Copy input into state array. */ 472 474 uint8_t state[ELEMS][ELEMS]; 473 for(size_t i = 0; i < ELEMS; i++) { 474 for(size_t j = 0; j < ELEMS; j++) { 475 state[i][j] = input[i + ELEMS*j]; 476 } 475 for (size_t i = 0; i < ELEMS; i++) { 476 for (size_t j = 0; j < ELEMS; j++) 477 state[i][j] = input[i + ELEMS * j]; 477 478 } 478 479 … … 480 481 add_round_key(state, key_exp); 481 482 482 for (size_t k = 1; k <= ROUNDS; k++) {483 for (size_t k = 1; k <= ROUNDS; k++) { 483 484 sub_bytes(state, false); 484 485 shift_rows(state); 485 if(k < ROUNDS) 486 487 if (k < ROUNDS) 486 488 mix_columns(state); 487 add_round_key(state, key_exp + k*ELEMS); 489 490 add_round_key(state, key_exp + k * ELEMS); 488 491 } 489 492 490 493 /* Copy state array into output. */ 491 for(size_t i = 0; i < ELEMS; i++) { 492 for(size_t j = 0; j < ELEMS; j++) { 493 output[i + j*ELEMS] = state[i][j]; 494 } 494 for (size_t i = 0; i < ELEMS; i++) { 495 for (size_t j = 0; j < ELEMS; j++) 496 output[i + j * ELEMS] = state[i][j]; 495 497 } 496 498 … … 498 500 } 499 501 500 /** 501 * AES-128 decryption algorithm. 502 * 503 * @param key Input key. 504 * @param input Input data sequence to be decrypted. 502 /** AES-128 decryption algorithm. 503 * 504 * @param key Input key. 505 * @param input Input data sequence to be decrypted. 505 506 * @param output Decrypted data sequence. 506 * 507 * @return EINVAL when input or key not specified, ENOMEM when pointer for 508 * output is not allocated, otherwise EOK. 507 * 508 * @return EINVAL when input or key not specified, 509 * ENOMEM when pointer for output is not allocated, 510 * otherwise EOK. 511 * 509 512 */ 510 513 int aes_decrypt(uint8_t *key, uint8_t *input, uint8_t *output) 511 514 { 512 if (!key || !input)515 if ((!key) || (!input)) 513 516 return EINVAL; 514 517 515 if (!output)518 if (!output) 516 519 return ENOMEM; 517 520 518 521 /* Create key expansion. */ 519 uint32_t key_exp[ELEMS * (ROUNDS +1)];522 uint32_t key_exp[ELEMS * (ROUNDS + 1)]; 520 523 key_expansion(key, key_exp); 521 524 522 525 /* Copy input into state array. */ 523 526 uint8_t state[ELEMS][ELEMS]; 524 for(size_t i = 0; i < ELEMS; i++) { 525 for(size_t j = 0; j < ELEMS; j++) { 526 state[i][j] = input[i + ELEMS*j]; 527 } 527 for (size_t i = 0; i < ELEMS; i++) { 528 for (size_t j = 0; j < ELEMS; j++) 529 state[i][j] = input[i + ELEMS * j]; 528 530 } 529 531 530 532 /* Processing loop. */ 531 add_round_key(state, key_exp + ROUNDS *ELEMS);532 533 for (int k = ROUNDS - 1; k >= 0; k--) {533 add_round_key(state, key_exp + ROUNDS * ELEMS); 534 535 for (int k = ROUNDS - 1; k >= 0; k--) { 534 536 inv_shift_rows(state); 535 537 sub_bytes(state, true); 536 add_round_key(state, key_exp + k*ELEMS); 537 if(k > 0) 538 add_round_key(state, key_exp + k * ELEMS); 539 540 if (k > 0) 538 541 inv_mix_columns(state); 539 542 } 540 543 541 544 /* Copy state array into output. */ 542 for(size_t i = 0; i < ELEMS; i++) { 543 for(size_t j = 0; j < ELEMS; j++) { 544 output[i + j*ELEMS] = state[i][j]; 545 } 545 for (size_t i = 0; i < ELEMS; i++) { 546 for (size_t j = 0; j < ELEMS; j++) 547 output[i + j * ELEMS] = state[i][j]; 546 548 } 547 549 -
uspace/lib/crypto/crypto.c
r09044cb r8a64320e 28 28 29 29 /** @file crypto.c 30 * 30 * 31 31 * Cryptographic functions library. 32 32 */ … … 37 37 #include <errno.h> 38 38 #include <byteorder.h> 39 40 39 #include "crypto.h" 41 40 42 /* Hash function procedure definition. */ 43 typedef void (*HASH_FUNC)(uint32_t*, uint32_t*); 44 45 /* Length of HMAC block. */ 46 #define HMAC_BLOCK_LENGTH 64 47 48 /* Ceiling for UINT32. */ 49 #define ceil_uint32(val) (((val) - (uint32_t)(val)) > 0 ? \ 50 (uint32_t)((val) + 1) : (uint32_t)(val)) 51 52 /* Floor for UINT32. */ 53 #define floor_uint32(val) (((val) - (uint32_t)(val)) < 0 ? \ 54 (uint32_t)((val) - 1) : (uint32_t)(val)) 55 56 /* Pick value at specified index from array or zero if out of bounds. */ 57 #define get_at(input, size, i) (i < size ? input[i] : 0) 58 59 /* Init values used in SHA1 and MD5 functions. */ 41 /** Hash function procedure definition. */ 42 typedef void (*hash_fnc_t)(uint32_t *, uint32_t *); 43 44 /** Length of HMAC block. */ 45 #define HMAC_BLOCK_LENGTH 64 46 47 /** Ceiling for uint32_t. */ 48 #define ceil_uint32(val) \ 49 (((val) - (uint32_t) (val)) > 0 ? \ 50 (uint32_t) ((val) + 1) : (uint32_t) (val)) 51 52 /** Floor for uint32_t. */ 53 #define floor_uint32(val) \ 54 (((val) - (uint32_t) (val)) < 0 ? \ 55 (uint32_t) ((val) - 1) : (uint32_t) (val)) 56 57 /** Pick value at specified index from array or zero if out of bounds. */ 58 #define get_at(input, size, i) \ 59 ((i) < (size) ? (input[i]) : 0) 60 61 /** Init values used in SHA1 and MD5 functions. */ 60 62 static const uint32_t hash_init[] = { 61 0x67452301, 0x EFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F063 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 62 64 }; 63 65 64 /* Shift amount array for MD5 algorithm. */66 /** Shift amount array for MD5 algorithm. */ 65 67 static const uint32_t md5_shift[] = { 66 68 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, … … 70 72 }; 71 73 72 /* Substitution box for MD5 algorithm. */74 /** Substitution box for MD5 algorithm. */ 73 75 static const uint32_t md5_sbox[] = { 74 76 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, … … 90 92 }; 91 93 92 /** 93 * Working procedure of MD5 cryptographic hash function. 94 * 95 * @param h Working array with interim hash parts values. 94 /** Working procedure of MD5 cryptographic hash function. 95 * 96 * @param h Working array with interim hash parts values. 96 97 * @param sched_arr Input array with scheduled values from input string. 98 * 97 99 */ 98 100 static void md5_proc(uint32_t *h, uint32_t *sched_arr) 99 101 { 100 102 uint32_t f, g, temp; 101 uint32_t w[HASH_MD5 /4];102 103 memcpy(w, h, (HASH_MD5 /4) * sizeof(uint32_t));104 105 for (size_t k = 0; k < 64; k++) {106 if (k < 16) {103 uint32_t w[HASH_MD5 / 4]; 104 105 memcpy(w, h, (HASH_MD5 / 4) * sizeof(uint32_t)); 106 107 for (size_t k = 0; k < 64; k++) { 108 if (k < 16) { 107 109 f = (w[1] & w[2]) | (~w[1] & w[3]); 108 110 g = k; 109 } else if (k >= 16 && k < 32) {111 } else if ((k >= 16) && (k < 32)) { 110 112 f = (w[1] & w[3]) | (w[2] & ~w[3]); 111 g = (5 *k + 1) % 16;112 } else if (k >= 32 && k < 48) {113 g = (5 * k + 1) % 16; 114 } else if ((k >= 32) && (k < 48)) { 113 115 f = w[1] ^ w[2] ^ w[3]; 114 g = (3 *k + 5) % 16;116 g = (3 * k + 5) % 16; 115 117 } else { 116 118 f = w[2] ^ (w[1] | ~w[3]); 117 g = 7 *k % 16;119 g = 7 * k % 16; 118 120 } 121 119 122 temp = w[3]; 120 123 w[3] = w[2]; 121 124 w[2] = w[1]; 122 w[1] += rotl_uint32(w[0] + f + md5_sbox[k] + 123 uint32_t_byteorder_swap(sched_arr[g]),124 125 w[1] += rotl_uint32(w[0] + f + md5_sbox[k] + 126 uint32_t_byteorder_swap(sched_arr[g]), 127 md5_shift[k]); 125 128 w[0] = temp; 126 129 } 127 130 128 for (uint8_t k = 0; k < HASH_MD5/4; k++)131 for (uint8_t k = 0; k < HASH_MD5 / 4; k++) 129 132 h[k] += w[k]; 130 133 } 131 134 132 /** 133 * Working procedure of SHA-1 cryptographic hash function. 134 * 135 * @param h Working array with interim hash parts values. 135 /** Working procedure of SHA-1 cryptographic hash function. 136 * 137 * @param h Working array with interim hash parts values. 136 138 * @param sched_arr Input array with scheduled values from input string. 139 * 137 140 */ 138 141 static void sha1_proc(uint32_t *h, uint32_t *sched_arr) 139 142 { 140 143 uint32_t f, cf, temp; 141 uint32_t w[HASH_SHA1 /4];142 143 for (size_t k = 16; k < 80; k++) {144 uint32_t w[HASH_SHA1 / 4]; 145 146 for (size_t k = 16; k < 80; k++) { 144 147 sched_arr[k] = rotl_uint32( 145 146 147 148 sched_arr[k-16],149 150 } 151 152 memcpy(w, h, (HASH_SHA1 /4) * sizeof(uint32_t));153 154 for (size_t k = 0; k < 80; k++) {155 if (k < 20) {148 sched_arr[k-3] ^ 149 sched_arr[k-8] ^ 150 sched_arr[k-14] ^ 151 sched_arr[k-16], 152 1); 153 } 154 155 memcpy(w, h, (HASH_SHA1 / 4) * sizeof(uint32_t)); 156 157 for (size_t k = 0; k < 80; k++) { 158 if (k < 20) { 156 159 f = (w[1] & w[2]) | (~w[1] & w[3]); 157 160 cf = 0x5A827999; 158 } else if (k >= 20 && k < 40) {161 } else if ((k >= 20) && (k < 40)) { 159 162 f = w[1] ^ w[2] ^ w[3]; 160 cf = 0x6 ED9EBA1;161 } else if (k >= 40 && k < 60) {163 cf = 0x6ed9eba1; 164 } else if ((k >= 40) && (k < 60)) { 162 165 f = (w[1] & w[2]) | (w[1] & w[3]) | (w[2] & w[3]); 163 cf = 0x8 F1BBCDC;166 cf = 0x8f1bbcdc; 164 167 } else { 165 168 f = w[1] ^ w[2] ^ w[3]; 166 cf = 0x CA62C1D6;169 cf = 0xca62c1d6; 167 170 } 168 171 169 172 temp = rotl_uint32(w[0], 5) + f + w[4] + cf + sched_arr[k]; 170 173 171 174 w[4] = w[3]; 172 175 w[3] = w[2]; … … 175 178 w[0] = temp; 176 179 } 177 178 for (uint8_t k = 0; k < HASH_SHA1/4; k++)180 181 for (uint8_t k = 0; k < HASH_SHA1 / 4; k++) 179 182 h[k] += w[k]; 180 183 } 181 184 182 /** 183 * Create hash based on selected algorithm. 184 * 185 * @param input Input message byte sequence. 185 /** Create hash based on selected algorithm. 186 * 187 * @param input Input message byte sequence. 186 188 * @param input_size Size of message sequence. 187 * @param output Result hash byte sequence. 188 * @param hash_sel Hash function selector. 189 * 190 * @return EINVAL when input not specified, ENOMEM when pointer for 191 * output hash result is not allocated, otherwise EOK. 189 * @param output Result hash byte sequence. 190 * @param hash_sel Hash function selector. 191 * 192 * @return EINVAL when input not specified, 193 * ENOMEM when pointer for output hash result 194 * is not allocated, otherwise EOK. 195 * 192 196 */ 193 197 int create_hash(uint8_t *input, size_t input_size, uint8_t *output, 194 195 { 196 if (!input)198 hash_func_t hash_sel) 199 { 200 if (!input) 197 201 return EINVAL; 198 202 199 if (!output)203 if (!output) 200 204 return ENOMEM; 201 205 202 HASH_FUNChash_func = (hash_sel == HASH_MD5) ? md5_proc : sha1_proc;206 hash_fnc_t hash_func = (hash_sel == HASH_MD5) ? md5_proc : sha1_proc; 203 207 204 208 /* Prepare scheduled input. */ … … 207 211 work_input[input_size] = 0x80; 208 212 209 size_t blocks = ceil_uint32((((double)input_size + 1) / 4 + 2) / 16); 213 // FIXME: double? 214 size_t blocks = ceil_uint32((((double) input_size + 1) / 4 + 2) / 16); 210 215 uint32_t work_arr[blocks * 16]; 211 for (size_t i = 0; i < blocks; i++) {212 for (size_t j = 0; j < 16; j++) {213 work_arr[i*16 + j] = 214 (get_at(work_input, input_size+1, i*64+j*4) << 24) |215 (get_at(work_input, input_size+1, i*64+j*4+1) << 16) |216 (get_at(work_input, input_size+1, i*64+j*4+2) << 8) |217 get_at(work_input, input_size+1, i*64+j*4+3);216 for (size_t i = 0; i < blocks; i++) { 217 for (size_t j = 0; j < 16; j++) { 218 work_arr[i*16 + j] = 219 (get_at(work_input, input_size + 1, i * 64 + j * 4) << 24) | 220 (get_at(work_input, input_size + 1, i * 64 + j * 4 + 1) << 16) | 221 (get_at(work_input, input_size + 1, i * 64 + j * 4 + 2) << 8) | 222 get_at(work_input, input_size + 1, i * 64 + j * 4 + 3); 218 223 } 219 224 } 220 225 221 uint64_t bits_size = (uint64_t) (input_size * 8);222 if (hash_sel == HASH_MD5)226 uint64_t bits_size = (uint64_t) (input_size * 8); 227 if (hash_sel == HASH_MD5) 223 228 bits_size = uint64_t_byteorder_swap(bits_size); 224 229 225 230 work_arr[(blocks - 1) * 16 + 14] = bits_size >> 32; 226 work_arr[(blocks - 1) * 16 + 15] = bits_size & 0x FFFFFFFF;231 work_arr[(blocks - 1) * 16 + 15] = bits_size & 0xffffffff; 227 232 228 233 /* Hash computation. */ 229 uint32_t h[hash_sel /4];230 memcpy(h, hash_init, (hash_sel /4) * sizeof(uint32_t));234 uint32_t h[hash_sel / 4]; 235 memcpy(h, hash_init, (hash_sel / 4) * sizeof(uint32_t)); 231 236 uint32_t sched_arr[80]; 232 for(size_t i = 0; i < blocks; i++) { 233 for(size_t k = 0; k < 16; k++) { 234 sched_arr[k] = work_arr[i*16 + k]; 235 } 237 for (size_t i = 0; i < blocks; i++) { 238 for (size_t k = 0; k < 16; k++) 239 sched_arr[k] = work_arr[i * 16 + k]; 236 240 237 241 hash_func(h, sched_arr); … … 239 243 240 244 /* Copy hash parts into final result. */ 241 for (size_t i = 0; i < hash_sel/4; i++) {242 if (hash_sel == HASH_SHA1)245 for (size_t i = 0; i < hash_sel / 4; i++) { 246 if (hash_sel == HASH_SHA1) 243 247 h[i] = uint32_t_byteorder_swap(h[i]); 244 memcpy(output + i*sizeof(uint32_t), &h[i], sizeof(uint32_t)); 248 249 memcpy(output + i * sizeof(uint32_t), &h[i], sizeof(uint32_t)); 245 250 } 246 251 … … 248 253 } 249 254 250 /** 251 * Hash-based message authentication code. 252 * 253 * @param key Cryptographic key sequence. 255 /** Hash-based message authentication code. 256 * 257 * @param key Cryptographic key sequence. 254 258 * @param key_size Size of key sequence. 255 * @param msg Message sequence.259 * @param msg Message sequence. 256 260 * @param msg_size Size of message sequence. 257 * @param hash Output parameter for result hash.261 * @param hash Output parameter for result hash. 258 262 * @param hash_sel Hash function selector. 259 * 260 * @return EINVAL when key or message not specified, ENOMEM when pointer for 261 * output hash result is not allocated, otherwise EOK. 263 * 264 * @return EINVAL when key or message not specified, 265 * ENOMEM when pointer for output hash result 266 * is not allocated, otherwise EOK. 267 * 262 268 */ 263 269 int hmac(uint8_t *key, size_t key_size, uint8_t *msg, size_t msg_size, 264 265 { 266 if (!key || !msg)270 uint8_t *hash, hash_func_t hash_sel) 271 { 272 if ((!key) || (!msg)) 267 273 return EINVAL; 268 274 269 if (!hash)275 if (!hash) 270 276 return ENOMEM; 271 277 … … 276 282 memset(work_key, 0, HMAC_BLOCK_LENGTH); 277 283 278 if(key_size > HMAC_BLOCK_LENGTH) {284 if(key_size > HMAC_BLOCK_LENGTH) 279 285 create_hash(key, key_size, work_key, hash_sel); 280 } else {286 else 281 287 memcpy(work_key, key, key_size); 282 } 283 284 for(size_t i = 0; i < HMAC_BLOCK_LENGTH; i++) { 285 o_key_pad[i] = work_key[i] ^ 0x5C; 288 289 for (size_t i = 0; i < HMAC_BLOCK_LENGTH; i++) { 290 o_key_pad[i] = work_key[i] ^ 0x5c; 286 291 i_key_pad[i] = work_key[i] ^ 0x36; 287 292 } … … 291 296 memcpy(temp_work + HMAC_BLOCK_LENGTH, msg, msg_size); 292 297 293 create_hash(temp_work, HMAC_BLOCK_LENGTH + msg_size, temp_hash, 294 298 create_hash(temp_work, HMAC_BLOCK_LENGTH + msg_size, temp_hash, 299 hash_sel); 295 300 296 301 memcpy(temp_work, o_key_pad, HMAC_BLOCK_LENGTH); … … 302 307 } 303 308 304 /** 305 * Password-Based Key Derivation Function 2 as defined in RFC 2898,306 * using HMAC-SHA1 with 4096 iterations and 32 bytes key result used307 * for WPA/WPA2.308 * 309 * @param pass Password sequence.309 /** Password-Based Key Derivation Function 2. 310 * 311 * As defined in RFC 2898, using HMAC-SHA1 with 4096 iterations 312 * and 32 bytes key result used for WPA/WPA2. 313 * 314 * @param pass Password sequence. 310 315 * @param pass_size Password sequence length. 311 * @param salt Salt sequence to be used with password.316 * @param salt Salt sequence to be used with password. 312 317 * @param salt_size Salt sequence length. 313 * @param hash Output parameter for result hash (32 byte value). 314 * 315 * @return EINVAL when pass or salt not specified, ENOMEM when pointer for 316 * output hash result is not allocated, otherwise EOK. 317 */ 318 int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, size_t salt_size, 319 uint8_t *hash) 320 { 321 if(!pass || !salt) 318 * @param hash Output parameter for result hash (32 byte value). 319 * 320 * @return EINVAL when pass or salt not specified, 321 * ENOMEM when pointer for output hash result 322 * is not allocated, otherwise EOK. 323 * 324 */ 325 int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, size_t salt_size, 326 uint8_t *hash) 327 { 328 if ((!pass) || (!salt)) 322 329 return EINVAL; 323 330 324 if (!hash)331 if (!hash) 325 332 return ENOMEM; 326 333 … … 330 337 uint8_t temp_hmac[HASH_SHA1]; 331 338 uint8_t xor_hmac[HASH_SHA1]; 332 uint8_t temp_hash[HASH_SHA1*2]; 333 334 for(size_t i = 0; i < 2; i++) { 335 uint32_t be_i = host2uint32_t_be(i+1); 339 uint8_t temp_hash[HASH_SHA1 * 2]; 340 341 for (size_t i = 0; i < 2; i++) { 342 uint32_t be_i = host2uint32_t_be(i + 1); 343 336 344 memcpy(work_salt + salt_size, &be_i, 4); 337 345 hmac(pass, pass_size, work_salt, salt_size + 4, 338 346 work_hmac, HASH_SHA1); 339 347 memcpy(xor_hmac, work_hmac, HASH_SHA1); 340 348 341 for (size_t k = 1; k < 4096; k++) {349 for (size_t k = 1; k < 4096; k++) { 342 350 memcpy(temp_hmac, work_hmac, HASH_SHA1); 343 hmac(pass, pass_size, temp_hmac, HASH_SHA1, 344 work_hmac, HASH_SHA1); 345 for(size_t t = 0; t < HASH_SHA1; t++) { 351 hmac(pass, pass_size, temp_hmac, HASH_SHA1, 352 work_hmac, HASH_SHA1); 353 354 for (size_t t = 0; t < HASH_SHA1; t++) 346 355 xor_hmac[t] ^= work_hmac[t]; 347 }348 356 } 349 memcpy(temp_hash + i*HASH_SHA1, xor_hmac, HASH_SHA1); 357 358 memcpy(temp_hash + i * HASH_SHA1, xor_hmac, HASH_SHA1); 350 359 } 351 360 -
uspace/lib/crypto/crypto.h
r09044cb r8a64320e 32 32 #include <sys/types.h> 33 33 34 #define AES_CIPHER_LENGTH 1635 #define PBKDF2_KEY_LENGTH 3234 #define AES_CIPHER_LENGTH 16 35 #define PBKDF2_KEY_LENGTH 32 36 36 37 /* Left rotation for UINT32. */ 38 #define rotl_uint32(val, shift) (((val) << shift) | ((val) >> (32 - shift))) 37 /* Left rotation for uint32_t. */ 38 #define rotl_uint32(val, shift) \ 39 (((val) << shift) | ((val) >> (32 - shift))) 39 40 40 /* Right rotation for UINT32. */ 41 #define rotr_uint32(val, shift) (((val) >> shift) | ((val) << (32 - shift))) 41 /* Right rotation for uint32_t. */ 42 #define rotr_uint32(val, shift) \ 43 (((val) >> shift) | ((val) << (32 - shift))) 42 44 43 45 /** Hash function selector and also result hash length indicator. */ 44 46 typedef enum { 45 HASH_MD5 = 46 HASH_SHA1 = 47 HASH_MD5 = 16, 48 HASH_SHA1 = 20 47 49 } hash_func_t; 48 50 49 extern int rc4(uint8_t *key, size_t key_size, uint8_t *input, size_t input_size, 50 size_t skip, uint8_t *output); 51 extern int aes_encrypt(uint8_t *key, uint8_t *input, uint8_t *output); 52 extern int aes_decrypt(uint8_t *key, uint8_t *input, uint8_t *output); 53 extern int create_hash(uint8_t *input, size_t input_size, uint8_t *output, 54 hash_func_t hash_sel); 55 extern int hmac(uint8_t *key, size_t key_size, uint8_t *msg, size_t msg_size, 56 uint8_t *hash, hash_func_t hash_sel); 57 extern int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, 58 size_t salt_size, uint8_t *hash); 51 extern int rc4(uint8_t *, size_t, uint8_t *, size_t, size_t, uint8_t *); 52 extern int aes_encrypt(uint8_t *, uint8_t *, uint8_t *); 53 extern int aes_decrypt(uint8_t *, uint8_t *, uint8_t *); 54 extern int create_hash(uint8_t *, size_t, uint8_t *, hash_func_t); 55 extern int hmac(uint8_t *, size_t, uint8_t *, size_t, uint8_t *, hash_func_t); 56 extern int pbkdf2(uint8_t *, size_t, uint8_t *, size_t, uint8_t *); 59 57 60 58 #endif -
uspace/lib/crypto/rc4.c
r09044cb r8a64320e 28 28 29 29 /** @file rc4.c 30 * 30 * 31 31 * Implementation of ARC4 symmetric cipher cryptographic algorithm. 32 * 32 * 33 33 */ 34 34 35 35 #include <errno.h> 36 36 #include <mem.h> 37 38 37 #include "crypto.h" 39 38 40 39 /* Sbox table size. */ 41 #define SBOX_SIZE 25640 #define SBOX_SIZE 256 42 41 43 /** 44 * Swap two values in sbox. 45 * 46 * @param i First index of value in sbox to be swapped. 47 * @param j Second index of value in sbox to be swapped. 42 /** Swap two values in sbox. 43 * 44 * @param i First index of value in sbox to be swapped. 45 * @param j Second index of value in sbox to be swapped. 48 46 * @param sbox Sbox to be modified. 47 * 49 48 */ 50 49 static void swap(size_t i, size_t j, uint8_t *sbox) … … 55 54 } 56 55 57 /** 58 * Sbox initialization procedure. 59 * 60 * @param key Input key. 56 /** Sbox initialization procedure. 57 * 58 * @param key Input key. 61 59 * @param key_size Size of key sequence. 62 * @param sbox Place for result sbox. 60 * @param sbox Place for result sbox. 61 * 63 62 */ 64 63 static void create_sbox(uint8_t *key, size_t key_size, uint8_t *sbox) 65 64 { 66 for (size_t i = 0; i < SBOX_SIZE; i++) {65 for (size_t i = 0; i < SBOX_SIZE; i++) 67 66 sbox[i] = i; 68 }69 67 70 68 uint8_t j = 0; 71 for (size_t i = 0; i < SBOX_SIZE; i++) {69 for (size_t i = 0; i < SBOX_SIZE; i++) { 72 70 j = j + sbox[i] + key[i % key_size]; 73 71 swap(i, j, sbox); … … 75 73 } 76 74 77 /** 78 * ARC4 encryption/decryption algorithm. 79 * 80 * @param key Input key. 81 * @param key_size Size of key sequence. 82 * @param input Input data sequence to be processed. 75 /** ARC4 encryption/decryption algorithm. 76 * 77 * @param key Input key. 78 * @param key_size Size of key sequence. 79 * @param input Input data sequence to be processed. 83 80 * @param input_size Size of input data sequence. 84 * @param skip Number of bytes to be skipped from the beginning of key stream. 85 * @param output Result data sequence. 86 * 87 * @return EINVAL when input or key not specified, ENOMEM when pointer for 88 * output is not allocated, otherwise EOK. 81 * @param skip Number of bytes to be skipped from 82 * the beginning of key stream. 83 * @param output Result data sequence. 84 * 85 * @return EINVAL when input or key not specified, 86 * ENOMEM when pointer for output is not allocated, 87 * otherwise EOK. 88 * 89 89 */ 90 int rc4(uint8_t *key, size_t key_size, uint8_t *input, size_t input_size, 91 90 int rc4(uint8_t *key, size_t key_size, uint8_t *input, size_t input_size, 91 size_t skip, uint8_t *output) 92 92 { 93 if (!key || !input)93 if ((!key) || (!input)) 94 94 return EINVAL; 95 95 96 if (!output)96 if (!output) 97 97 return ENOMEM; 98 98 … … 102 102 103 103 /* Skip first x bytes. */ 104 uint8_t i = 0, j = 0; 105 for(size_t k = 0; k < skip; k++) { 104 uint8_t i = 0; 105 uint8_t j = 0; 106 for (size_t k = 0; k < skip; k++) { 106 107 i = i + 1; 107 108 j = j + sbox[i]; … … 111 112 /* Processing loop. */ 112 113 uint8_t val; 113 for (size_t k = 0; k < input_size; k++) {114 for (size_t k = 0; k < input_size; k++) { 114 115 i = i + 1; 115 116 j = j + sbox[i];
Note:
See TracChangeset
for help on using the changeset viewer.