21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

If you are using padding and you know the length of the input message in advance,<br />

you can calculate the output length easily. If the message is of a length that is an<br />

exact multiple of the block size, the output message will be a block larger. Otherwise,<br />

the message will get as many bytes added to it as necessary to make the input<br />

length a multiple of the block size. Using integer math, we can calculate the output<br />

length as follows, where il is the input length:<br />

((il / SPC_BLOCK_SZ) * SPC_BLOCK_SZ) + SPC_BLOCK_SZ<br />

If we do not have the entire message at once, when using padding the easiest thing to<br />

do is to assume there may be an additional block of output. That is, if you pass in 7<br />

bytes, allocating 7 + SPC_BLOCK_SZ is safe. If you wish to be a bit more precise, you<br />

can always add SPC_BLOCK_SZ bytes to the input length, then reduce the number to<br />

the next block-aligned size. For example, if we have an 8-byte block, and we call spc_<br />

cbc_encrypt_update( ) with 7 bytes, there is no way to get more than 8 bytes of output,<br />

no matter how much data was buffered internally. Note that if no data was buffered<br />

internally, we won’t get any output!<br />

Of course, you can exactly determine the amount of data to pass in if you are keeping<br />

track of how many bytes are buffered at any given time (which you can do by<br />

looking at ctx->ix). If you do that, add the buffered length to your input length. The<br />

amount of output is always the largest block-aligned value less than or equal to this<br />

total length.<br />

If you’re not using padding, you will get a block of output for every block of input.<br />

To switch off padding, you can call the following function, passing in a 0 for the second<br />

argument:<br />

void spc_cbc_set_padding(SPC_CBC_CTX *ctx, int pad) {<br />

ctx->pad = pad;<br />

}<br />

Here’s our implementation of spc_cbc_encrypt_update( ):<br />

int spc_cbc_encrypt_update(SPC_CBC_CTX *ctx, unsigned char *in, size_t il,<br />

unsigned char *out, size_t *ol) {<br />

/* Keep a ptr to in, which we advance; we calculate ol by subtraction later. */<br />

int i;<br />

unsigned char *start = out;<br />

/* If we have leftovers, but not enough to fill a block, XOR them into the right<br />

* places in the IV slot and return. It's not much stuff, so one byte at a time<br />

* is fine.<br />

*/<br />

if (il < SPC_BLOCK_SZ-ctx->ix) {<br />

while (il--) ctx->iv[ctx->ix++] ^= *in++;<br />

if (ol) *ol = 0;<br />

return 1;<br />

}<br />

/* If we did have leftovers, and we're here, fill up a block then output the<br />

* ciphertext.<br />

Using a Generic CBC Mode Implementation | 181<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!