Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions nimcrypto/sha2/sha2.nim
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ func reset*(ctx: var Sha2Context) {.noinit.} =
ctx.state[6] = 0x2B0199FC2C85B8AA'u64
ctx.state[7] = 0x0EB72DDC81C52CA2'u64

template checkContext(ctx: var Sha2Context) =
doAssert(not(isNil(ctx.compressFunc)),
"Context should be initialized first!")

func getCompressFunction(
Sha2ContextType: typedesc[sha224|sha256],
implementation: Sha2Implementation,
Expand Down Expand Up @@ -226,6 +230,8 @@ func clear*(ctx: var Sha2Context) {.noinit.} =
burnMem(ctx)

func update*[T: bchar](ctx: var Sha2Context, data: openArray[T]) {.noinit.} =
ctx.checkContext()

var
pos = 0
bytesLeft = len(data)
Expand Down Expand Up @@ -313,6 +319,7 @@ func finalize512(ctx: var Sha2Context) {.inline, noinit.} =

func finish*(ctx: var Sha2Context,
data: var openArray[byte]): uint {.noinit, discardable.} =
ctx.checkContext()
when ctx.bits == 224 and ctx.bsize == 64:
if len(data) >= 28:
finalize256(ctx)
Expand Down
47 changes: 47 additions & 0 deletions tests/testsha2.nim
Original file line number Diff line number Diff line change
Expand Up @@ -915,3 +915,50 @@ suite "SHA2 Tests":
skip()
else:
check sha512.millionAtest2() == stripSpaces(digest1ma512)

test "Uninitialized context update()/finish() crash test":
var
ctx1: sha224
ctx2: sha256
ctx3: sha384
ctx4: sha512
ctx5: sha512_224
ctx6: sha512_256

template doCheckUpdate(a: untyped): untyped =
try:
a.update([0x00'u8])
false
except AssertionDefect:
true
except CatchableError:
false
except Defect:
false

template doCheckFinish(a: untyped): untyped =
try:
var digest: array[64, byte]
let count {.used.} = a.finish(digest)
false
except AssertionDefect:
true
except CatchableError:
false
except Defect:
false

check:
ctx1.doCheckUpdate() == true
ctx2.doCheckUpdate() == true
ctx3.doCheckUpdate() == true
ctx4.doCheckUpdate() == true
ctx5.doCheckUpdate() == true
ctx6.doCheckUpdate() == true
check:
ctx1.doCheckFinish() == true
ctx2.doCheckFinish() == true
ctx3.doCheckFinish() == true
ctx4.doCheckFinish() == true
ctx5.doCheckFinish() == true
ctx6.doCheckFinish() == true