1# Key Derivation Using Scrypt (C/C++) 2 3<!--Kit: Crypto Architecture Kit--> 4<!--Subsystem: Security--> 5<!--Owner: @zxz--3--> 6<!--Designer: @lanming--> 7<!--Tester: @PAFT--> 8<!--Adviser: @zengyawen--> 9 10For details about the corresponding algorithm specifications, see [Scrypt](crypto-key-derivation-overview.md#scrypt). 11 12## How to Develop 13 141. Call [OH_CryptoKdfParams_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-kdf-h.md#oh_cryptokdfparams_create) and specify the string parameter **SCRYPT** to create a key derivation parameter object. 15 162. Call [OH_CryptoKdfParams_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-kdf-h.md#oh_cryptokdfparams_setparam) to set the parameters required by SCRYPT. 17 18When a key derivation failure occurs, check whether the following parameters are set: 19 - **CRYPTO_KDF_KEY_DATABLOB**: original password used to generate the derived key. 20 - **CRYPTO_KDF_SALT_DATABLOB**: salt value. 21 - **CRYPTO_KDF_SCRYPT_N_UINT64**: CPU/memory overhead, which must be a power of 2. 22 - **CRYPTO_KDF_SCRYPT_R_UINT64**: block size, which affects the degree of parallelism. 23 - **CRYPTO_KDF_SCRYPT_P_UINT64**: parallelization. 24 - **CRYPTO_KDF_SCRYPT_MAX_MEM_UINT64**: maximum memory limit (bytes). 25 263. Call [OH_CryptoKdf_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-kdf-h.md#oh_cryptokdf_create) and specify the string parameter **SCRYPT** to create a key derivation function object. 27 284. Call [OH_CryptoKdf_Derive](../../reference/apis-crypto-architecture-kit/capi-crypto-kdf-h.md#oh_cryptokdf_derive) and specify the byte length of the target key. 29 30```C++ 31#include "CryptoArchitectureKit/crypto_architecture_kit.h" 32#include "CryptoArchitectureKit/crypto_kdf.h" 33#include <stdio.h> 34#include <cstring> 35 36static OH_Crypto_ErrCode doTestScrypt() 37{ 38 // Create a SCRYPT parameter object. 39 OH_CryptoKdfParams *params = nullptr; 40 OH_Crypto_ErrCode ret = OH_CryptoKdfParams_Create("SCRYPT", ¶ms); 41 if (ret != CRYPTO_SUCCESS) { 42 return ret; 43 } 44 45 // Set the password. 46 const char *password = "123456"; 47 Crypto_DataBlob passwordBlob = { 48 .data = reinterpret_cast<uint8_t *>(const_cast<char *>(password)), 49 .len = strlen(password) 50 }; 51 ret = OH_CryptoKdfParams_SetParam(params, CRYPTO_KDF_KEY_DATABLOB, &passwordBlob); 52 if (ret != CRYPTO_SUCCESS) { 53 OH_CryptoKdfParams_Destroy(params); 54 return ret; 55 } 56 57 // Set the salt value. 58 const char *salt = "saltstring"; 59 Crypto_DataBlob saltBlob = { 60 .data = reinterpret_cast<uint8_t *>(const_cast<char *>(salt)), 61 .len = strlen(salt) 62 }; 63 ret = OH_CryptoKdfParams_SetParam(params, CRYPTO_KDF_SALT_DATABLOB, &saltBlob); 64 if (ret != CRYPTO_SUCCESS) { 65 OH_CryptoKdfParams_Destroy(params); 66 return ret; 67 } 68 69 // Set SCRYPT parameters. 70 uint64_t n = 1024; // CPU/memory overhead. 71 uint64_t r = 8; // Block size. 72 uint64_t p = 16; // Parallelization. 73 uint64_t maxMem = 1067008; // Maximum memory limit (bytes). 74 75 Crypto_DataBlob nData = { 76 .data = reinterpret_cast<uint8_t *>(&n), 77 .len = sizeof(uint64_t) 78 }; 79 Crypto_DataBlob rData = { 80 .data = reinterpret_cast<uint8_t *>(&r), 81 .len = sizeof(uint64_t) 82 }; 83 Crypto_DataBlob pData = { 84 .data = reinterpret_cast<uint8_t *>(&p), 85 .len = sizeof(uint64_t) 86 }; 87 Crypto_DataBlob maxMemData = { 88 .data = reinterpret_cast<uint8_t *>(&maxMem), 89 .len = sizeof(uint64_t) 90 }; 91 92 ret = OH_CryptoKdfParams_SetParam(params, CRYPTO_KDF_SCRYPT_N_UINT64, &nData); 93 if (ret != CRYPTO_SUCCESS) { 94 OH_CryptoKdfParams_Destroy(params); 95 return ret; 96 } 97 ret = OH_CryptoKdfParams_SetParam(params, CRYPTO_KDF_SCRYPT_R_UINT64, &rData); 98 if (ret != CRYPTO_SUCCESS) { 99 OH_CryptoKdfParams_Destroy(params); 100 return ret; 101 } 102 ret = OH_CryptoKdfParams_SetParam(params, CRYPTO_KDF_SCRYPT_P_UINT64, &pData); 103 if (ret != CRYPTO_SUCCESS) { 104 OH_CryptoKdfParams_Destroy(params); 105 return ret; 106 } 107 ret = OH_CryptoKdfParams_SetParam(params, CRYPTO_KDF_SCRYPT_MAX_MEM_UINT64, &maxMemData); 108 if (ret != CRYPTO_SUCCESS) { 109 OH_CryptoKdfParams_Destroy(params); 110 return ret; 111 } 112 113 // Create a key derivation function object. 114 OH_CryptoKdf *kdfCtx = nullptr; 115 ret = OH_CryptoKdf_Create("SCRYPT", &kdfCtx); 116 if (ret != CRYPTO_SUCCESS) { 117 OH_CryptoKdfParams_Destroy(params); 118 return ret; 119 } 120 121 // Derive a key. 122 Crypto_DataBlob out = {0}; 123 uint32_t keyLength = 32; // Generate a 32-byte key. 124 ret = OH_CryptoKdf_Derive(kdfCtx, params, keyLength, &out); 125 if (ret != CRYPTO_SUCCESS) { 126 OH_CryptoKdf_Destroy(kdfCtx); 127 OH_CryptoKdfParams_Destroy(params); 128 return ret; 129 } 130 131 printf("Derived key length: %u\n", out.len); 132 133 // Free resources. 134 OH_Crypto_FreeDataBlob(&out); 135 OH_CryptoKdf_Destroy(kdfCtx); 136 OH_CryptoKdfParams_Destroy(params); 137 return CRYPTO_SUCCESS; 138} 139``` 140