]>
Commit | Line | Data |
---|---|---|
39037602 A |
1 | /* |
2 | * ccmode_siv.h | |
3 | * corecrypto | |
4 | * | |
5 | * Created on 11/13/2015 | |
6 | * | |
7 | * Copyright (c) 2015 Apple Inc. All rights reserved. | |
8 | * | |
9 | */ | |
10 | ||
11 | #ifndef _CORECRYPTO_CCMODE_SIV_H_ | |
12 | #define _CORECRYPTO_CCMODE_SIV_H_ | |
13 | ||
14 | #include <corecrypto/cc.h> | |
15 | #include <corecrypto/ccmode.h> | |
16 | #include <corecrypto/ccmode_impl.h> | |
17 | ||
18 | #include <corecrypto/cccmac.h> | |
19 | ||
20 | /* This provide an implementation of SIV | |
21 | as specified in https://tools.ietf.org/html/rfc5297 | |
22 | also in http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/siv/siv.pdf | |
23 | Counter Mode where IV is based on CMAC | |
24 | */ | |
25 | ||
26 | cc_aligned_struct(16) ccsiv_ctx; | |
27 | ||
28 | struct ccmode_siv { | |
29 | size_t size; /* first argument to ccsiv_ctx_decl(). */ | |
30 | size_t block_size; | |
31 | int (*init)(const struct ccmode_siv *siv, ccsiv_ctx *ctx, | |
32 | size_t key_len, const uint8_t *key); | |
33 | int (*set_nonce)(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in); // could just be ccm with NULL out | |
34 | int (*auth)(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in); // could just be ccm with NULL out | |
35 | int (*crypt)(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in, uint8_t *out); | |
36 | int (*reset)(ccsiv_ctx *ctx); | |
37 | const struct ccmode_cbc *cbc; | |
38 | const struct ccmode_ctr *ctr; | |
39 | }; | |
40 | ||
41 | #define ccsiv_ctx_decl(_size_, _name_) cc_ctx_decl(ccsiv_ctx, _size_, _name_) | |
42 | #define ccsiv_ctx_clear(_size_, _name_) cc_clear(_size_, _name_) | |
43 | ||
44 | // Functions | |
45 | ||
46 | CC_INLINE size_t ccsiv_context_size(const struct ccmode_siv *mode) | |
47 | { | |
48 | return mode->size; | |
49 | } | |
50 | ||
51 | CC_INLINE size_t ccsiv_block_size(const struct ccmode_siv *mode) | |
52 | { | |
53 | return mode->block_size; | |
54 | } | |
55 | ||
56 | CC_INLINE size_t ccsiv_ciphertext_size(const struct ccmode_siv *mode, | |
57 | size_t plaintext_size) | |
58 | { | |
59 | return plaintext_size+mode->cbc->block_size; | |
60 | } | |
61 | ||
62 | CC_INLINE size_t ccsiv_plaintext_size(const struct ccmode_siv *mode, | |
63 | size_t ciphertext_size) | |
64 | { | |
65 | if (ciphertext_size<mode->cbc->block_size) { | |
66 | return 0; // error | |
67 | } | |
68 | return ciphertext_size-mode->cbc->block_size; | |
69 | } | |
70 | ||
71 | // In theory, supported key sizes are 32, 48, 64 bytes | |
72 | // In practice, we only support key size 32 bytes due to cmac limitation | |
73 | CC_INLINE int ccsiv_init(const struct ccmode_siv *mode, ccsiv_ctx *ctx, | |
74 | size_t key_byte_len, const uint8_t *key) | |
75 | { | |
76 | return mode->init(mode, ctx, key_byte_len, key); | |
77 | } | |
78 | ||
79 | // Process nonce. it is actually just an authenticated data | |
80 | CC_INLINE int ccsiv_set_nonce(const struct ccmode_siv *mode, ccsiv_ctx *ctx, | |
81 | size_t nbytes, const uint8_t *in) | |
82 | { | |
83 | return mode->set_nonce(ctx, nbytes, in); | |
84 | } | |
85 | ||
86 | // Process authenticated data. Taken into account for authentication but not | |
87 | // encrypted | |
88 | CC_INLINE int ccsiv_aad(const struct ccmode_siv *mode, ccsiv_ctx *ctx, | |
89 | size_t nbytes, const uint8_t *in) | |
90 | { | |
91 | return mode->auth(ctx, nbytes, in); | |
92 | } | |
93 | ||
94 | // Encryption data. Authenticated and encrypted. | |
95 | // Encrypt/Decrypt can only be called once | |
96 | CC_INLINE int ccsiv_crypt(const struct ccmode_siv *mode, ccsiv_ctx *ctx, | |
97 | size_t nbytes, const uint8_t *in, uint8_t *out) | |
98 | { | |
99 | return mode->crypt(ctx, nbytes, in, out); | |
100 | } | |
101 | ||
102 | // Clear all context for reuse. | |
103 | // Key is clear to avoid leaking it | |
104 | CC_INLINE int ccsiv_reset(const struct ccmode_siv *mode, ccsiv_ctx *ctx) | |
105 | { | |
106 | return mode->reset(ctx); | |
107 | } | |
108 | ||
109 | // One shot with only one vector of adata | |
110 | CC_INLINE int ccsiv_one_shot(const struct ccmode_siv *mode, | |
111 | size_t key_len, const uint8_t *key, | |
112 | unsigned nonce_nbytes, const uint8_t* nonce, | |
113 | unsigned adata_nbytes, const uint8_t* adata, | |
114 | size_t in_nbytes, const uint8_t *in, uint8_t *out) | |
115 | { | |
116 | int rc; | |
117 | ccsiv_ctx_decl(mode->size, ctx); | |
118 | ccsiv_init(mode, ctx, key_len, key); | |
119 | rc=mode->set_nonce(ctx, nonce_nbytes, nonce); | |
120 | if (rc) {return rc;} | |
121 | rc=mode->auth(ctx, adata_nbytes, adata); | |
122 | if (rc) {return rc;} | |
123 | rc=mode->crypt(ctx, in_nbytes, in, out); | |
124 | if (rc) {return rc;} | |
125 | ccsiv_ctx_clear(mode->size, ctx); | |
126 | return rc; | |
127 | } | |
128 | ||
129 | void ccmode_factory_siv_encrypt(struct ccmode_siv *siv, | |
130 | const struct ccmode_cbc *cbc, | |
131 | const struct ccmode_ctr *ctr); | |
132 | ||
133 | void ccmode_factory_siv_decrypt(struct ccmode_siv *siv, | |
134 | const struct ccmode_cbc *cbc, | |
135 | const struct ccmode_ctr *ctr); | |
136 | ||
137 | ||
138 | #endif /* _CORECRYPTO_CCMODE_H_ */ |