1 /* 2 * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include <openssl/asn1t.h> 13 #include <openssl/core_names.h> 14 #include <openssl/err.h> 15 #include <openssl/evp.h> 16 #include <openssl/x509.h> 17 #include <openssl/rand.h> 18 #include "crypto/evp.h" 19 20 #ifndef OPENSSL_NO_SCRYPT 21 /* PKCS#5 scrypt password based encryption structures */ 22 23 ASN1_SEQUENCE(SCRYPT_PARAMS) = { 24 ASN1_SIMPLE(SCRYPT_PARAMS, salt, ASN1_OCTET_STRING), 25 ASN1_SIMPLE(SCRYPT_PARAMS, costParameter, ASN1_INTEGER), 26 ASN1_SIMPLE(SCRYPT_PARAMS, blockSize, ASN1_INTEGER), 27 ASN1_SIMPLE(SCRYPT_PARAMS, parallelizationParameter, ASN1_INTEGER), 28 ASN1_OPT(SCRYPT_PARAMS, keyLength, ASN1_INTEGER), 29 } ASN1_SEQUENCE_END(SCRYPT_PARAMS) 30 31 IMPLEMENT_ASN1_FUNCTIONS(SCRYPT_PARAMS) 32 33 static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen, 34 size_t keylen, uint64_t N, uint64_t r, 35 uint64_t p); 36 37 /* 38 * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm using scrypt 39 */ 40 41 X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, 42 const unsigned char *salt, int saltlen, 43 unsigned char *aiv, uint64_t N, uint64_t r, 44 uint64_t p) 45 { 46 X509_ALGOR *scheme = NULL, *ret = NULL; 47 int alg_nid; 48 size_t keylen = 0; 49 EVP_CIPHER_CTX *ctx = NULL; 50 unsigned char iv[EVP_MAX_IV_LENGTH]; 51 PBE2PARAM *pbe2 = NULL; 52 53 if (!cipher) { 54 ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER); 55 goto err; 56 } 57 58 if (EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) { 59 ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_SCRYPT_PARAMETERS); 60 goto err; 61 } 62 63 alg_nid = EVP_CIPHER_get_type(cipher); 64 if (alg_nid == NID_undef) { 65 ERR_raise(ERR_LIB_ASN1, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); 66 goto err; 67 } 68 69 pbe2 = PBE2PARAM_new(); 70 if (pbe2 == NULL) 71 goto merr; 72 73 /* Setup the AlgorithmIdentifier for the encryption scheme */ 74 scheme = pbe2->encryption; 75 76 scheme->algorithm = OBJ_nid2obj(alg_nid); 77 scheme->parameter = ASN1_TYPE_new(); 78 if (scheme->parameter == NULL) 79 goto merr; 80 81 /* Create random IV */ 82 if (EVP_CIPHER_get_iv_length(cipher)) { 83 if (aiv) 84 memcpy(iv, aiv, EVP_CIPHER_get_iv_length(cipher)); 85 else if (RAND_bytes(iv, EVP_CIPHER_get_iv_length(cipher)) <= 0) 86 goto err; 87 } 88 89 ctx = EVP_CIPHER_CTX_new(); 90 if (ctx == NULL) 91 goto merr; 92 93 /* Dummy cipherinit to just setup the IV */ 94 if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0) == 0) 95 goto err; 96 if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) <= 0) { 97 ERR_raise(ERR_LIB_ASN1, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); 98 goto err; 99 } 100 EVP_CIPHER_CTX_free(ctx); 101 ctx = NULL; 102 103 /* If its RC2 then we'd better setup the key length */ 104 105 if (alg_nid == NID_rc2_cbc) 106 keylen = EVP_CIPHER_get_key_length(cipher); 107 108 /* Setup keyfunc */ 109 110 X509_ALGOR_free(pbe2->keyfunc); 111 112 pbe2->keyfunc = pkcs5_scrypt_set(salt, saltlen, keylen, N, r, p); 113 114 if (pbe2->keyfunc == NULL) 115 goto merr; 116 117 /* Now set up top level AlgorithmIdentifier */ 118 119 ret = X509_ALGOR_new(); 120 if (ret == NULL) 121 goto merr; 122 123 ret->algorithm = OBJ_nid2obj(NID_pbes2); 124 125 /* Encode PBE2PARAM into parameter */ 126 127 if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2, 128 &ret->parameter) == NULL) 129 goto merr; 130 131 PBE2PARAM_free(pbe2); 132 pbe2 = NULL; 133 134 return ret; 135 136 merr: 137 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 138 139 err: 140 PBE2PARAM_free(pbe2); 141 X509_ALGOR_free(ret); 142 EVP_CIPHER_CTX_free(ctx); 143 144 return NULL; 145 } 146 147 static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen, 148 size_t keylen, uint64_t N, uint64_t r, 149 uint64_t p) 150 { 151 X509_ALGOR *keyfunc = NULL; 152 SCRYPT_PARAMS *sparam = SCRYPT_PARAMS_new(); 153 154 if (sparam == NULL) 155 goto merr; 156 157 if (!saltlen) 158 saltlen = PKCS5_SALT_LEN; 159 160 /* This will either copy salt or grow the buffer */ 161 if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0) 162 goto merr; 163 164 if (salt == NULL && RAND_bytes(sparam->salt->data, saltlen) <= 0) 165 goto err; 166 167 if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0) 168 goto merr; 169 170 if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0) 171 goto merr; 172 173 if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0) 174 goto merr; 175 176 /* If have a key len set it up */ 177 178 if (keylen > 0) { 179 sparam->keyLength = ASN1_INTEGER_new(); 180 if (sparam->keyLength == NULL) 181 goto merr; 182 if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0) 183 goto merr; 184 } 185 186 /* Finally setup the keyfunc structure */ 187 188 keyfunc = X509_ALGOR_new(); 189 if (keyfunc == NULL) 190 goto merr; 191 192 keyfunc->algorithm = OBJ_nid2obj(NID_id_scrypt); 193 194 /* Encode SCRYPT_PARAMS into parameter of pbe2 */ 195 196 if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), sparam, 197 &keyfunc->parameter) == NULL) 198 goto merr; 199 200 SCRYPT_PARAMS_free(sparam); 201 return keyfunc; 202 203 merr: 204 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 205 err: 206 SCRYPT_PARAMS_free(sparam); 207 X509_ALGOR_free(keyfunc); 208 return NULL; 209 } 210 211 int PKCS5_v2_scrypt_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, 212 int passlen, ASN1_TYPE *param, 213 const EVP_CIPHER *c, const EVP_MD *md, int en_de, 214 OSSL_LIB_CTX *libctx, const char *propq) 215 { 216 unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; 217 uint64_t p, r, N; 218 size_t saltlen; 219 size_t keylen = 0; 220 int t, rv = 0; 221 SCRYPT_PARAMS *sparam = NULL; 222 223 if (EVP_CIPHER_CTX_get0_cipher(ctx) == NULL) { 224 ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); 225 goto err; 226 } 227 228 /* Decode parameter */ 229 230 sparam = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), param); 231 232 if (sparam == NULL) { 233 ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR); 234 goto err; 235 } 236 237 t = EVP_CIPHER_CTX_get_key_length(ctx); 238 if (t < 0) { 239 ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH); 240 goto err; 241 } 242 keylen = t; 243 244 /* Now check the parameters of sparam */ 245 246 if (sparam->keyLength) { 247 uint64_t spkeylen; 248 if ((ASN1_INTEGER_get_uint64(&spkeylen, sparam->keyLength) == 0) 249 || (spkeylen != keylen)) { 250 ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEYLENGTH); 251 goto err; 252 } 253 } 254 /* Check all parameters fit in uint64_t and are acceptable to scrypt */ 255 if (ASN1_INTEGER_get_uint64(&N, sparam->costParameter) == 0 256 || ASN1_INTEGER_get_uint64(&r, sparam->blockSize) == 0 257 || ASN1_INTEGER_get_uint64(&p, sparam->parallelizationParameter) == 0 258 || EVP_PBE_scrypt_ex(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0, 259 libctx, propq) == 0) { 260 ERR_raise(ERR_LIB_EVP, EVP_R_ILLEGAL_SCRYPT_PARAMETERS); 261 goto err; 262 } 263 264 /* it seems that its all OK */ 265 266 salt = sparam->salt->data; 267 saltlen = sparam->salt->length; 268 if (EVP_PBE_scrypt_ex(pass, passlen, salt, saltlen, N, r, p, 0, key, 269 keylen, libctx, propq) == 0) 270 goto err; 271 rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); 272 err: 273 if (keylen) 274 OPENSSL_cleanse(key, keylen); 275 SCRYPT_PARAMS_free(sparam); 276 return rv; 277 } 278 279 int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, 280 int passlen, ASN1_TYPE *param, 281 const EVP_CIPHER *c, const EVP_MD *md, int en_de) 282 { 283 return PKCS5_v2_scrypt_keyivgen_ex(ctx, pass, passlen, param, c, md, en_de, NULL, NULL); 284 } 285 286 #endif /* OPENSSL_NO_SCRYPT */ 287