Added _kdf_ all implementations and a simple and probably pointless test, also noted which functions are not available as they are not part of LazySodium
This commit is contained in:
parent
5c387545ab
commit
8b26764938
@ -0,0 +1,33 @@
|
|||||||
|
package com.ionspin.kotlin.crypto.kdf
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 16/Sep/2020
|
||||||
|
*/
|
||||||
|
const val crypto_kdf_PRIMITIVE = "blake2b"
|
||||||
|
const val crypto_kdf_BYTES_MIN = 16
|
||||||
|
const val crypto_kdf_BYTES_MAX = 64
|
||||||
|
const val crypto_kdf_CONTEXTBYTES = 8
|
||||||
|
const val crypto_kdf_KEYBYTES = 32
|
||||||
|
|
||||||
|
expect object Kdf {
|
||||||
|
/**
|
||||||
|
* The crypto_kdf_derive_from_key() function derives a subkey_id-th subkey subkey of length subkey_len bytes using
|
||||||
|
* the master key key and the context ctx.
|
||||||
|
* subkey_id can be any value up to (2^64)-1.
|
||||||
|
* subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive).
|
||||||
|
* Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for.
|
||||||
|
* Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but
|
||||||
|
* in two distinct contexts is likely to generate two different outputs.
|
||||||
|
* Contexts don't have to be secret and can have a low entropy.
|
||||||
|
* Examples of contexts include UserName, __auth__, pictures and userdata.
|
||||||
|
* They must be crypto_kdf_CONTEXTBYTES bytes long.
|
||||||
|
* If more convenient, it is also fine to use a single global context for a whole application. This will still
|
||||||
|
* prevent the same keys from being mistakenly used by another application.
|
||||||
|
*/
|
||||||
|
fun deriveFromKey(subkeyId: Int, subkeyLength: Int, context: String, masterKey: UByteArray) : UByteArray
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The crypto_kdf_keygen() function creates a master key.
|
||||||
|
*/
|
||||||
|
fun keygen() : UByteArray
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.ionspin.kotlin.crypto.kdf
|
||||||
|
|
||||||
|
import com.ionspin.kotlin.crypto.LibsodiumInitializer
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertFails
|
||||||
|
import kotlin.test.assertFalse
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 16/Sep/2020
|
||||||
|
*/
|
||||||
|
class KdfTest {
|
||||||
|
@Test
|
||||||
|
fun testKdf() {
|
||||||
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
|
val masterKey = Kdf.keygen()
|
||||||
|
val subkey1 = Kdf.deriveFromKey(1, crypto_kdf_BYTES_MAX, "test1234", masterKey)
|
||||||
|
val subkey2 = Kdf.deriveFromKey(2, crypto_kdf_BYTES_MAX, "test1234", masterKey)
|
||||||
|
|
||||||
|
assertTrue {
|
||||||
|
subkey1.size == crypto_kdf_BYTES_MAX &&
|
||||||
|
subkey2.size == crypto_kdf_BYTES_MAX
|
||||||
|
}
|
||||||
|
|
||||||
|
val repeatSubkey1 = Kdf.deriveFromKey(1, crypto_kdf_BYTES_MAX, "test1234", masterKey)
|
||||||
|
assertTrue {
|
||||||
|
subkey1.contentEquals(repeatSubkey1)
|
||||||
|
}
|
||||||
|
assertFalse {
|
||||||
|
subkey1.contentEquals(subkey2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -174,7 +174,15 @@ interface JsSodiumInterface {
|
|||||||
fun crypto_sign_verify_detached(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array) : Boolean
|
fun crypto_sign_verify_detached(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array) : Boolean
|
||||||
|
|
||||||
|
|
||||||
// ---- Sign end
|
// ---- Sign end ----
|
||||||
|
|
||||||
|
|
||||||
|
// ---- KDF ----
|
||||||
|
|
||||||
|
fun crypto_kdf_derive_from_key(subkey_len: UInt, subkeyId : UInt, ctx: String, key: Uint8Array) : Uint8Array
|
||||||
|
fun crypto_kdf_keygen() : Uint8Array
|
||||||
|
|
||||||
|
// ---- KDF end -----
|
||||||
|
|
||||||
//util
|
//util
|
||||||
fun memzero(array: Uint8Array)
|
fun memzero(array: Uint8Array)
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.ionspin.kotlin.crypto.kdf
|
||||||
|
|
||||||
|
import com.ionspin.kotlin.crypto.getSodium
|
||||||
|
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
|
||||||
|
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
|
||||||
|
|
||||||
|
actual object Kdf {
|
||||||
|
/**
|
||||||
|
* The crypto_kdf_derive_from_key() function derives a subkey_id-th subkey subkey of length subkey_len bytes using
|
||||||
|
* the master key key and the context ctx.
|
||||||
|
* subkey_id can be any value up to (2^64)-1.
|
||||||
|
* subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive).
|
||||||
|
* Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for.
|
||||||
|
* Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but
|
||||||
|
* in two distinct contexts is likely to generate two different outputs.
|
||||||
|
* Contexts don't have to be secret and can have a low entropy.
|
||||||
|
* Examples of contexts include UserName, __auth__, pictures and userdata.
|
||||||
|
* They must be crypto_kdf_CONTEXTBYTES bytes long.
|
||||||
|
* If more convenient, it is also fine to use a single global context for a whole application. This will still
|
||||||
|
* prevent the same keys from being mistakenly used by another application.
|
||||||
|
*/
|
||||||
|
actual fun deriveFromKey(
|
||||||
|
subkeyId: Int,
|
||||||
|
subkeyLength: Int,
|
||||||
|
context: String,
|
||||||
|
masterKey: UByteArray
|
||||||
|
): UByteArray {
|
||||||
|
return getSodium().crypto_kdf_derive_from_key(
|
||||||
|
subkeyLength.toUInt(),
|
||||||
|
subkeyId.toUInt(),
|
||||||
|
context,
|
||||||
|
masterKey.toUInt8Array()
|
||||||
|
).toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The crypto_kdf_keygen() function creates a master key.
|
||||||
|
*/
|
||||||
|
actual fun keygen(): UByteArray {
|
||||||
|
return getSodium().crypto_kdf_keygen().toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.ionspin.kotlin.crypto.kdf
|
||||||
|
|
||||||
|
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
|
||||||
|
|
||||||
|
actual object Kdf {
|
||||||
|
/**
|
||||||
|
* The crypto_kdf_derive_from_key() function derives a subkey_id-th subkey subkey of length subkey_len bytes using
|
||||||
|
* the master key key and the context ctx.
|
||||||
|
* subkey_id can be any value up to (2^64)-1.
|
||||||
|
* subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive).
|
||||||
|
* Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for.
|
||||||
|
* Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but
|
||||||
|
* in two distinct contexts is likely to generate two different outputs.
|
||||||
|
* Contexts don't have to be secret and can have a low entropy.
|
||||||
|
* Examples of contexts include UserName, __auth__, pictures and userdata.
|
||||||
|
* They must be crypto_kdf_CONTEXTBYTES bytes long.
|
||||||
|
* If more convenient, it is also fine to use a single global context for a whole application. This will still
|
||||||
|
* prevent the same keys from being mistakenly used by another application.
|
||||||
|
*/
|
||||||
|
actual fun deriveFromKey(
|
||||||
|
subkeyId: Int,
|
||||||
|
subkeyLength: Int,
|
||||||
|
context: String,
|
||||||
|
masterKey: UByteArray
|
||||||
|
): UByteArray {
|
||||||
|
val subkey = UByteArray(subkeyLength)
|
||||||
|
val contextEncoded = context.encodeToByteArray()
|
||||||
|
|
||||||
|
sodium.crypto_kdf_derive_from_key(
|
||||||
|
subkey.asByteArray(),
|
||||||
|
subkeyLength,
|
||||||
|
subkeyId.toLong(),
|
||||||
|
contextEncoded,
|
||||||
|
masterKey.asByteArray()
|
||||||
|
)
|
||||||
|
|
||||||
|
return subkey
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The crypto_kdf_keygen() function creates a master key.
|
||||||
|
*/
|
||||||
|
actual fun keygen(): UByteArray {
|
||||||
|
val masterKey = UByteArray(crypto_kdf_KEYBYTES)
|
||||||
|
sodium.crypto_kdf_keygen(masterKey.asByteArray())
|
||||||
|
return masterKey
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.ionspin.kotlin.crypto.kdf
|
||||||
|
|
||||||
|
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
|
||||||
|
import com.ionspin.kotlin.crypto.util.toPtr
|
||||||
|
import kotlinx.cinterop.addressOf
|
||||||
|
import kotlinx.cinterop.convert
|
||||||
|
import kotlinx.cinterop.pin
|
||||||
|
import libsodium.crypto_kdf_derive_from_key
|
||||||
|
import libsodium.crypto_kdf_keygen
|
||||||
|
|
||||||
|
actual object Kdf {
|
||||||
|
/**
|
||||||
|
* The crypto_kdf_derive_from_key() function derives a subkey_id-th subkey subkey of length subkey_len bytes using
|
||||||
|
* the master key key and the context ctx.
|
||||||
|
* subkey_id can be any value up to (2^64)-1.
|
||||||
|
* subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive).
|
||||||
|
* Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for.
|
||||||
|
* Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but
|
||||||
|
* in two distinct contexts is likely to generate two different outputs.
|
||||||
|
* Contexts don't have to be secret and can have a low entropy.
|
||||||
|
* Examples of contexts include UserName, __auth__, pictures and userdata.
|
||||||
|
* They must be crypto_kdf_CONTEXTBYTES bytes long.
|
||||||
|
* If more convenient, it is also fine to use a single global context for a whole application. This will still
|
||||||
|
* prevent the same keys from being mistakenly used by another application.
|
||||||
|
*/
|
||||||
|
actual fun deriveFromKey(
|
||||||
|
subkeyId: Int,
|
||||||
|
subkeyLength: Int,
|
||||||
|
context: String,
|
||||||
|
masterKey: UByteArray
|
||||||
|
): UByteArray {
|
||||||
|
val subkey = UByteArray(subkeyLength)
|
||||||
|
val contextEncoded = context.encodeToByteArray()
|
||||||
|
|
||||||
|
val contextEncodedAndPinned = contextEncoded.pin()
|
||||||
|
val masterKeyPinned = masterKey.pin()
|
||||||
|
val subkeyPinned = subkey.pin()
|
||||||
|
crypto_kdf_derive_from_key(
|
||||||
|
subkeyPinned.toPtr(),
|
||||||
|
subkeyLength.convert(),
|
||||||
|
subkeyId.convert(),
|
||||||
|
contextEncodedAndPinned.addressOf(0),
|
||||||
|
masterKeyPinned.toPtr()
|
||||||
|
)
|
||||||
|
|
||||||
|
contextEncodedAndPinned.unpin()
|
||||||
|
masterKeyPinned.unpin()
|
||||||
|
subkeyPinned.unpin()
|
||||||
|
|
||||||
|
return subkey
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The crypto_kdf_keygen() function creates a master key.
|
||||||
|
*/
|
||||||
|
actual fun keygen(): UByteArray {
|
||||||
|
val masterKey = UByteArray(crypto_kdf_KEYBYTES)
|
||||||
|
val masterKeyPinned = masterKey.pin()
|
||||||
|
crypto_kdf_keygen(masterKeyPinned.toPtr())
|
||||||
|
masterKeyPinned.unpin()
|
||||||
|
return masterKey
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -48,19 +48,19 @@
|
|||||||
| crypto_box_seal | :heavy_check_mark: |
|
| crypto_box_seal | :heavy_check_mark: |
|
||||||
| crypto_box_seal_open | :heavy_check_mark: |
|
| crypto_box_seal_open | :heavy_check_mark: |
|
||||||
| crypto_box_seed_keypair | :heavy_check_mark: |
|
| crypto_box_seed_keypair | :heavy_check_mark: |
|
||||||
| crypto_core_ristretto255_add | |
|
| crypto_core_ristretto255_add | not present in LazySodium |
|
||||||
| crypto_core_ristretto255_from_hash | |
|
| crypto_core_ristretto255_from_hash | not present in LazySodium |
|
||||||
| crypto_core_ristretto255_is_valid_point | |
|
| crypto_core_ristretto255_is_valid_point | not present in LazySodium |
|
||||||
| crypto_core_ristretto255_random | |
|
| crypto_core_ristretto255_random | not present in LazySodium |
|
||||||
| crypto_core_ristretto255_scalar_add | |
|
| crypto_core_ristretto255_scalar_add | not present in LazySodium |
|
||||||
| crypto_core_ristretto255_scalar_complement | |
|
| crypto_core_ristretto255_scalar_complement | not present in LazySodium |
|
||||||
| crypto_core_ristretto255_scalar_invert | |
|
| crypto_core_ristretto255_scalar_invert | not present in LazySodium |
|
||||||
| crypto_core_ristretto255_scalar_mul | |
|
| crypto_core_ristretto255_scalar_mul | not present in LazySodium |
|
||||||
| crypto_core_ristretto255_scalar_negate | |
|
| crypto_core_ristretto255_scalar_negate | not present in LazySodium |
|
||||||
| crypto_core_ristretto255_scalar_random | |
|
| crypto_core_ristretto255_scalar_random | not present in LazySodium |
|
||||||
| crypto_core_ristretto255_scalar_reduce | |
|
| crypto_core_ristretto255_scalar_reduce | not present in LazySodium |
|
||||||
| crypto_core_ristretto255_scalar_sub | |
|
| crypto_core_ristretto255_scalar_sub | not present in LazySodium |
|
||||||
| crypto_core_ristretto255_sub | |
|
| crypto_core_ristretto255_sub | not present in LazySodium |
|
||||||
| crypto_generichash | :heavy_check_mark: |
|
| crypto_generichash | :heavy_check_mark: |
|
||||||
| crypto_generichash_blake2b_salt_personal | |
|
| crypto_generichash_blake2b_salt_personal | |
|
||||||
| crypto_generichash_final | :heavy_check_mark: |
|
| crypto_generichash_final | :heavy_check_mark: |
|
||||||
@ -76,23 +76,23 @@
|
|||||||
| crypto_hash_sha512_final | :heavy_check_mark: |
|
| crypto_hash_sha512_final | :heavy_check_mark: |
|
||||||
| crypto_hash_sha512_init | :heavy_check_mark: |
|
| crypto_hash_sha512_init | :heavy_check_mark: |
|
||||||
| crypto_hash_sha512_update | :heavy_check_mark: |
|
| crypto_hash_sha512_update | :heavy_check_mark: |
|
||||||
| crypto_kdf_derive_from_key | |
|
| crypto_kdf_derive_from_key | :heavy_check_mark: |
|
||||||
| crypto_kdf_keygen | |
|
| crypto_kdf_keygen | :heavy_check_mark: |
|
||||||
| crypto_kx_client_session_keys | |
|
| crypto_kx_client_session_keys | |
|
||||||
| crypto_kx_keypair | |
|
| crypto_kx_keypair | |
|
||||||
| crypto_kx_seed_keypair | |
|
| crypto_kx_seed_keypair | |
|
||||||
| crypto_kx_server_session_keys | |
|
| crypto_kx_server_session_keys | |
|
||||||
| crypto_onetimeauth | |
|
| crypto_onetimeauth | not present in LazySodium |
|
||||||
| crypto_onetimeauth_final | |
|
| crypto_onetimeauth_final | not present in LazySodium |
|
||||||
| crypto_onetimeauth_init | |
|
| crypto_onetimeauth_init | not present in LazySodium |
|
||||||
| crypto_onetimeauth_keygen | |
|
| crypto_onetimeauth_keygen | not present in LazySodium |
|
||||||
| crypto_onetimeauth_update | |
|
| crypto_onetimeauth_update | not present in LazySodium |
|
||||||
| crypto_onetimeauth_verify | |
|
| crypto_onetimeauth_verify | not present in LazySodium |
|
||||||
| crypto_pwhash | |
|
| crypto_pwhash | |
|
||||||
| crypto_pwhash_scryptsalsa208sha256 | |
|
| crypto_pwhash_scryptsalsa208sha256 | not present in LazySodium for Android |
|
||||||
| crypto_pwhash_scryptsalsa208sha256_ll | |
|
| crypto_pwhash_scryptsalsa208sha256_ll | not present in LazySodium for Android |
|
||||||
| crypto_pwhash_scryptsalsa208sha256_str | |
|
| crypto_pwhash_scryptsalsa208sha256_str | not present in LazySodium for Android |
|
||||||
| crypto_pwhash_scryptsalsa208sha256_str_verify | |
|
| crypto_pwhash_scryptsalsa208sha256_str_verify | not present in LazySodium for Android |
|
||||||
| crypto_pwhash_str | |
|
| crypto_pwhash_str | |
|
||||||
| crypto_pwhash_str_needs_rehash | |
|
| crypto_pwhash_str_needs_rehash | |
|
||||||
| crypto_pwhash_str_verify | |
|
| crypto_pwhash_str_verify | |
|
||||||
@ -135,9 +135,9 @@
|
|||||||
| crypto_stream_chacha20_xor | |
|
| crypto_stream_chacha20_xor | |
|
||||||
| crypto_stream_chacha20_xor_ic | |
|
| crypto_stream_chacha20_xor_ic | |
|
||||||
| crypto_stream_keygen | |
|
| crypto_stream_keygen | |
|
||||||
| crypto_stream_xchacha20_keygen | |
|
| crypto_stream_xchacha20_keygen | not present in LazySodium Android |
|
||||||
| crypto_stream_xchacha20_xor | |
|
| crypto_stream_xchacha20_xor | not present in LazySodium Android|
|
||||||
| crypto_stream_xchacha20_xor_ic | |
|
| crypto_stream_xchacha20_xor_ic | not present in LazySodium Android |
|
||||||
| randombytes_buf | |
|
| randombytes_buf | |
|
||||||
| randombytes_buf_deterministic | |
|
| randombytes_buf_deterministic | |
|
||||||
| randombytes_close | |
|
| randombytes_close | |
|
||||||
|
Loading…
x
Reference in New Issue
Block a user