Skip to content

Commit 34701d6

Browse files
authored
Throw InvalidKeyException on inappropriate keyLength argument (#115)
1 parent dd65a52 commit 34701d6

File tree

14 files changed

+182
-26
lines changed

14 files changed

+182
-26
lines changed

library/blake2/src/commonMain/kotlin/org/kotlincrypto/hash/blake2/BLAKE2Digest.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import org.kotlincrypto.bitops.endian.Endian.Little.leIntAt
2222
import org.kotlincrypto.bitops.endian.Endian.Little.leLongAt
2323
import org.kotlincrypto.bitops.endian.Endian.Little.lePackIntoUnsafe
2424
import org.kotlincrypto.core.digest.Digest
25+
import org.kotlincrypto.error.InvalidKeyException
2526
import org.kotlincrypto.error.InvalidParameterException
2627
import org.kotlincrypto.error.requireParam
2728
import org.kotlincrypto.hash.blake2.internal.*
@@ -72,7 +73,7 @@ public sealed class BLAKE2Digest: Digest {
7273
private var m: Bit32Message?
7374
private val t: Counter.Bit32
7475

75-
@Throws(InvalidParameterException::class)
76+
@Throws(InvalidKeyException::class, InvalidParameterException::class)
7677
protected constructor(
7778
variant: String,
7879
bitStrength: Int,
@@ -333,7 +334,7 @@ public sealed class BLAKE2Digest: Digest {
333334
private var m: Bit64Message?
334335
private val t: Counter.Bit64
335336

336-
@Throws(InvalidParameterException::class)
337+
@Throws(InvalidKeyException::class, InvalidParameterException::class)
337338
protected constructor(
338339
variant: String,
339340
bitStrength: Int,
@@ -580,7 +581,7 @@ public sealed class BLAKE2Digest: Digest {
580581
}
581582

582583
// BLAKE2Digest
583-
@Throws(InvalidParameterException::class)
584+
@Throws(InvalidKeyException::class, InvalidParameterException::class)
584585
private constructor(
585586
variant: String,
586587
blockSize: Int,
@@ -609,7 +610,9 @@ public sealed class BLAKE2Digest: Digest {
609610
// s: 64 / 2 = 32
610611
// b: 128 / 2 = 64
611612
(blockSize / 2).let { size ->
612-
requireParam(keyLength in 0..size) { "keyLength must be between 0 and $size (inclusive)" }
613+
if (keyLength !in 0..size) {
614+
throw InvalidKeyException("keyLength must be between 0 and $size (inclusive)")
615+
}
613616
requireParam(innerLength in 0..size) { "innerLength must be between 0 and $size (inclusive)" }
614617
}
615618

library/blake2/src/commonMain/kotlin/org/kotlincrypto/hash/blake2/BLAKE2b.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.kotlincrypto.hash.blake2
1717

1818
import org.kotlincrypto.core.InternalKotlinCryptoApi
19+
import org.kotlincrypto.error.InvalidKeyException
1920
import org.kotlincrypto.error.InvalidParameterException
2021

2122
/**
@@ -84,10 +85,11 @@ public class BLAKE2b: BLAKE2Digest.Bit64 {
8485
* - [bitStrength] is less than 8
8586
* - [bitStrength] is greater than 512
8687
* - [bitStrength] is not a factor of 8
87-
* - [keyLength] is less than 0
88-
* - [keyLength] is greater than 64
8988
* - [salt] is non-null and not exactly 16 bytes in length
9089
* - [personalization] is non-null and not exactly 16 bytes in length
90+
* @throws [InvalidKeyException] when:
91+
* - [keyLength] is less than 0
92+
* - [keyLength] is greater than 64
9193
*
9294
* @suppress
9395
* */
@@ -109,7 +111,7 @@ public class BLAKE2b: BLAKE2Digest.Bit64 {
109111

110112
public override fun copy(): BLAKE2b = BLAKE2b(this)
111113

112-
@Throws(InvalidParameterException::class)
114+
@Throws(InvalidKeyException::class, InvalidParameterException::class)
113115
private constructor(
114116
bitStrength: Int,
115117
keyLength: Int,

library/blake2/src/commonMain/kotlin/org/kotlincrypto/hash/blake2/BLAKE2s.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.kotlincrypto.hash.blake2
1919

2020
import org.kotlincrypto.core.InternalKotlinCryptoApi
21+
import org.kotlincrypto.error.InvalidKeyException
2122
import org.kotlincrypto.error.InvalidParameterException
2223

2324
/**
@@ -86,10 +87,11 @@ public class BLAKE2s: BLAKE2Digest.Bit32 {
8687
* - [bitStrength] is less than 8
8788
* - [bitStrength] is greater than 256
8889
* - [bitStrength] is not a factor of 8
89-
* - [keyLength] is less than 0
90-
* - [keyLength] is greater than 32
9190
* - [salt] is non-null and not exactly 8 bytes in length
9291
* - [personalization] is non-null and not exactly 8 bytes in length
92+
* @throws [InvalidKeyException] when:
93+
* - [keyLength] is less than 0
94+
* - [keyLength] is greater than 32
9395
*
9496
* @suppress
9597
* */
@@ -111,7 +113,7 @@ public class BLAKE2s: BLAKE2Digest.Bit32 {
111113

112114
public override fun copy(): BLAKE2s = BLAKE2s(this)
113115

114-
@Throws(InvalidParameterException::class)
116+
@Throws(InvalidKeyException::class, InvalidParameterException::class)
115117
private constructor(
116118
bitStrength: Int,
117119
keyLength: Int,
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (c) 2025 KotlinCrypto
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
**/
16+
package org.kotlincrypto.hash.blake2
17+
18+
import org.kotlincrypto.core.InternalKotlinCryptoApi
19+
import org.kotlincrypto.error.InvalidKeyException
20+
import org.kotlincrypto.error.InvalidParameterException
21+
import kotlin.test.Test
22+
import kotlin.test.assertFailsWith
23+
24+
@OptIn(InternalKotlinCryptoApi::class)
25+
class BLAKE2bUnitTest {
26+
27+
@Test
28+
fun givenBLAKE2bDigest_whenInvalidBitStrength_thenThrowsException() {
29+
assertFailsWith<InvalidParameterException> { BLAKE2b(8 - 8) }
30+
assertFailsWith<InvalidParameterException> { BLAKE2b(8 - 1) }
31+
assertFailsWith<InvalidParameterException> { BLAKE2b(512 + 8) }
32+
assertFailsWith<InvalidParameterException> { BLAKE2b(512 + 1) }
33+
}
34+
35+
@Test
36+
fun givenBLAKE2bDigest_whenInvalidPersonalization_thenThrowsException() {
37+
// Checks assertion parameters used for non-personalization arguments are valid
38+
BLAKE2b(512, ByteArray(16))
39+
assertFailsWith<InvalidParameterException> { BLAKE2b(512, ByteArray(16 - 1)) }
40+
}
41+
42+
@Test
43+
fun givenBLAKE2bDigest_whenInvalidSalt_thenThrowsException() {
44+
// Checks assertion parameters used for non-salt arguments are valid
45+
BLAKE2b(512, 0, salt = ByteArray(16), null)
46+
assertFailsWith<InvalidParameterException> { BLAKE2b(512, 0, salt = ByteArray(16 -1), null) }
47+
}
48+
49+
@Test
50+
fun givenBLAKE2bDigest_whenInvalidKeyLength_thenThrowsException() {
51+
// Checks assertion parameters used for non keyLength arguments are valid
52+
BLAKE2b(512, 0, null, null)
53+
assertFailsWith<InvalidKeyException> { BLAKE2b(512, 0 - 1, null, null) }
54+
assertFailsWith<InvalidKeyException> { BLAKE2b(512, 64 + 1, null, null) }
55+
}
56+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (c) 2025 KotlinCrypto
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
**/
16+
package org.kotlincrypto.hash.blake2
17+
18+
import org.kotlincrypto.core.InternalKotlinCryptoApi
19+
import org.kotlincrypto.error.InvalidKeyException
20+
import org.kotlincrypto.error.InvalidParameterException
21+
import kotlin.test.Test
22+
import kotlin.test.assertFailsWith
23+
24+
@OptIn(InternalKotlinCryptoApi::class)
25+
class BLAKE2sUnitTest {
26+
27+
@Test
28+
fun givenBLAKE2sDigest_whenInvalidBitStrength_thenThrowsException() {
29+
assertFailsWith<InvalidParameterException> { BLAKE2s(8 - 8) }
30+
assertFailsWith<InvalidParameterException> { BLAKE2s(8 - 1) }
31+
assertFailsWith<InvalidParameterException> { BLAKE2s(256 + 8) }
32+
assertFailsWith<InvalidParameterException> { BLAKE2s(256 + 1) }
33+
}
34+
35+
@Test
36+
fun givenBLAKE2sDigest_whenInvalidPersonalization_thenThrowsException() {
37+
// Checks assertion parameters used for non-personalization arguments are valid
38+
BLAKE2s(256, ByteArray(8))
39+
assertFailsWith<InvalidParameterException> { BLAKE2s(256, ByteArray(8 - 1)) }
40+
}
41+
42+
@Test
43+
fun givenBLAKE2sDigest_whenInvalidSalt_thenThrowsException() {
44+
// Checks assertion parameters used for non-salt arguments are valid
45+
BLAKE2s(256, 0, salt = ByteArray(8), null)
46+
assertFailsWith<InvalidParameterException> { BLAKE2s(256, 0, salt = ByteArray(8 -1), null) }
47+
}
48+
49+
@Test
50+
fun givenBLAKE2sDigest_whenInvalidKeyLength_thenThrowsException() {
51+
// Checks assertion parameters used for non keyLength arguments are valid
52+
BLAKE2s(256, 0, null, null)
53+
assertFailsWith<InvalidKeyException> { BLAKE2s(256, 0 - 1, null, null) }
54+
assertFailsWith<InvalidKeyException> { BLAKE2s(256, 32 + 1, null, null) }
55+
}
56+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2025 KotlinCrypto
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
**/
16+
package org.kotlincrypto.hash.sha2
17+
18+
import org.kotlincrypto.error.InvalidParameterException
19+
import kotlin.test.Test
20+
import kotlin.test.assertFailsWith
21+
22+
class SHA512tUnitTest {
23+
24+
@Test
25+
fun givenSHA512tDigest_whenInvalidBitStrength_thenThrowsException() {
26+
assertFailsWith<InvalidParameterException> { SHA512t(-1) }
27+
assertFailsWith<InvalidParameterException> { SHA512t(384) }
28+
assertFailsWith<InvalidParameterException> { SHA512t(512) }
29+
assertFailsWith<InvalidParameterException> { SHA512t(512 - 8 + 1) }
30+
}
31+
}

library/sha3/src/commonMain/kotlin/org/kotlincrypto/hash/sha3/CSHAKE128.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public class CSHAKE128: SHAKEDigest {
5555
* of the function. When no customization is desired, [S] is set to an
5656
* empty or null value. (e.g. "My Customization".encodeToByteArray())
5757
* @param [outputLength] The number of bytes returned when [digest] is invoked
58+
*
5859
* @throws [InvalidParameterException] If [outputLength] is negative
5960
* */
6061
public constructor(

library/sha3/src/commonMain/kotlin/org/kotlincrypto/hash/sha3/CSHAKE256.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public class CSHAKE256: SHAKEDigest {
5555
* of the function. When no customization is desired, [S] is set to an
5656
* empty or null value. (e.g. "My Customization".encodeToByteArray())
5757
* @param [outputLength] The number of bytes returned when [digest] is invoked
58+
*
5859
* @throws [InvalidParameterException] If [outputLength] is negative
5960
* */
6061
public constructor(

library/sha3/src/commonMain/kotlin/org/kotlincrypto/hash/sha3/ParallelHash128.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class ParallelHash128: ParallelDigest {
3939
* of the function. When no customization is desired, [S] is set to an
4040
* empty or null value. (e.g. "My Customization".encodeToByteArray())
4141
* @param [B] The block size for the inner hash function in bytes
42+
*
4243
* @throws [InvalidParameterException] If [B] is less than 1
4344
* */
4445
public constructor(
@@ -55,6 +56,7 @@ public class ParallelHash128: ParallelDigest {
5556
* empty or null value. (e.g. "My Customization".encodeToByteArray())
5657
* @param [B] The block size for the inner hash function in bytes
5758
* @param [outputLength] The number of bytes returned when [digest] is invoked
59+
*
5860
* @throws [InvalidParameterException] If [B] is less than 1, or [outputLength] is negative
5961
* */
6062
public constructor(
@@ -87,6 +89,7 @@ public class ParallelHash128: ParallelDigest {
8789
* Produces a new [Xof] (Extendable-Output Function) for [ParallelHash128]
8890
*
8991
* @param [B] The block size for the inner hash function in bytes
92+
*
9093
* @throws [InvalidParameterException] If [B] is less than 1
9194
* */
9295
@JvmStatic
@@ -99,6 +102,7 @@ public class ParallelHash128: ParallelDigest {
99102
* of the function. When no customization is desired, [S] is set to an
100103
* empty or null value. (e.g. "My Customization".encodeToByteArray())
101104
* @param [B] The block size for the inner hash function in bytes
105+
*
102106
* @throws [InvalidParameterException] If [B] is less than 1
103107
* */
104108
@JvmStatic

library/sha3/src/commonMain/kotlin/org/kotlincrypto/hash/sha3/ParallelHash256.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class ParallelHash256: ParallelDigest {
3939
* of the function. When no customization is desired, [S] is set to an
4040
* empty or null value. (e.g. "My Customization".encodeToByteArray())
4141
* @param [B] The block size for the inner hash function in bytes
42+
*
4243
* @throws [InvalidParameterException] If [B] is less than 1
4344
* */
4445
public constructor(
@@ -55,6 +56,7 @@ public class ParallelHash256: ParallelDigest {
5556
* empty or null value. (e.g. "My Customization".encodeToByteArray())
5657
* @param [B] The block size for the inner hash function in bytes
5758
* @param [outputLength] The number of bytes returned when [digest] is invoked
59+
*
5860
* @throws [InvalidParameterException] If [B] is less than 1, or [outputLength] is negative
5961
* */
6062
public constructor(
@@ -87,6 +89,7 @@ public class ParallelHash256: ParallelDigest {
8789
* Produces a new [Xof] (Extendable-Output Function) for [ParallelHash256]
8890
*
8991
* @param [B] The block size for the inner hash function in bytes
92+
*
9093
* @throws [InvalidParameterException] If [B] is less than 1
9194
* */
9295
@JvmStatic
@@ -99,6 +102,7 @@ public class ParallelHash256: ParallelDigest {
99102
* of the function. When no customization is desired, [S] is set to an
100103
* empty or null value. (e.g. "My Customization".encodeToByteArray())
101104
* @param [B] The block size for the inner hash function in bytes
105+
*
102106
* @throws [InvalidParameterException] If [B] is less than 1
103107
* */
104108
@JvmStatic

library/sha3/src/commonMain/kotlin/org/kotlincrypto/hash/sha3/SHAKE128.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,15 @@ import kotlin.jvm.JvmStatic
3030
public class SHAKE128: SHAKEDigest {
3131

3232
/**
33-
* Creates a new [SHAKE128] [Digest] instance with a default output
34-
* length of 32 bytes.
33+
* Creates a new [SHAKE128] [Digest] instance with a default output length of 32 bytes.
3534
* */
3635
public constructor(): this(DIGEST_LENGTH_BIT_128)
3736

3837
/**
39-
* Creates a new [SHAKE128] [Digest] instance with a non-default output
40-
* length.
38+
* Creates a new [SHAKE128] [Digest] instance with a non-default output length.
4139
*
4240
* @param [outputLength] The number of bytes returned when [digest] is invoked
41+
*
4342
* @throws [InvalidParameterException] If [outputLength] is negative
4443
* */
4544
public constructor(

library/sha3/src/commonMain/kotlin/org/kotlincrypto/hash/sha3/SHAKE256.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,15 @@ import kotlin.jvm.JvmStatic
3030
public class SHAKE256: SHAKEDigest {
3131

3232
/**
33-
* Creates a new [SHAKE256] [Digest] instance with a default output
34-
* length of 64 bytes.
33+
* Creates a new [SHAKE256] [Digest] instance with a default output length of 64 bytes.
3534
* */
3635
public constructor(): this(DIGEST_LENGTH_BIT_256)
3736

3837
/**
39-
* Creates a new [SHAKE256] [Digest] instance with a non-default output
40-
* length.
38+
* Creates a new [SHAKE256] [Digest] instance with a non-default output length.
4139
*
4240
* @param [outputLength] The number of bytes returned when [digest] is invoked
41+
*
4342
* @throws [InvalidParameterException] If [outputLength] is negative
4443
* */
4544
public constructor(

library/sha3/src/commonMain/kotlin/org/kotlincrypto/hash/sha3/TupleHash128.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ import kotlin.jvm.JvmStatic
3232
public class TupleHash128: TupleDigest {
3333

3434
/**
35-
* Creates a new [TupleHash128] [Digest] instance with a default output
36-
* length of 32 bytes.
35+
* Creates a new [TupleHash128] [Digest] instance with a default output length of 32 bytes.
3736
*
3837
* @param [S] A user selected customization bit string to define a variant
3938
* of the function. When no customization is desired, [S] is set to an
@@ -42,13 +41,13 @@ public class TupleHash128: TupleDigest {
4241
public constructor(S: ByteArray?): this(S, DIGEST_LENGTH_BIT_128)
4342

4443
/**
45-
* Creates a new [TupleHash128] [Digest] instance with a non-default output
46-
* length.
44+
* Creates a new [TupleHash128] [Digest] instance with a non-default output length.
4745
*
4846
* @param [S] A user selected customization bit string to define a variant
4947
* of the function. When no customization is desired, [S] is set to an
5048
* empty or null value. (e.g. "My Customization".encodeToByteArray())
5149
* @param [outputLength] The number of bytes returned when [digest] is invoked
50+
*
5251
* @throws [InvalidParameterException] If [outputLength] is negative
5352
* */
5453
public constructor(

0 commit comments

Comments
 (0)