Initial commit
[authen-passphrase-scrypt.git] / scrypt-1.2.1 / libcperciva / crypto / crypto_aesctr.c
1 #include <stdint.h>
2 #include <stdlib.h>
3
4 #include "crypto_aes.h"
5 #include "insecure_memzero.h"
6 #include "sysendian.h"
7
8 #include "crypto_aesctr.h"
9
10 struct crypto_aesctr {
11 const struct crypto_aes_key * key;
12 uint64_t nonce;
13 uint64_t bytectr;
14 uint8_t buf[16];
15 };
16
17 /**
18 * crypto_aesctr_init(key, nonce):
19 * Prepare to encrypt/decrypt data with AES in CTR mode, using the provided
20 * expanded key and nonce. The key provided must remain valid for the
21 * lifetime of the stream.
22 */
23 struct crypto_aesctr *
24 crypto_aesctr_init(const struct crypto_aes_key * key, uint64_t nonce)
25 {
26 struct crypto_aesctr * stream;
27
28 /* Allocate memory. */
29 if ((stream = malloc(sizeof(struct crypto_aesctr))) == NULL)
30 goto err0;
31
32 /* Initialize values. */
33 stream->key = key;
34 stream->nonce = nonce;
35 stream->bytectr = 0;
36
37 /* Success! */
38 return (stream);
39
40 err0:
41 /* Failure! */
42 return (NULL);
43 }
44
45 /**
46 * crypto_aesctr_stream(stream, inbuf, outbuf, buflen):
47 * Generate the next ${buflen} bytes of the AES-CTR stream and xor them with
48 * bytes from ${inbuf}, writing the result into ${outbuf}. If the buffers
49 * ${inbuf} and ${outbuf} overlap, they must be identical.
50 */
51 void
52 crypto_aesctr_stream(struct crypto_aesctr * stream, const uint8_t * inbuf,
53 uint8_t * outbuf, size_t buflen)
54 {
55 uint8_t pblk[16];
56 size_t pos;
57 int bytemod;
58
59 for (pos = 0; pos < buflen; pos++) {
60 /* How far through the buffer are we? */
61 bytemod = stream->bytectr % 16;
62
63 /* Generate a block of cipherstream if needed. */
64 if (bytemod == 0) {
65 be64enc(pblk, stream->nonce);
66 be64enc(pblk + 8, stream->bytectr / 16);
67 crypto_aes_encrypt_block(pblk, stream->buf,
68 stream->key);
69 }
70
71 /* Encrypt a byte. */
72 outbuf[pos] = inbuf[pos] ^ stream->buf[bytemod];
73
74 /* Move to the next byte of cipherstream. */
75 stream->bytectr += 1;
76 }
77 }
78
79 /**
80 * crypto_aesctr_free(stream):
81 * Free the provided stream object.
82 */
83 void
84 crypto_aesctr_free(struct crypto_aesctr * stream)
85 {
86
87 /* Behave consistently with free(NULL). */
88 if (stream == NULL)
89 return;
90
91 /* Zero potentially sensitive information. */
92 insecure_memzero(stream, sizeof(struct crypto_aesctr));
93
94 /* Free the stream. */
95 free(stream);
96 }
97
98 /**
99 * crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen):
100 * Equivalent to _init(key, nonce); _stream(inbuf, outbuf, buflen); _free().
101 */
102 void
103 crypto_aesctr_buf(const struct crypto_aes_key * key, uint64_t nonce,
104 const uint8_t * inbuf, uint8_t * outbuf, size_t buflen)
105 {
106 struct crypto_aesctr stream_rec;
107 struct crypto_aesctr * stream = &stream_rec;
108
109 /* Initialize values. */
110 stream->key = key;
111 stream->nonce = nonce;
112 stream->bytectr = 0;
113
114 /* Perform the encryption. */
115 crypto_aesctr_stream(stream, inbuf, outbuf, buflen);
116
117 /* Zero potentially sensitive information. */
118 insecure_memzero(stream, sizeof(struct crypto_aesctr));
119 }
This page took 0.023913 seconds and 4 git commands to generate.