From 17183c2763d9ce1427af0512142eba7119a707e6 Mon Sep 17 00:00:00 2001 From: Emilio Pavia Date: Mon, 19 Dec 2022 18:08:10 +0100 Subject: [PATCH 1/2] Do not use unsafe code --- Guardian/Generators/OneTimePasswordGenerator.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Guardian/Generators/OneTimePasswordGenerator.swift b/Guardian/Generators/OneTimePasswordGenerator.swift index f14dbe6..52f3352 100644 --- a/Guardian/Generators/OneTimePasswordGenerator.swift +++ b/Guardian/Generators/OneTimePasswordGenerator.swift @@ -82,11 +82,11 @@ struct OneTimePasswordGenerator: TOTP, HOTP { var c = UInt64(counter).bigEndian let buffer = Data(bytes: &c, count: MemoryLayout.size); let digestData = hmac.sign(buffer) - let length = MemoryLayout.size - // digestData.count - 1 will always be >0, because digestData depends on algorythm and can be only 20, 32, or 64. - let offset = Int(digestData[digestData.count - 1] & 0x0f) - // offset is always <=15, length is always 4, so prefix will always be within digestData count. - var hash = digestData.dropFirst(offset).prefix(length).reduce(0, { $0 << 8 | UInt32($1) }) + guard let offset = digestData.last.map({ Int($0 & 0x0f) }), + (offset + 4) < digestData.count else { + return -1 + } + var hash = digestData.dropFirst(offset).prefix(4).reduce(0, { $0 << 8 | UInt32($1) }) hash &= 0x7fffffff hash = hash % UInt32(pow(10, Float(self.parameters.digits))) return Int(hash) From 8b745be19c62127d4a31f37c1e7a506bd83d19a9 Mon Sep 17 00:00:00 2001 From: Emilio Pavia Date: Mon, 19 Dec 2022 18:48:22 +0100 Subject: [PATCH 2/2] Fix code --- Guardian/Generators/OneTimePasswordGenerator.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Guardian/Generators/OneTimePasswordGenerator.swift b/Guardian/Generators/OneTimePasswordGenerator.swift index 52f3352..e70153c 100644 --- a/Guardian/Generators/OneTimePasswordGenerator.swift +++ b/Guardian/Generators/OneTimePasswordGenerator.swift @@ -82,11 +82,12 @@ struct OneTimePasswordGenerator: TOTP, HOTP { var c = UInt64(counter).bigEndian let buffer = Data(bytes: &c, count: MemoryLayout.size); let digestData = hmac.sign(buffer) + let length = MemoryLayout.size guard let offset = digestData.last.map({ Int($0 & 0x0f) }), - (offset + 4) < digestData.count else { - return -1 + (offset + length) < digestData.count else { + return 0 } - var hash = digestData.dropFirst(offset).prefix(4).reduce(0, { $0 << 8 | UInt32($1) }) + var hash = digestData.dropFirst(offset).prefix(length).reduce(0, { $0 << 8 | UInt32($1) }) hash &= 0x7fffffff hash = hash % UInt32(pow(10, Float(self.parameters.digits))) return Int(hash)