1195972f6Sopenharmony_ci/** 2195972f6Sopenharmony_ci * @file 3195972f6Sopenharmony_ci * SNMPv3 crypto/auth functions implemented for ARM mbedtls. 4195972f6Sopenharmony_ci */ 5195972f6Sopenharmony_ci 6195972f6Sopenharmony_ci/* 7195972f6Sopenharmony_ci * Copyright (c) 2016 Elias Oenal and Dirk Ziegelmeier. 8195972f6Sopenharmony_ci * All rights reserved. 9195972f6Sopenharmony_ci * 10195972f6Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 11195972f6Sopenharmony_ci * are permitted provided that the following conditions are met: 12195972f6Sopenharmony_ci * 13195972f6Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, 14195972f6Sopenharmony_ci * this list of conditions and the following disclaimer. 15195972f6Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, 16195972f6Sopenharmony_ci * this list of conditions and the following disclaimer in the documentation 17195972f6Sopenharmony_ci * and/or other materials provided with the distribution. 18195972f6Sopenharmony_ci * 3. The name of the author may not be used to endorse or promote products 19195972f6Sopenharmony_ci * derived from this software without specific prior written permission. 20195972f6Sopenharmony_ci * 21195972f6Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 22195972f6Sopenharmony_ci * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23195972f6Sopenharmony_ci * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 24195972f6Sopenharmony_ci * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25195972f6Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26195972f6Sopenharmony_ci * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27195972f6Sopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28195972f6Sopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29195972f6Sopenharmony_ci * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 30195972f6Sopenharmony_ci * OF SUCH DAMAGE. 31195972f6Sopenharmony_ci * 32195972f6Sopenharmony_ci * Author: Elias Oenal <lwip@eliasoenal.com> 33195972f6Sopenharmony_ci * Dirk Ziegelmeier <dirk@ziegelmeier.net> 34195972f6Sopenharmony_ci */ 35195972f6Sopenharmony_ci 36195972f6Sopenharmony_ci#include "lwip/apps/snmpv3.h" 37195972f6Sopenharmony_ci#include "snmpv3_priv.h" 38195972f6Sopenharmony_ci#include "lwip/arch.h" 39195972f6Sopenharmony_ci#include "snmp_msg.h" 40195972f6Sopenharmony_ci#include "lwip/sys.h" 41195972f6Sopenharmony_ci#include <string.h> 42195972f6Sopenharmony_ci 43195972f6Sopenharmony_ci#if LWIP_SNMP && LWIP_SNMP_V3 && LWIP_SNMP_V3_MBEDTLS 44195972f6Sopenharmony_ci 45195972f6Sopenharmony_ci#include "mbedtls/md.h" 46195972f6Sopenharmony_ci#include "mbedtls/cipher.h" 47195972f6Sopenharmony_ci 48195972f6Sopenharmony_ci#include "mbedtls/md5.h" 49195972f6Sopenharmony_ci#include "mbedtls/sha1.h" 50195972f6Sopenharmony_ci 51195972f6Sopenharmony_cierr_t 52195972f6Sopenharmony_cisnmpv3_auth(struct snmp_pbuf_stream *stream, u16_t length, 53195972f6Sopenharmony_ci const u8_t *key, snmpv3_auth_algo_t algo, u8_t *hmac_out) 54195972f6Sopenharmony_ci{ 55195972f6Sopenharmony_ci u32_t i; 56195972f6Sopenharmony_ci u8_t key_len; 57195972f6Sopenharmony_ci const mbedtls_md_info_t *md_info; 58195972f6Sopenharmony_ci mbedtls_md_context_t ctx; 59195972f6Sopenharmony_ci struct snmp_pbuf_stream read_stream; 60195972f6Sopenharmony_ci snmp_pbuf_stream_init(&read_stream, stream->pbuf, stream->offset, stream->length); 61195972f6Sopenharmony_ci 62195972f6Sopenharmony_ci if (algo == SNMP_V3_AUTH_ALGO_MD5) { 63195972f6Sopenharmony_ci md_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5); 64195972f6Sopenharmony_ci key_len = SNMP_V3_MD5_LEN; 65195972f6Sopenharmony_ci } else if (algo == SNMP_V3_AUTH_ALGO_SHA) { 66195972f6Sopenharmony_ci md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); 67195972f6Sopenharmony_ci key_len = SNMP_V3_SHA_LEN; 68195972f6Sopenharmony_ci } else { 69195972f6Sopenharmony_ci return ERR_ARG; 70195972f6Sopenharmony_ci } 71195972f6Sopenharmony_ci 72195972f6Sopenharmony_ci mbedtls_md_init(&ctx); 73195972f6Sopenharmony_ci if (mbedtls_md_setup(&ctx, md_info, 1) != 0) { 74195972f6Sopenharmony_ci return ERR_ARG; 75195972f6Sopenharmony_ci } 76195972f6Sopenharmony_ci 77195972f6Sopenharmony_ci if (mbedtls_md_hmac_starts(&ctx, key, key_len) != 0) { 78195972f6Sopenharmony_ci goto free_md; 79195972f6Sopenharmony_ci } 80195972f6Sopenharmony_ci 81195972f6Sopenharmony_ci for (i = 0; i < length; i++) { 82195972f6Sopenharmony_ci u8_t byte; 83195972f6Sopenharmony_ci 84195972f6Sopenharmony_ci if (snmp_pbuf_stream_read(&read_stream, &byte)) { 85195972f6Sopenharmony_ci goto free_md; 86195972f6Sopenharmony_ci } 87195972f6Sopenharmony_ci 88195972f6Sopenharmony_ci if (mbedtls_md_hmac_update(&ctx, &byte, 1) != 0) { 89195972f6Sopenharmony_ci goto free_md; 90195972f6Sopenharmony_ci } 91195972f6Sopenharmony_ci } 92195972f6Sopenharmony_ci 93195972f6Sopenharmony_ci if (mbedtls_md_hmac_finish(&ctx, hmac_out) != 0) { 94195972f6Sopenharmony_ci goto free_md; 95195972f6Sopenharmony_ci } 96195972f6Sopenharmony_ci 97195972f6Sopenharmony_ci mbedtls_md_free(&ctx); 98195972f6Sopenharmony_ci return ERR_OK; 99195972f6Sopenharmony_ci 100195972f6Sopenharmony_cifree_md: 101195972f6Sopenharmony_ci mbedtls_md_free(&ctx); 102195972f6Sopenharmony_ci return ERR_ARG; 103195972f6Sopenharmony_ci} 104195972f6Sopenharmony_ci 105195972f6Sopenharmony_ci#if LWIP_SNMP_V3_CRYPTO 106195972f6Sopenharmony_ci 107195972f6Sopenharmony_cierr_t 108195972f6Sopenharmony_cisnmpv3_crypt(struct snmp_pbuf_stream *stream, u16_t length, 109195972f6Sopenharmony_ci const u8_t *key, const u8_t *priv_param, const u32_t engine_boots, 110195972f6Sopenharmony_ci const u32_t engine_time, snmpv3_priv_algo_t algo, snmpv3_priv_mode_t mode) 111195972f6Sopenharmony_ci{ 112195972f6Sopenharmony_ci size_t i; 113195972f6Sopenharmony_ci mbedtls_cipher_context_t ctx; 114195972f6Sopenharmony_ci const mbedtls_cipher_info_t *cipher_info; 115195972f6Sopenharmony_ci 116195972f6Sopenharmony_ci struct snmp_pbuf_stream read_stream; 117195972f6Sopenharmony_ci struct snmp_pbuf_stream write_stream; 118195972f6Sopenharmony_ci snmp_pbuf_stream_init(&read_stream, stream->pbuf, stream->offset, stream->length); 119195972f6Sopenharmony_ci snmp_pbuf_stream_init(&write_stream, stream->pbuf, stream->offset, stream->length); 120195972f6Sopenharmony_ci mbedtls_cipher_init(&ctx); 121195972f6Sopenharmony_ci 122195972f6Sopenharmony_ci if (algo == SNMP_V3_PRIV_ALGO_DES) { 123195972f6Sopenharmony_ci u8_t iv_local[8]; 124195972f6Sopenharmony_ci u8_t out_bytes[8]; 125195972f6Sopenharmony_ci size_t out_len; 126195972f6Sopenharmony_ci 127195972f6Sopenharmony_ci /* RFC 3414 mandates padding for DES */ 128195972f6Sopenharmony_ci if ((length & 0x07) != 0) { 129195972f6Sopenharmony_ci return ERR_ARG; 130195972f6Sopenharmony_ci } 131195972f6Sopenharmony_ci 132195972f6Sopenharmony_ci cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_CBC); 133195972f6Sopenharmony_ci if (mbedtls_cipher_setup(&ctx, cipher_info) != 0) { 134195972f6Sopenharmony_ci return ERR_ARG; 135195972f6Sopenharmony_ci } 136195972f6Sopenharmony_ci if (mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_NONE) != 0) { 137195972f6Sopenharmony_ci return ERR_ARG; 138195972f6Sopenharmony_ci } 139195972f6Sopenharmony_ci if (mbedtls_cipher_setkey(&ctx, key, 8 * 8, (mode == SNMP_V3_PRIV_MODE_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT) != 0) { 140195972f6Sopenharmony_ci goto error; 141195972f6Sopenharmony_ci } 142195972f6Sopenharmony_ci 143195972f6Sopenharmony_ci /* Prepare IV */ 144195972f6Sopenharmony_ci for (i = 0; i < LWIP_ARRAYSIZE(iv_local); i++) { 145195972f6Sopenharmony_ci iv_local[i] = priv_param[i] ^ key[i + 8]; 146195972f6Sopenharmony_ci } 147195972f6Sopenharmony_ci if (mbedtls_cipher_set_iv(&ctx, iv_local, LWIP_ARRAYSIZE(iv_local)) != 0) { 148195972f6Sopenharmony_ci goto error; 149195972f6Sopenharmony_ci } 150195972f6Sopenharmony_ci 151195972f6Sopenharmony_ci for (i = 0; i < length; i += 8) { 152195972f6Sopenharmony_ci size_t j; 153195972f6Sopenharmony_ci u8_t in_bytes[8]; 154195972f6Sopenharmony_ci out_len = LWIP_ARRAYSIZE(out_bytes) ; 155195972f6Sopenharmony_ci 156195972f6Sopenharmony_ci for (j = 0; j < LWIP_ARRAYSIZE(in_bytes); j++) { 157195972f6Sopenharmony_ci if (snmp_pbuf_stream_read(&read_stream, &in_bytes[j]) != ERR_OK) { 158195972f6Sopenharmony_ci goto error; 159195972f6Sopenharmony_ci } 160195972f6Sopenharmony_ci } 161195972f6Sopenharmony_ci 162195972f6Sopenharmony_ci if (mbedtls_cipher_update(&ctx, in_bytes, LWIP_ARRAYSIZE(in_bytes), out_bytes, &out_len) != 0) { 163195972f6Sopenharmony_ci goto error; 164195972f6Sopenharmony_ci } 165195972f6Sopenharmony_ci 166195972f6Sopenharmony_ci if (snmp_pbuf_stream_writebuf(&write_stream, out_bytes, (u16_t)out_len) != ERR_OK) { 167195972f6Sopenharmony_ci goto error; 168195972f6Sopenharmony_ci } 169195972f6Sopenharmony_ci } 170195972f6Sopenharmony_ci 171195972f6Sopenharmony_ci out_len = LWIP_ARRAYSIZE(out_bytes); 172195972f6Sopenharmony_ci if (mbedtls_cipher_finish(&ctx, out_bytes, &out_len) != 0) { 173195972f6Sopenharmony_ci goto error; 174195972f6Sopenharmony_ci } 175195972f6Sopenharmony_ci 176195972f6Sopenharmony_ci if (snmp_pbuf_stream_writebuf(&write_stream, out_bytes, (u16_t)out_len) != ERR_OK) { 177195972f6Sopenharmony_ci goto error; 178195972f6Sopenharmony_ci } 179195972f6Sopenharmony_ci } else if (algo == SNMP_V3_PRIV_ALGO_AES) { 180195972f6Sopenharmony_ci u8_t iv_local[16]; 181195972f6Sopenharmony_ci 182195972f6Sopenharmony_ci cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CFB128); 183195972f6Sopenharmony_ci if (mbedtls_cipher_setup(&ctx, cipher_info) != 0) { 184195972f6Sopenharmony_ci return ERR_ARG; 185195972f6Sopenharmony_ci } 186195972f6Sopenharmony_ci if (mbedtls_cipher_setkey(&ctx, key, 16 * 8, (mode == SNMP_V3_PRIV_MODE_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT) != 0) { 187195972f6Sopenharmony_ci goto error; 188195972f6Sopenharmony_ci } 189195972f6Sopenharmony_ci 190195972f6Sopenharmony_ci /* 191195972f6Sopenharmony_ci * IV is the big endian concatenation of boots, 192195972f6Sopenharmony_ci * uptime and priv param - see RFC3826. 193195972f6Sopenharmony_ci */ 194195972f6Sopenharmony_ci iv_local[0 + 0] = (engine_boots >> 24) & 0xFF; 195195972f6Sopenharmony_ci iv_local[0 + 1] = (engine_boots >> 16) & 0xFF; 196195972f6Sopenharmony_ci iv_local[0 + 2] = (engine_boots >> 8) & 0xFF; 197195972f6Sopenharmony_ci iv_local[0 + 3] = (engine_boots >> 0) & 0xFF; 198195972f6Sopenharmony_ci iv_local[4 + 0] = (engine_time >> 24) & 0xFF; 199195972f6Sopenharmony_ci iv_local[4 + 1] = (engine_time >> 16) & 0xFF; 200195972f6Sopenharmony_ci iv_local[4 + 2] = (engine_time >> 8) & 0xFF; 201195972f6Sopenharmony_ci iv_local[4 + 3] = (engine_time >> 0) & 0xFF; 202195972f6Sopenharmony_ci SMEMCPY(iv_local + 8, priv_param, 8); 203195972f6Sopenharmony_ci if (mbedtls_cipher_set_iv(&ctx, iv_local, LWIP_ARRAYSIZE(iv_local)) != 0) { 204195972f6Sopenharmony_ci goto error; 205195972f6Sopenharmony_ci } 206195972f6Sopenharmony_ci 207195972f6Sopenharmony_ci for (i = 0; i < length; i++) { 208195972f6Sopenharmony_ci u8_t in_byte; 209195972f6Sopenharmony_ci u8_t out_byte; 210195972f6Sopenharmony_ci size_t out_len = sizeof(out_byte); 211195972f6Sopenharmony_ci 212195972f6Sopenharmony_ci if (snmp_pbuf_stream_read(&read_stream, &in_byte) != ERR_OK) { 213195972f6Sopenharmony_ci goto error; 214195972f6Sopenharmony_ci } 215195972f6Sopenharmony_ci if (mbedtls_cipher_update(&ctx, &in_byte, sizeof(in_byte), &out_byte, &out_len) != 0) { 216195972f6Sopenharmony_ci goto error; 217195972f6Sopenharmony_ci } 218195972f6Sopenharmony_ci if (snmp_pbuf_stream_write(&write_stream, out_byte) != ERR_OK) { 219195972f6Sopenharmony_ci goto error; 220195972f6Sopenharmony_ci } 221195972f6Sopenharmony_ci } 222195972f6Sopenharmony_ci } else { 223195972f6Sopenharmony_ci return ERR_ARG; 224195972f6Sopenharmony_ci } 225195972f6Sopenharmony_ci 226195972f6Sopenharmony_ci mbedtls_cipher_free(&ctx); 227195972f6Sopenharmony_ci return ERR_OK; 228195972f6Sopenharmony_ci 229195972f6Sopenharmony_cierror: 230195972f6Sopenharmony_ci mbedtls_cipher_free(&ctx); 231195972f6Sopenharmony_ci return ERR_OK; 232195972f6Sopenharmony_ci} 233195972f6Sopenharmony_ci 234195972f6Sopenharmony_ci#endif /* LWIP_SNMP_V3_CRYPTO */ 235195972f6Sopenharmony_ci 236195972f6Sopenharmony_ci/* A.2.1. Password to Key Sample Code for MD5 */ 237195972f6Sopenharmony_civoid 238195972f6Sopenharmony_cisnmpv3_password_to_key_md5( 239195972f6Sopenharmony_ci const u8_t *password, /* IN */ 240195972f6Sopenharmony_ci size_t passwordlen, /* IN */ 241195972f6Sopenharmony_ci const u8_t *engineID, /* IN - pointer to snmpEngineID */ 242195972f6Sopenharmony_ci u8_t engineLength,/* IN - length of snmpEngineID */ 243195972f6Sopenharmony_ci u8_t *key) /* OUT - pointer to caller 16-octet buffer */ 244195972f6Sopenharmony_ci{ 245195972f6Sopenharmony_ci mbedtls_md5_context MD; 246195972f6Sopenharmony_ci u8_t *cp, password_buf[64]; 247195972f6Sopenharmony_ci u32_t password_index = 0; 248195972f6Sopenharmony_ci u8_t i; 249195972f6Sopenharmony_ci u32_t count = 0; 250195972f6Sopenharmony_ci 251195972f6Sopenharmony_ci mbedtls_md5_init(&MD); /* initialize MD5 */ 252195972f6Sopenharmony_ci mbedtls_md5_starts(&MD); 253195972f6Sopenharmony_ci 254195972f6Sopenharmony_ci /**********************************************/ 255195972f6Sopenharmony_ci /* Use while loop until we've done 1 Megabyte */ 256195972f6Sopenharmony_ci /**********************************************/ 257195972f6Sopenharmony_ci while (count < 1048576) { 258195972f6Sopenharmony_ci cp = password_buf; 259195972f6Sopenharmony_ci for (i = 0; i < 64; i++) { 260195972f6Sopenharmony_ci /*************************************************/ 261195972f6Sopenharmony_ci /* Take the next octet of the password, wrapping */ 262195972f6Sopenharmony_ci /* to the beginning of the password as necessary.*/ 263195972f6Sopenharmony_ci /*************************************************/ 264195972f6Sopenharmony_ci *cp++ = password[password_index++ % passwordlen]; 265195972f6Sopenharmony_ci } 266195972f6Sopenharmony_ci mbedtls_md5_update(&MD, password_buf, 64); 267195972f6Sopenharmony_ci count += 64; 268195972f6Sopenharmony_ci } 269195972f6Sopenharmony_ci mbedtls_md5_finish(&MD, key); /* tell MD5 we're done */ 270195972f6Sopenharmony_ci 271195972f6Sopenharmony_ci /*****************************************************/ 272195972f6Sopenharmony_ci /* Now localize the key with the engineID and pass */ 273195972f6Sopenharmony_ci /* through MD5 to produce final key */ 274195972f6Sopenharmony_ci /* May want to ensure that engineLength <= 32, */ 275195972f6Sopenharmony_ci /* otherwise need to use a buffer larger than 64 */ 276195972f6Sopenharmony_ci /*****************************************************/ 277195972f6Sopenharmony_ci SMEMCPY(password_buf, key, 16); 278195972f6Sopenharmony_ci MEMCPY(password_buf + 16, engineID, engineLength); 279195972f6Sopenharmony_ci SMEMCPY(password_buf + 16 + engineLength, key, 16); 280195972f6Sopenharmony_ci 281195972f6Sopenharmony_ci mbedtls_md5_starts(&MD); 282195972f6Sopenharmony_ci mbedtls_md5_update(&MD, password_buf, 32 + engineLength); 283195972f6Sopenharmony_ci mbedtls_md5_finish(&MD, key); 284195972f6Sopenharmony_ci 285195972f6Sopenharmony_ci mbedtls_md5_free(&MD); 286195972f6Sopenharmony_ci return; 287195972f6Sopenharmony_ci} 288195972f6Sopenharmony_ci 289195972f6Sopenharmony_ci/* A.2.2. Password to Key Sample Code for SHA */ 290195972f6Sopenharmony_civoid 291195972f6Sopenharmony_cisnmpv3_password_to_key_sha( 292195972f6Sopenharmony_ci const u8_t *password, /* IN */ 293195972f6Sopenharmony_ci size_t passwordlen, /* IN */ 294195972f6Sopenharmony_ci const u8_t *engineID, /* IN - pointer to snmpEngineID */ 295195972f6Sopenharmony_ci u8_t engineLength,/* IN - length of snmpEngineID */ 296195972f6Sopenharmony_ci u8_t *key) /* OUT - pointer to caller 20-octet buffer */ 297195972f6Sopenharmony_ci{ 298195972f6Sopenharmony_ci mbedtls_sha1_context SH; 299195972f6Sopenharmony_ci u8_t *cp, password_buf[72]; 300195972f6Sopenharmony_ci u32_t password_index = 0; 301195972f6Sopenharmony_ci u8_t i; 302195972f6Sopenharmony_ci u32_t count = 0; 303195972f6Sopenharmony_ci 304195972f6Sopenharmony_ci mbedtls_sha1_init(&SH); /* initialize SHA */ 305195972f6Sopenharmony_ci mbedtls_sha1_starts(&SH); 306195972f6Sopenharmony_ci 307195972f6Sopenharmony_ci /**********************************************/ 308195972f6Sopenharmony_ci /* Use while loop until we've done 1 Megabyte */ 309195972f6Sopenharmony_ci /**********************************************/ 310195972f6Sopenharmony_ci while (count < 1048576) { 311195972f6Sopenharmony_ci cp = password_buf; 312195972f6Sopenharmony_ci for (i = 0; i < 64; i++) { 313195972f6Sopenharmony_ci /*************************************************/ 314195972f6Sopenharmony_ci /* Take the next octet of the password, wrapping */ 315195972f6Sopenharmony_ci /* to the beginning of the password as necessary.*/ 316195972f6Sopenharmony_ci /*************************************************/ 317195972f6Sopenharmony_ci *cp++ = password[password_index++ % passwordlen]; 318195972f6Sopenharmony_ci } 319195972f6Sopenharmony_ci mbedtls_sha1_update(&SH, password_buf, 64); 320195972f6Sopenharmony_ci count += 64; 321195972f6Sopenharmony_ci } 322195972f6Sopenharmony_ci mbedtls_sha1_finish(&SH, key); /* tell SHA we're done */ 323195972f6Sopenharmony_ci 324195972f6Sopenharmony_ci /*****************************************************/ 325195972f6Sopenharmony_ci /* Now localize the key with the engineID and pass */ 326195972f6Sopenharmony_ci /* through SHA to produce final key */ 327195972f6Sopenharmony_ci /* May want to ensure that engineLength <= 32, */ 328195972f6Sopenharmony_ci /* otherwise need to use a buffer larger than 72 */ 329195972f6Sopenharmony_ci /*****************************************************/ 330195972f6Sopenharmony_ci SMEMCPY(password_buf, key, 20); 331195972f6Sopenharmony_ci MEMCPY(password_buf + 20, engineID, engineLength); 332195972f6Sopenharmony_ci SMEMCPY(password_buf + 20 + engineLength, key, 20); 333195972f6Sopenharmony_ci 334195972f6Sopenharmony_ci mbedtls_sha1_starts(&SH); 335195972f6Sopenharmony_ci mbedtls_sha1_update(&SH, password_buf, 40 + engineLength); 336195972f6Sopenharmony_ci mbedtls_sha1_finish(&SH, key); 337195972f6Sopenharmony_ci 338195972f6Sopenharmony_ci mbedtls_sha1_free(&SH); 339195972f6Sopenharmony_ci return; 340195972f6Sopenharmony_ci} 341195972f6Sopenharmony_ci 342195972f6Sopenharmony_ci#endif /* LWIP_SNMP && LWIP_SNMP_V3 && LWIP_SNMP_V3_MBEDTLS */ 343