authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2020-10-05 23:50:38+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2020-10-05 23:50:38+02:00
logd343b75e7fa11d94e9668fb306b9e6b2ba68a0da
tree01171c58d9aec7ec9e7e314f8bef4a1b630fe734
parent7f7e2d608adb81cd00e54fd7fe5e7035a890565f

ghash & poly1305: fix handling of partial blocks and add pad()

pad() aligns the next input to the first byte of a block, which is useful to implement the IETF version of ChaCha20Poly1305 and AES-GCM.

2 files changed, 29 insertions(+), 9 deletions(-)

lib/std/crypto/ghash.zig+15-8
...@@ -250,7 +250,7 @@ pub const Ghash = struct {...@@ -250,7 +250,7 @@ pub const Ghash = struct {
250 }250 }
251 mb = mb[want..];251 mb = mb[want..];
252 st.leftover += want;252 st.leftover += want;
253 if (st.leftover > block_size) {253 if (st.leftover < block_size) {
254 return;254 return;
255 }255 }
256 st.blocks(&st.buf);256 st.blocks(&st.buf);
...@@ -269,14 +269,21 @@ pub const Ghash = struct {...@@ -269,14 +269,21 @@ pub const Ghash = struct {
269 }269 }
270 }270 }
271271
272 pub fn final(st: *Ghash, out: *[mac_length]u8) void {272 /// Zero-pad to align the next input to the first byte of a block
273 if (st.leftover > 0) {273 pub fn pad(st: *Ghash) void {
274 var i = st.leftover;274 if (st.leftover == 0) {
275 while (i < block_size) : (i += 1) {275 return;
276 st.buf[i] = 0;
277 }
278 st.blocks(&st.buf);
279 }276 }
277 var i = st.leftover;
278 while (i < block_size) : (i += 1) {
279 st.buf[i] = 0;
280 }
281 st.blocks(&st.buf);
282 st.leftover = 0;
283 }
284
285 pub fn final(st: *Ghash, out: *[mac_length]u8) void {
286 st.pad();
280 mem.writeIntBig(u64, out[0..8], st.y1);287 mem.writeIntBig(u64, out[0..8], st.y1);
281 mem.writeIntBig(u64, out[8..16], st.y0);288 mem.writeIntBig(u64, out[8..16], st.y0);
282289
lib/std/crypto/poly1305.zig+14-1
...@@ -91,7 +91,7 @@ pub const Poly1305 = struct {...@@ -91,7 +91,7 @@ pub const Poly1305 = struct {
91 }91 }
92 mb = mb[want..];92 mb = mb[want..];
93 st.leftover += want;93 st.leftover += want;
94 if (st.leftover > block_size) {94 if (st.leftover < block_size) {
95 return;95 return;
96 }96 }
97 st.blocks(&st.buf, false);97 st.blocks(&st.buf, false);
...@@ -114,6 +114,19 @@ pub const Poly1305 = struct {...@@ -114,6 +114,19 @@ pub const Poly1305 = struct {
114 }114 }
115 }115 }
116116
117 /// Zero-pad to align the next input to the first byte of a block
118 pub fn pad(st: *Poly1305) void {
119 if (st.leftover == 0) {
120 return;
121 }
122 var i = st.leftover;
123 while (i < block_size) : (i += 1) {
124 st.buf[i] = 0;
125 }
126 st.blocks(&st.buf);
127 st.leftover = 0;
128 }
129
117 pub fn final(st: *Poly1305, out: *[mac_length]u8) void {130 pub fn final(st: *Poly1305, out: *[mac_length]u8) void {
118 if (st.leftover > 0) {131 if (st.leftover > 0) {
119 var i = st.leftover;132 var i = st.leftover;