Skip to content

Commit a0b65f2

Browse files
authored
Fix hmac size block template issue (#82)
* Add one more check. * Distribute hmacSizeBlock() to implementations, eliminate dependency on hashes for HMAC code. * Bump nimble file version.
1 parent 71bca15 commit a0b65f2

11 files changed

+52
-39
lines changed

nimcrypto.nimble

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Package
22

3-
version = "0.6.0"
3+
version = "0.6.1"
44
author = "Eugene Kabanov"
55
description = "Nim cryptographic library"
66
license = "MIT"

nimcrypto/blake2.nim

+5
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,11 @@ template sizeBlock*(r: typedesc[blake2]): int =
283283
else:
284284
(128)
285285

286+
template hmacSizeBlock*(r: typedesc[blake2]): int =
287+
## Size of processing block in octets (bytes), while perform HMAC[blake2]
288+
## operation.
289+
r.sizeBlock
290+
286291
proc init*[T: bchar](ctx: var Blake2Context, key: openArray[T]) {.inline.} =
287292
when ctx is Blake2sContext:
288293
when nimvm:

nimcrypto/hash.nim

-3
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ else:
6666
## Message digest type
6767
data*: array[bits div 8, byte]
6868

69-
type
70-
bchar* = byte | char
71-
7269
proc `$`*(digest: MDigest): string =
7370
## Return hexadecimal string representation of ``digest``.
7471
##

nimcrypto/hmac.nim

+13-31
Original file line numberDiff line numberDiff line change
@@ -55,29 +55,7 @@
5555
## # 18AF7C8586141A47EAAD416C2B356431D001FAFF3B8C98C80AA108DC971B230D
5656
## # 18AF7C8586141A47EAAD416C2B356431D001FAFF3B8C98C80AA108DC971B230D
5757
## # 18AF7C8586141A47EAAD416C2B356431D001FAFF3B8C98C80AA108DC971B230D
58-
import utils
59-
import sha, sha2, ripemd, keccak, blake2, hash
60-
export sha, sha2, ripemd, keccak, blake2, hash
61-
62-
template hmacSizeBlock*(h: typedesc): int =
63-
mixin sizeBlock
64-
when (h is Sha1Context) or (h is Sha2Context) or (h is RipemdContext) or
65-
(h is Blake2Context):
66-
int(h.sizeBlock)
67-
elif h is KeccakContext:
68-
when h.kind == Keccak or h.kind == Sha3:
69-
when h.bits == 224:
70-
144
71-
elif h.bits == 256:
72-
136
73-
elif h.bits == 384:
74-
104
75-
elif h.bits == 512:
76-
72
77-
else:
78-
{.fatal: "Choosen hash primitive is not yet supported!".}
79-
else:
80-
{.fatal: "Choosen hash primitive is not yet supported!".}
58+
import hash, utils
8159

8260
type
8361
HMAC*[HashType] = object
@@ -136,6 +114,7 @@ proc init*[T](hmctx: var HMAC[T], key: ptr byte, keylen: uint) =
136114
proc clear*(hmctx: var HMAC) =
137115
## Clear HMAC context ``hmctx``.
138116
when nimvm:
117+
mixin clear
139118
hmctx.mdctx.clear()
140119
hmctx.opadctx.clear()
141120
for i in 0 ..< len(hmctx.ipad):
@@ -199,18 +178,21 @@ proc finish*[T: bchar](hmctx: var HMAC,
199178
## ``data``. ``data`` length must be at least ``hmctx.sizeDigest`` octets
200179
## (bytes).
201180
mixin update, finish
202-
if len(data) >= int(hmctx.sizeDigest):
203-
var buffer: array[hmctx.sizeDigest, byte]
204-
discard finish(hmctx.mdctx, buffer)
205-
hmctx.opadctx.update(buffer)
206-
result = hmctx.opadctx.finish(data)
181+
if len(data) < int(hmctx.sizeDigest):
182+
return 0'u
183+
184+
var buffer: array[hmctx.sizeDigest, byte]
185+
discard finish(hmctx.mdctx, buffer)
186+
hmctx.opadctx.update(buffer)
187+
hmctx.opadctx.finish(data)
188+
207189

208190
proc finish*(hmctx: var HMAC, pbytes: ptr byte, nbytes: uint): uint {.inline.} =
209191
## Finalize HMAC context ``hmctx`` and store calculated digest to address
210192
## pointed by ``pbytes`` of length ``nbytes``. ``pbytes`` must be able to
211193
## hold at ``hmctx.sizeDigest`` octets (bytes).
212194
var ptrarr = cast[ptr UncheckedArray[byte]](pbytes)
213-
result = hmctx.finish(ptrarr.toOpenArray(0, int(nbytes) - 1))
195+
hmctx.finish(ptrarr.toOpenArray(0, int(nbytes) - 1))
214196

215197
proc finish*(hmctx: var HMAC): MDigest[hmctx.HashType.bits] =
216198
## Finalize HMAC context ``hmctx`` and return calculated digest as
@@ -270,5 +252,5 @@ proc hmac*(HashType: typedesc, key: ptr byte, klen: uint,
270252
## echo ripemd160.hmac(key, keylen, data, datalen)
271253
var keyarr = cast[ptr UncheckedArray[byte]](key)
272254
var dataarr = cast[ptr UncheckedArray[byte]](data)
273-
result = hmac(HashType, keyarr.toOpenArray(0, int(klen) - 1),
274-
dataarr.toOpenArray(0, int(ulen) - 1))
255+
hmac(HashType, keyarr.toOpenArray(0, int(klen) - 1),
256+
dataarr.toOpenArray(0, int(ulen) - 1))

nimcrypto/keccak.nim

+14
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,20 @@ template sizeDigest*(r: typedesc[keccak | shake128 | shake256]): int =
348348
template sizeBlock*(r: typedesc[keccak | shake128 | shake256]): int =
349349
(200)
350350

351+
template hmacSizeBlock*(r: typedesc[keccak]): int =
352+
## Size of processing block in octets (bytes), while perform HMAC[keccak]
353+
## operation.
354+
when r.bits == 224:
355+
144
356+
elif r.bits == 256:
357+
136
358+
elif r.bits == 384:
359+
104
360+
elif r.bits == 512:
361+
72
362+
else:
363+
{.fatal: "Choosen hash primitive is not supported!".}
364+
351365
proc init*(ctx: var KeccakContext) {.inline.} =
352366
ctx = type(ctx)()
353367

nimcrypto/ripemd.nim

+5
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,11 @@ template sizeDigest*(r: typedesc[ripemd]): int =
658658
template sizeBlock*(r: typedesc[ripemd]): int =
659659
(64)
660660

661+
template hmacSizeBlock*(r: typedesc[ripemd]): int =
662+
## Size of processing block in octets (bytes), while perform HMAC[ripemd]
663+
## operation.
664+
r.sizeBlock
665+
661666
proc init*(ctx: var RipemdContext) {.inline.} =
662667
ctx.count[0] = 0
663668
ctx.count[1] = 0

nimcrypto/scrypt.nim

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
## This module implements
1111
## The scrypt Password-Based Key Derivation Function
1212
## https://tools.ietf.org/html/rfc7914
13-
import utils, hmac, pbkdf2
13+
import utils, sha2, hmac, pbkdf2
1414
export hmac
1515

1616
proc salsaXor(tmp: var openArray[uint32],

nimcrypto/sha.nim

+5
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ template sizeDigest*(r: typedesc[sha1]): int =
6767
template sizeBlock*(r: typedesc[sha1]): int =
6868
(512 div 8)
6969

70+
template hmacSizeBlock*(r: typedesc[sha1]): int =
71+
## Size of processing block in octets (bytes), while perform HMAC[sha1]
72+
## operation.
73+
r.sizeBlock
74+
7075
proc init*(ctx: var Sha1Context) {.inline.} =
7176
ctx.size = 0'u64
7277
ctx.h[0] = 0x67452301'u32

nimcrypto/sha2.nim

+5
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ template sizeBlock*(r: typedesc[sha2]): int =
129129
else:
130130
(128)
131131

132+
template hmacSizeBlock*(r: typedesc[sha2]): int =
133+
## Size of processing block in octets (bytes), while perform HMAC[sha2]
134+
## operation.
135+
r.sizeBlock
136+
132137
proc init*(ctx: var Sha2Context) {.inline.} =
133138
ctx.count[0] = 0
134139
ctx.count[1] = 0

nimcrypto/utils.nim

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ type
2121
SkipSpaces, ## Skips all the whitespace characters inside of string
2222
SkipPrefix ## Skips `0x` and `x` prefixes at the begining of string
2323

24+
bchar* = byte | char
25+
2426
template ROL*(x: uint32, n: int): uint32 =
2527
(x shl uint32(n and 0x1F)) or (x shr uint32(32 - (n and 0x1F)))
2628

tests/testhmac.nim

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import nimcrypto/hmac, nimcrypto/hash, nimcrypto/utils
2-
import nimcrypto/sha2, nimcrypto/ripemd, nimcrypto/keccak
3-
import nimcrypto/sha
1+
import nimcrypto/[hmac, hash, utils, sha, sha2, ripemd, keccak]
42
import unittest
53

64
when defined(nimHasUsed): {.used.}

0 commit comments

Comments
 (0)