Initialize an OCB context. @param ocb [out] The destination of the OCB state @param cipher The index of the desired cipher @param key The secret key @param keylen The length of the secret key (octets) @param nonce The session nonce (length of the block size of the cipher) @return CRYPT_OK if successful */
| 43 | @return CRYPT_OK if successful |
| 44 | */ |
| 45 | int ocb_init(ocb_state *ocb, int cipher, |
| 46 | const unsigned char *key, unsigned long keylen, const unsigned char *nonce) |
| 47 | { |
| 48 | int poly, x, y, m, err; |
| 49 | |
| 50 | LTC_ARGCHK(ocb != NULL); |
| 51 | LTC_ARGCHK(key != NULL); |
| 52 | LTC_ARGCHK(nonce != NULL); |
| 53 | |
| 54 | /* valid cipher? */ |
| 55 | if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { |
| 56 | return err; |
| 57 | } |
| 58 | |
| 59 | /* determine which polys to use */ |
| 60 | ocb->block_len = cipher_descriptor[cipher].block_length; |
| 61 | x = (int)(sizeof(polys)/sizeof(polys[0])); |
| 62 | for (poly = 0; poly < x; poly++) { |
| 63 | if (polys[poly].len == ocb->block_len) { |
| 64 | break; |
| 65 | } |
| 66 | } |
| 67 | if (poly == x) { |
| 68 | return CRYPT_INVALID_ARG; /* block_len not found in polys */ |
| 69 | } |
| 70 | if (polys[poly].len != ocb->block_len) { |
| 71 | return CRYPT_INVALID_ARG; |
| 72 | } |
| 73 | |
| 74 | /* schedule the key */ |
| 75 | if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) { |
| 76 | return err; |
| 77 | } |
| 78 | |
| 79 | /* find L = E[0] */ |
| 80 | zeromem(ocb->L, ocb->block_len); |
| 81 | if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) { |
| 82 | return err; |
| 83 | } |
| 84 | |
| 85 | /* find R = E[N xor L] */ |
| 86 | for (x = 0; x < ocb->block_len; x++) { |
| 87 | ocb->R[x] = ocb->L[x] ^ nonce[x]; |
| 88 | } |
| 89 | if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) { |
| 90 | return err; |
| 91 | } |
| 92 | |
| 93 | /* find Ls[i] = L << i for i == 0..31 */ |
| 94 | XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len); |
| 95 | for (x = 1; x < 32; x++) { |
| 96 | m = ocb->Ls[x-1][0] >> 7; |
| 97 | for (y = 0; y < ocb->block_len-1; y++) { |
| 98 | ocb->Ls[x][y] = ((ocb->Ls[x-1][y] << 1) | (ocb->Ls[x-1][y+1] >> 7)) & 255; |
| 99 | } |
| 100 | ocb->Ls[x][ocb->block_len-1] = (ocb->Ls[x-1][ocb->block_len-1] << 1) & 255; |
| 101 | |
| 102 | if (m == 1) { |
no test coverage detected