Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
security_lib.c
00001 /* 00002 * Copyright (c) 2013-2019, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 #include "nsconfig.h" 00018 #include "ns_types.h" 00019 #include "ns_trace.h" 00020 #include "string.h" 00021 #include "eventOS_event.h" 00022 #include "nsdynmemLIB.h" 00023 #include "Core/include/ns_socket.h" 00024 #include "NWK_INTERFACE/Include/protocol.h" 00025 #include "shalib.h" 00026 #include "randLIB.h" 00027 #ifdef ECC 00028 #include "libX509_V3.h" 00029 #include "ecc.h" 00030 #endif 00031 #include "Security/TLS/tls_lib.h" 00032 #include "Security/TLS/tls_ccm_crypt.h" 00033 #include "Security/Common/sec_lib.h" 00034 #include "net_nvm_api.h" 00035 #include "Security/PANA/pana_nvm.h" 00036 #include "Security/PANA/pana.h" 00037 #include "Security/PANA/eap_protocol.h" 00038 #include "Security/PANA/pana_internal_api.h" 00039 #include "common_functions.h" 00040 00041 #ifdef PANA 00042 00043 #ifndef SEC_TLS_TIMEOUT 00044 #define SEC_TLS_TIMEOUT 65000 00045 #endif 00046 00047 #define TRACE_GROUP "secl" 00048 00049 NS_LARGE NS_LIST_DEFINE(sec_suite_list, sec_suite_t, link); 00050 sec_suite_t *NS_LARGE active_ecc_sec_suite = 0; 00051 00052 static void tls_MSK_calc(sec_suite_t *suite); 00053 00054 #ifdef PANA_SERVER_API 00055 #ifdef ECC 00056 static void tls_server_hash_copy(uint8_t *ptr, tls_msg_t *tmp_msg, sec_suite_t *suite); 00057 #endif 00058 #endif 00059 00060 #ifdef ECC 00061 00062 static MPint temp_key_entry; 00063 00064 static int8_t ecc_signature_calculate_hash(tls_heap_t *theap); 00065 #endif 00066 00067 static void sec_tx_done(sec_suite_t *suite); 00068 static bool sec_suite_tls_allocate(sec_suite_t *suite); 00069 00070 00071 sec_suite_t *sec_lib_security_session_allocate(bool tls_allocate) 00072 { 00073 sec_suite_t *cur = ns_dyn_mem_alloc(sizeof(sec_suite_t)); 00074 if (cur) { 00075 00076 tls_session_t *tls_session; 00077 if (tls_allocate) { 00078 tls_session = amr_tls_session_allocate(); 00079 if (!tls_session) { 00080 ns_dyn_mem_free(cur); 00081 return NULL; 00082 } 00083 } else { 00084 tls_session = NULL; 00085 } 00086 memset(cur, 0, sizeof(sec_suite_t)); 00087 cur->tls_session = tls_session; 00088 cur->psk_key_id = -1; 00089 cur->supported_chipher_suites = SEC_DEFAULT_SUPPORTED_CHIPHER_SUITES; 00090 pana_session_base_init(&cur->pana_session); 00091 ns_list_add_to_start(&sec_suite_list, cur); 00092 } 00093 return cur; 00094 } 00095 00096 00097 void sec_lib_state_machine_lock(sec_suite_t *suite, sec_state_machine_t state) 00098 { 00099 suite->state = state; 00100 suite->timer = 0; 00101 suite->retry_counter = 0; 00102 } 00103 00104 void sec_lib_state_machine_trig(sec_suite_t *suite, sec_state_machine_t state) 00105 { 00106 suite->state = state; 00107 suite->timer = 1; 00108 suite->retry_counter = 0; 00109 00110 } 00111 00112 #ifdef ECC 00113 void tls_server_hash_copy(uint8_t *ptr, tls_msg_t *tmp_msg, sec_suite_t *suite) 00114 { 00115 #ifdef PANA_SERVER_API 00116 tls_heap_t *t_heap = suite->tls_session->tls_heap; 00117 uint16_t t_length = 39; //Base and random and seq len 00118 t_length += suite->tls_session->id_length; 00119 if (t_heap->tls_chipher_mode == CHIPHER_ECC) { 00120 t_length += 11; 00121 } else { 00122 t_length += 7; 00123 } 00124 00125 tmp_msg->len = t_length; 00126 tmp_msg->len -= 4; 00127 tmp_msg->msg_ptr = ptr + 4; 00128 tls_build_server_hello_msg(ptr, suite->tls_session); 00129 tls_handshake_copy(tmp_msg, t_heap); 00130 tr_debug("Pana server S-Hello,Cert hash"); 00131 #endif 00132 } 00133 #endif 00134 00135 #ifdef PANA_SERVER_API 00136 uint8_t tls_server_certi_hash_copy(sec_suite_t *suite) 00137 { 00138 if (suite->setups & TLS_HANSHAKE_HASH) { 00139 return 1; 00140 } else { 00141 #ifdef ECC 00142 certificate_chain_internal_t *temp; 00143 uint16_t len = 0; 00144 buffer_t *buf; 00145 tls_msg_t *tmp_msg = tls_msg_ptr_get(); 00146 tls_heap_t *t_heap = suite->tls_session->tls_heap; 00147 00148 00149 temp = sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN); 00150 00151 if (temp) { 00152 len = tls_certificate_len(temp); 00153 00154 buf = buffer_get(len); 00155 if (buf) { 00156 uint8_t *ptr; 00157 buf->interface = suite->interface; 00158 00159 ptr = buffer_data_pointer(buf); 00160 tls_server_hash_copy(ptr, tmp_msg, suite); 00161 ptr = buffer_data_pointer(buf); 00162 tmp_msg->len = len - 4; 00163 tmp_msg->msg_ptr = ptr + 4; 00164 ptr = tls_certificate_msg_set(ptr, temp); 00165 tls_handshake_copy(tmp_msg, t_heap); 00166 suite->setups |= TLS_HANSHAKE_HASH; 00167 buffer_free(buf); 00168 return 1; 00169 00170 } 00171 } 00172 #endif 00173 } 00174 return 0; 00175 } 00176 #endif 00177 00178 #ifdef ECC 00179 uint8_t tls_certi_hash_copy(sec_suite_t *suite) 00180 { 00181 if (suite->setups & TLS_HANSHAKE_HASH) { 00182 return 1; 00183 } else { 00184 #ifdef ECC 00185 certificate_chain_internal_t *temp; 00186 uint16_t len = 0; 00187 buffer_t *buf; 00188 tls_msg_t *tmp_msg = tls_msg_ptr_get(); 00189 tls_heap_t *t_heap = suite->tls_session->tls_heap; 00190 00191 00192 temp = sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN); 00193 00194 if (temp) { 00195 len = tls_certificate_len(temp); 00196 00197 buf = buffer_get(len); 00198 if (buf) { 00199 uint8_t *ptr; 00200 00201 buf->interface = suite->interface; 00202 ptr = buffer_data_pointer(buf); 00203 ptr = buffer_data_pointer(buf); 00204 tmp_msg->len = len - 4; 00205 tmp_msg->msg_ptr = ptr + 4; 00206 ptr = tls_certificate_msg_set(ptr, temp); 00207 tls_handshake_copy(tmp_msg, t_heap); 00208 00209 ptr = buffer_data_pointer(buf); 00210 tmp_msg->len = 66; 00211 tmp_msg->msg_ptr = ptr + 4; 00212 00213 ptr = tls_client_key_exchange_msg_set(ptr, t_heap); 00214 tls_handshake_copy(tmp_msg, t_heap); 00215 00216 suite->setups |= TLS_HANSHAKE_HASH; 00217 buffer_free(buf); 00218 return 1; 00219 00220 } 00221 } 00222 #endif 00223 } 00224 return 0; 00225 } 00226 #endif 00227 00228 static void tls_MSK_calc(sec_suite_t *suite) 00229 { 00230 uint8_t *ptr; 00231 tls_heap_t *theap = 0; 00232 pana_heap_t *pheap = 0; 00233 prf_sec_param_t *prf_ptr = shalib_prf_param_get(); 00234 theap = suite->tls_session->tls_heap; 00235 pheap = suite->pana_session.pana_heap; 00236 //tr_debug("CAL MSK:"); 00237 prf_ptr->secret = suite->tls_session->master_secret; 00238 prf_ptr->sec_len = 48; 00239 prf_ptr->label = "client EAP encryption"; 00240 prf_ptr->seed = theap->temp_buf; 00241 ptr = theap->temp_buf; 00242 memcpy(ptr, (theap->tls_hello_random + CLIENT_HELLO_PTR), 32); 00243 ptr += 32; 00244 memcpy(ptr, (theap->tls_hello_random + SERVER_HELLO_PTR), 32); 00245 prf_ptr->seedlen = 64; 00246 shalib_prf_calc(pheap->MSK, 16); 00247 } 00248 00249 #ifdef PANA_SERVER_API 00250 static int tls_check_client_change_chiphersuite(uint8_t *verfify, sec_suite_t *suite) 00251 { 00252 tls_heap_t *tls_heap = suite->tls_session->tls_heap; 00253 int ret_val = -1; 00254 if (tls_heap == NULL) { 00255 tr_warn("TLS Heap fail 1"); 00256 return -1; 00257 } 00258 00259 if (tls_heap->client_verify_buf == NULL) { 00260 tr_warn("TLS Heap verfify ptr fail 1"); 00261 return -1; 00262 } 00263 00264 if (tls_ccm_data_decrypt(tls_heap->client_verify_buf, tls_heap->client_verify_buf_len, suite->tls_session->key_expansion, TLS_HANDSHAKE, false) != 0) { 00265 tr_warn("AUTH Mic Fail"); 00266 goto end_process; 00267 } 00268 00269 uint8_t *ptr = tls_heap->client_verify_buf + 8; 00270 00271 if (ptr[0] == TLS_FINISHED && common_read_24_bit(ptr + 1) == 12) { 00272 ptr += 4; 00273 if (memcmp(verfify, ptr, 12) == 0) { 00274 //tr_debug("Client verify OK"); 00275 ret_val = 0; 00276 tls_finnish_copy(ptr, tls_heap); 00277 tls_hanshake_hash_cal(tls_heap); 00278 sec_lib_state_machine_lock(suite, PRF_CALC2); 00279 tls_verify_calc(tls_heap->verify, 1, tls_heap, suite->tls_session->master_secret); 00280 sec_lib_state_machine_trig(suite, TLS_KEY_CHANGE); 00281 00282 } else { 00283 tr_warn("Verify Mismatch: %s != %s", trace_array(ptr, 12), trace_array(verfify, 12)); 00284 } 00285 } else { 00286 tr_debug("No Chiphertext"); 00287 } 00288 00289 end_process: 00290 //tr_debug("Free"); 00291 if (tls_heap->client_verify_buf) { 00292 ns_dyn_mem_free(tls_heap->client_verify_buf); 00293 tls_heap->client_verify_buf = NULL; 00294 } 00295 00296 return ret_val; 00297 } 00298 #endif 00299 #ifdef ECC 00300 00301 void sec_ecc_state_free(sec_suite_t *suite) 00302 { 00303 if (active_ecc_sec_suite) { 00304 tr_debug("Active ECC"); 00305 if (suite == active_ecc_sec_suite) { 00306 tr_debug("Stop ECC"); 00307 ecc_free_memory(); 00308 active_ecc_sec_suite = NULL; 00309 } 00310 } 00311 } 00312 00313 00314 void sec_ecc_state_save(sec_suite_t *suite) 00315 { 00316 if (active_ecc_sec_suite == 0 && suite) { 00317 active_ecc_sec_suite = suite; 00318 //Send ECC event callback 00319 00320 arm_event_s event = { 00321 .receiver = protocol_read_tasklet_id(), 00322 .sender = 0, 00323 .event_type = ARM_IN_SECURITY_ECC_CALLER, 00324 .data_ptr = NULL, 00325 .priority = ARM_LIB_LOW_PRIORITY_EVENT, 00326 }; 00327 if (eventOS_event_send(&event) != 0) { 00328 tr_error("sec_ecc_state_save(): event send failed"); 00329 } 00330 } 00331 } 00332 00333 00334 uint8_t tls_certificate_build(sec_suite_t *suite) 00335 { 00336 buffer_t *buf; 00337 certificate_chain_internal_t *temp; 00338 uint16_t len = 0; 00339 00340 temp = sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN); 00341 00342 if (temp) { 00343 00344 len = tls_certificate_len(temp); 00345 len += 50; //TLS/EAP/PANA/TCP /IP 00346 00347 //Client Key Exchange 70, Certiverify max 80, Finnish 43 00348 len += (70 + 80 + 43); 00349 buf = buffer_get(len); //(690); 00350 00351 if (buf) { 00352 uint8_t *ptr; 00353 tls_msg_t *tmp_msg = tls_msg_ptr_get(); 00354 buf->interface = suite->interface; 00355 ptr = buffer_data_pointer(buf); 00356 //Leave Space for Tls Handshake Header 00357 ptr += 5; 00358 /* Set Certificate */ 00359 ptr = tls_certificate_msg_set(ptr, temp); 00360 /* Client Key Exchange */ 00361 ptr = tls_client_key_exchange_msg_set(ptr, suite->tls_session->tls_heap); 00362 00363 /* Certificate Verify */ 00364 if ((suite->setups & TLS_HANSHAKE_HASH) == 0) { 00365 uint8_t *ptr_2; 00366 ptr_2 = ptr; 00367 ptr_2 += 4; 00368 00369 tmp_msg->msg_ptr = ptr_2; 00370 ptr = tls_certificate_verify_msg_set(ptr, suite->tls_session->tls_heap); 00371 tr_debug("Set Cert Ver"); 00372 tmp_msg->len = ptr - ptr_2; 00373 tls_handshake_copy(tmp_msg, suite->tls_session->tls_heap); 00374 sec_prf_state_set(suite); 00375 00376 } else { 00377 ptr = tls_certificate_verify_msg_set(ptr, suite->tls_session->tls_heap); 00378 } 00379 00380 buffer_data_end_set(buf, ptr); 00381 00382 tls_header_set(buf); 00383 ptr = buffer_data_end(buf); 00384 if ((suite->setups & TLS_HANSHAKE_HASH) == 0) { 00385 uint8_t *ptr_2; 00386 ptr_2 = ptr; 00387 ptr_2 += 9; 00388 tmp_msg->msg_ptr = ptr; 00389 ptr = tls_build_change_chipher_suite_finnish_msg(ptr, suite->tls_session); 00390 tmp_msg->len = ptr - ptr_2; 00391 tls_handshake_copy(tmp_msg, suite->tls_session->tls_heap); 00392 suite->setups |= TLS_HANSHAKE_HASH; 00393 } else { 00394 ptr = tls_build_change_chipher_suite_finnish_msg(ptr, suite->tls_session); 00395 } 00396 buf->buf_end = ptr - buf->buf ; 00397 00398 tr_debug("TX Cer"); 00399 pana_eap_down(buf, suite); 00400 return 1; 00401 } 00402 } 00403 return 0; 00404 } 00405 #endif 00406 00407 #ifdef ECC 00408 void sec_ecc_sceduler(void) 00409 { 00410 if (ecc_run() != ECC_STATUS_IDLE) { 00411 arm_event_s event = { 00412 .receiver = protocol_read_tasklet_id(), 00413 .sender = 0, 00414 .event_type = ARM_IN_SECURITY_ECC_CALLER, 00415 .data_ptr = NULL, 00416 .priority = ARM_LIB_LOW_PRIORITY_EVENT, 00417 }; 00418 if (eventOS_event_send(&event) != 0) { 00419 tr_error("sec_ecc_sceduler(): event send failed"); 00420 } 00421 } 00422 } 00423 #ifdef PANA_SERVER_API 00424 uint8_t tls_pana_server_exchange_build(sec_suite_t *suite) 00425 { 00426 certificate_chain_internal_t *temp; 00427 buffer_t *buf; 00428 tls_heap_t *t_heap = suite->tls_session->tls_heap; 00429 uint16_t len = 39; 00430 00431 temp = sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN); 00432 00433 if (temp) { 00434 len += suite->tls_session->id_length; 00435 if (t_heap->tls_chipher_mode == CHIPHER_ECC) { 00436 len += 11; 00437 } else { 00438 len += 7; 00439 } 00440 00441 len += tls_certificate_len(temp); //Certi Len 00442 len += 240; //server key exchange 00443 len += 16; //Cert REQ & Hello Done 00444 00445 buf = buffer_get(len); 00446 if (buf) { 00447 uint8_t *ptr, *t_ptr; 00448 tls_msg_t *tmp_msg = tls_msg_ptr_get(); 00449 buf->interface = suite->interface; 00450 ptr = buffer_data_pointer(buf); 00451 ptr += 5; 00452 00453 //Server Hello build 00454 ptr = tls_build_server_hello_msg(ptr, suite->tls_session); 00455 // Certificate(s) 00456 ptr = tls_certificate_msg_set(ptr, temp); 00457 //Server Key Exchange 00458 tmp_msg->msg_ptr = ptr + 4; 00459 t_ptr = ptr; 00460 ptr = tls_server_key_excahnge_msg_build(ptr, t_heap); 00461 tmp_msg->len = ptr - t_ptr; 00462 tmp_msg->len -= 4; 00463 if ((suite->setups & TLS_HANSHAKE_HASH) == 0) { 00464 tls_handshake_copy(tmp_msg, t_heap); 00465 } 00466 //Cert Req 00467 *ptr++ = TLS_CERTIFICATE_REQUEST; 00468 ptr = common_write_24_bit(8, ptr); 00469 00470 tmp_msg->msg_ptr = ptr; 00471 *ptr++ = 1; //Type Count 00472 *ptr++ = TLS_CERT_TYPE_ECDSA; 00473 ptr = common_write_16_bit(2, ptr); //length 00474 ptr = common_write_16_bit(TLS_SIG_HASH_ALG_SHA256_ECDSA, ptr); //SET ALGORYTH 00475 ptr = common_write_16_bit(0, ptr); 00476 00477 00478 tmp_msg->len = 8; 00479 if ((suite->setups & TLS_HANSHAKE_HASH) == 0) { 00480 tls_handshake_copy(tmp_msg, t_heap); 00481 } 00482 00483 00484 //Server Hello Done 00485 *ptr++ = TLS_SERVER_HELLO_DONE; 00486 ptr = common_write_24_bit(0, ptr); 00487 tmp_msg->msg_ptr = ptr; 00488 tmp_msg->len = 0; 00489 if ((suite->setups & TLS_HANSHAKE_HASH) == 0) { 00490 tls_handshake_copy(tmp_msg, t_heap); 00491 suite->setups |= TLS_HANSHAKE_HASH; 00492 } 00493 buffer_data_end_set(buf, ptr); 00494 tls_header_set(buf); 00495 pana_eap_down(buf, suite); 00496 return 1; 00497 } 00498 } 00499 00500 return 0; 00501 } 00502 #endif 00503 00504 static int8_t ecc_signature_calculate_hash(tls_heap_t *theap) 00505 { 00506 tr_debug("sign hash:"); 00507 if (theap->ecc_heap) { 00508 //tr_debug("Allocate SIG"); 00509 if (theap->ecc_heap->sgnt == 0) { 00510 theap->ecc_heap->sgnt = ecc_get_ecdsa_signature(); 00511 } 00512 00513 if (!theap->ecc_heap->sgnt) { 00514 tr_warn("Signature Allocate Fail"); 00515 return -1; 00516 } 00517 } else { 00518 tr_warn("Signature Allocate Fail"); 00519 return -1; 00520 } 00521 tls_ecc_server_key_signature_hash(theap); 00522 tr_debug(" done"); 00523 return 0; 00524 00525 } 00526 #endif 00527 void sec_libray_init(void) 00528 { 00529 #ifdef ECC 00530 ecc_init(); 00531 #endif 00532 } 00533 00534 00535 static bool sec_suite_tls_allocate(sec_suite_t *suite) 00536 { 00537 tls_heap_t *tls_heap; 00538 tls_heap = tls_heap_allocate(); 00539 if (!tls_heap) { 00540 return false; 00541 } 00542 00543 suite->tls_session->tls_heap = tls_heap; 00544 if (suite->setups & TLS_SERVER_MODE) { 00545 if (suite->tls_session->id_length == 0) { 00546 tls_session_id_genrate(suite->tls_session->tls_session_id, 4); 00547 suite->tls_session->id_length = 4; 00548 } 00549 memset(suite->tls_session->tls_nonce_explit, 0, 8); 00550 } 00551 return true; 00552 } 00553 00554 static bool sec_suite_pana_allocate_dynamic_ram(sec_suite_t *suite) 00555 { 00556 ns_dyn_mem_free(suite->pana_session.pana_heap); 00557 suite->pana_session.pana_heap = pana_heap_structure_allocate(); 00558 if (!suite->pana_session.pana_heap) { 00559 return false; 00560 } 00561 return true; 00562 } 00563 00564 00565 int sec_pana_protocol_init(sec_suite_t *suite) 00566 { 00567 if (suite->tls_session == NULL) { 00568 suite->tls_session = amr_tls_session_allocate(); 00569 } 00570 00571 if (!suite->tls_session) { 00572 sec_lib_state_machine_trig(suite, PANA_ERROR); 00573 return 0; 00574 } 00575 //Initialize current TLS session data 00576 sec_suite_tls_free(suite, false); 00577 00578 pana_session_state_init(&suite->pana_session); 00579 suite->pana_session.prf_algorythm = 0; 00580 suite->pana_session.integrity_algorythm = 0; 00581 suite->pana_session.session_id = 0; 00582 suite->pana_session.req_seq = randLIB_get_32bit(); 00583 suite->pana_session.res_seq = 0; 00584 00585 //Free pana heap and init eap fragmentation 00586 pana_free_dynamic_ram(suite); 00587 00588 suite->setups &= ~TLS_HANSHAKE_HASH; 00589 suite->timer = 1; 00590 if (!sec_suite_tls_allocate(suite) || !sec_suite_pana_allocate_dynamic_ram(suite)) { 00591 sec_suite_tls_free(suite, true); 00592 sec_lib_state_machine_trig(suite, PANA_ERROR); 00593 return 0; 00594 } 00595 suite->state = PANA_PCI_TX; 00596 00597 return 1; 00598 } 00599 00600 00601 void sec_suite_tls_free(sec_suite_t *suite, bool free_session) 00602 { 00603 if (suite->tls_session) { 00604 arm_tls_session_clear(suite->tls_session); 00605 if (free_session) { 00606 ns_dyn_mem_free(suite->tls_session); 00607 suite->tls_session = NULL; 00608 } 00609 } 00610 suite->setups &= ~(TLS_ECC_CERTIFICATE_REQUESTED | TLS_ECC_CERTIFICATE_RECEIVED | TLS_ECC_CERTIFICATE_VERIFY); 00611 } 00612 00613 00614 uint8_t sec_auth_re_check(sec_suite_t *suite) 00615 { 00616 if (pana_retry_check(suite->retry_counter, suite->state) == 0) { 00617 suite->retry_counter++; 00618 return 1; 00619 } else { 00620 //Init back to zero after fail 00621 suite->retry_counter = 0; 00622 } 00623 return 0; 00624 } 00625 00626 uint8_t sec_check_suite_ptrs(sec_suite_t *suite) 00627 { 00628 uint8_t ret_val = 1; 00629 if (suite->pana_session.auth_info == 0) { 00630 if (!suite->pana_session.user_server) { 00631 tr_debug("AUTH Info!"); 00632 ret_val = 0; 00633 } 00634 } 00635 if (suite->tls_session) { 00636 if (suite->tls_session->tls_heap == 0) { 00637 tr_debug("TLS Heap!"); 00638 ret_val = 0; 00639 } 00640 } else { 00641 if (suite->state != PANA_PING_REQ) { 00642 ret_val = 0; 00643 tr_debug("No TLS session allocated"); 00644 } 00645 } 00646 return ret_val; 00647 00648 } 00649 00650 00651 00652 void sec_timer_handle(void) 00653 { 00654 ns_list_foreach_safe(sec_suite_t, cur, &sec_suite_list) { 00655 uint8_t remove_cur = 0; 00656 if (cur->timer && --cur->timer == 0) { 00657 pana_common_state_machine(cur); 00658 if ((cur->state == PANA_ERROR) && (cur->timer == 0)) { 00659 if (cur->setups & TLS_SERVER_MODE) { 00660 remove_cur = 1; 00661 } 00662 } 00663 } 00664 if (remove_cur) { 00665 tr_debug("Remove Session"); 00666 sec_suite_remove(cur); 00667 } 00668 } 00669 //Here Possible to set 1 Second delay 00670 pana_key_update_delay_timer(); 00671 } 00672 00673 void sec_suite_list_clean(void) 00674 { 00675 ns_list_foreach_safe(sec_suite_t, cur, &sec_suite_list) { 00676 sec_suite_remove(cur); 00677 } 00678 00679 } 00680 00681 sec_suite_t *sec_suite_verify(sec_suite_t *session) 00682 { 00683 ns_list_foreach(sec_suite_t, cur, &sec_suite_list) { 00684 if (cur == session) { 00685 return cur; 00686 } 00687 } 00688 return NULL; 00689 } 00690 00691 sec_suite_t *sec_suite_selected_py_pan_id(uint16_t pan_id) 00692 { 00693 ns_list_foreach(sec_suite_t, cur, &sec_suite_list) { 00694 if (cur->pan_id == pan_id) { 00695 return cur; 00696 } 00697 } 00698 return NULL; 00699 } 00700 00701 sec_suite_t *sec_suite_selected_pana_session(uint32_t session_id) 00702 { 00703 ns_list_foreach(sec_suite_t, cur, &sec_suite_list) { 00704 if (cur->pana_session.session_id == session_id) { 00705 return cur; 00706 } 00707 } 00708 return NULL; 00709 } 00710 00711 sec_suite_t *sec_suite_selected_address(const uint8_t address[static 16]) 00712 { 00713 ns_list_foreach(sec_suite_t, cur, &sec_suite_list) { 00714 if (memcmp(cur->session_address, address, 16) == 0) { 00715 return cur; 00716 } 00717 } 00718 return NULL; 00719 } 00720 00721 uint16_t sec_pana_key_update_trig(uint16_t th_time) 00722 { 00723 uint32_t trig_interval = 1; 00724 uint16_t counter = 0; 00725 uint32_t threshold_change; 00726 //Convert seconds to 100ms ticks 00727 threshold_change = (th_time * 10); 00728 ns_list_foreach(sec_suite_t, cur, &sec_suite_list) { 00729 if (cur->pana_session.session_ready) { 00730 if ((cur->pana_session.address_status & 3) == 0) { // 00731 tr_debug("Trig Key Update"); 00732 cur->timer = trig_interval; 00733 trig_interval += threshold_change; 00734 cur->state = PANA_KEY_UPDATE; 00735 cur->retry_counter = 0; 00736 tr_debug("NVM SEQ Update by Key Push"); 00737 pana_session_nvm_udate(cur, PANA_SERVER_CLIENT_SESSION_UPDATE); 00738 //Clear Current value 00739 cur->retry_counter = 0; 00740 counter++; 00741 } 00742 } 00743 } 00744 return counter; 00745 } 00746 00747 int8_t sec_suite_remove(sec_suite_t *cur) 00748 { 00749 if (!cur) { 00750 return -1; 00751 } 00752 00753 pana_free_dynamic_ram(cur); 00754 00755 sec_suite_tls_free(cur, true); 00756 #ifdef ECC 00757 sec_ecc_state_free(cur); 00758 #endif 00759 ns_list_remove(&sec_suite_list, cur); 00760 ns_dyn_mem_free(cur); 00761 return 0; 00762 } 00763 00764 sec_suite_t *sec_suite_create(void) 00765 { 00766 sec_suite_t *cur = sec_lib_security_session_allocate(true); 00767 if (!cur) { 00768 return NULL; 00769 } 00770 tls_heap_t *t_heap = tls_heap_allocate(); 00771 pana_heap_t *p_heap = pana_heap_structure_allocate(); 00772 00773 if (!t_heap || !p_heap) { 00774 ns_list_remove(&sec_suite_list, cur); 00775 ns_dyn_mem_free(t_heap); 00776 ns_dyn_mem_free(t_heap); 00777 ns_dyn_mem_free(p_heap); 00778 ns_dyn_mem_free(cur); 00779 return NULL; 00780 } 00781 00782 cur->tls_session->tls_heap = t_heap; 00783 cur->pana_session.pana_heap = p_heap; 00784 return cur; 00785 } 00786 00787 00788 00789 void sec_prf_state_set(sec_suite_t *suite) 00790 { 00791 if (suite->tls_session) { 00792 tls_heap_t *tls_heap = suite->tls_session->tls_heap; 00793 sec_lib_state_machine_lock(suite, PRF_CALC); 00794 tls_master_key_cal(tls_heap, suite); 00795 tls_key_expansion_cal(tls_heap, suite->tls_session->key_expansion, suite->tls_session->master_secret); 00796 tls_MSK_calc(suite); 00797 tls_hanshake_hash_cal(tls_heap); 00798 00799 if (suite->setups & TLS_SERVER_MODE) { 00800 #ifdef PANA_SERVER_API 00801 tls_verify_calc(tls_heap->verify, 0, tls_heap, suite->tls_session->master_secret); 00802 if (tls_check_client_change_chiphersuite(tls_heap->verify, suite) != 0) { 00803 sec_lib_state_machine_trig(suite, TLS_ALERT_DECRYPT); 00804 } 00805 #endif 00806 } else { 00807 tls_verify_calc(tls_heap->verify, 0, tls_heap, suite->tls_session->master_secret); 00808 if (tls_heap->tls_chipher_mode != CHIPHER_ECC) { 00809 sec_lib_state_machine_trig(suite, TLS_KEY_CHANGE); 00810 } else { 00811 tls_prepare_change_chipher_spec(suite); 00812 } 00813 } 00814 } 00815 } 00816 #ifdef ECC 00817 static void tls_key_set_elliptic_point(EllipticPoint *ellicpt_ptr, uint8_t *keyPtr) 00818 { 00819 tls_ecc_point_reverse_order((uint8_t *)ellicpt_ptr->x.data, keyPtr); 00820 tls_ecc_point_reverse_order((uint8_t *)ellicpt_ptr->y.data, (keyPtr + 32)); 00821 } 00822 00823 uint8_t tls_ecc_start_premaster_secret(EllipticPoint *ellicpt_ptr, sec_suite_t *suite) 00824 { 00825 uint8_t auth_setup = suite->setups; 00826 if (ellicpt_ptr == 0) { 00827 ellicpt_ptr = ecc_get_elliptic_point(); 00828 } else { 00829 memset(ellicpt_ptr, 0, sizeof(EllipticPoint)); 00830 ellicpt_ptr->finite = 1; 00831 } 00832 00833 if (ellicpt_ptr) { 00834 tls_heap_t *tls_heap = suite->tls_session->tls_heap; 00835 tr_debug("Cal ECC PSK"); 00836 if ((auth_setup & TLS_SERVER_MODE) == 0) { 00837 tls_key_set_elliptic_point(ellicpt_ptr, tls_heap->ecc_heap->server_public_key); 00838 } else { 00839 tls_key_set_elliptic_point(ellicpt_ptr, tls_heap->ecc_heap->client_public_key); 00840 } 00841 if (ecc_calculate_pre_master_secret(ellicpt_ptr, &(tls_heap->ecc_heap->private_key), &ecc_operation_done_callback) == ECC_STATUS_OK) { 00842 //tr_debug("PRE started"); 00843 sec_lib_state_machine_lock(suite, TLS_ECC_GENERATE_PREMASTER_SECRET); 00844 sec_ecc_state_save(suite); 00845 return 1; 00846 } else { 00847 tr_debug("Failed pre start"); 00848 ecc_library_free_pointer(ellicpt_ptr); 00849 } 00850 } 00851 00852 return 0; 00853 } 00854 00855 void ecc_operation_done_callback(int8_t status, void *result_ptr) 00856 { 00857 uint8_t alert = 0; 00858 sec_suite_t *suite = active_ecc_sec_suite; 00859 active_ecc_sec_suite = NULL; 00860 //tr_debug("ECC CB"); 00861 if (status != ECC_STATUS_OK) { 00862 tr_warn("ECC proces Fail: %i", status); 00863 if (result_ptr) { 00864 tr_debug("Free ECC Result"); 00865 ecc_library_free_pointer(result_ptr); 00866 } 00867 ecc_free_memory(); 00868 alert = 1; 00869 if (suite == 0) { 00870 tr_warn("NOt active ECC2!!"); 00871 return ; 00872 } 00873 } else { 00874 tls_heap_t *tls_heap = 0; 00875 if (suite == 0) { 00876 tr_warn("NOt active ECC!!"); 00877 return ; 00878 } 00879 00880 tls_heap = suite->tls_session->tls_heap; 00881 00882 switch (suite->state) { 00883 00884 00885 case TLS_ECC_CERTIFICATE_SIGNATURE_CHECK: 00886 if (tls_heap->ecc_heap->sgnt == 0) { 00887 tls_heap->ecc_heap->sgnt = ecc_get_ecdsa_signature(); 00888 } 00889 if (!tls_heap->ecc_heap->sgnt) { 00890 tr_warn("Signature Fail"); 00891 alert = 1; 00892 } else { 00893 00894 tls_certificate_signature_verify(suite); 00895 } 00896 00897 break; 00898 00899 case TLS_ECC_MESSAGE_VERIFY: 00900 if (suite->setups & TLS_SERVER_MODE) { 00901 tr_debug("Certi verify valid"); 00902 if (tls_ecc_start_premaster_secret(0, suite) == 0) { 00903 tr_debug("Pre sec start fail"); 00904 alert = 1; 00905 } 00906 } else { 00907 tr_debug("Server Key valid"); 00908 if (ecc_calculate_public_key(&(tls_heap->ecc_heap->private_key), &ecc_operation_done_callback) == ECC_STATUS_OK) { 00909 sec_lib_state_machine_lock(suite, TLS_ECC_GENERATE_PUBLIC_KEY); 00910 sec_ecc_state_save(suite); 00911 } else { 00912 alert = 2; 00913 } 00914 00915 } 00916 00917 break; 00918 case TLS_ECC_CERTIFICATE_VERIFY_SIGNATURE: 00919 if (!result_ptr) { 00920 alert = 1; 00921 } else { 00922 tls_heap->ecc_heap->sgnt = result_ptr; 00923 suite->setups &= ~TLS_HANSHAKE_HASH; 00924 sec_lib_state_machine_trig(suite, TLS_CLIENT_TX_CERTIFICATE_VERIFY); 00925 } 00926 active_ecc_sec_suite = 0; 00927 break; 00928 case TLS_ECC_GENERATE_PUBLIC_KEY: { 00929 uint8_t *temp_ptr; 00930 EllipticPoint *result; 00931 result = result_ptr; 00932 00933 //Save Result 00934 if (suite->setups & TLS_SERVER_MODE) { 00935 temp_ptr = tls_heap->ecc_heap->server_public_key; 00936 } else { 00937 temp_ptr = tls_heap->ecc_heap->client_public_key; 00938 00939 } 00940 if (result) { 00941 tls_ecc_point_reverse_order(temp_ptr, (uint8_t *)result->x.data); 00942 tls_ecc_point_reverse_order((temp_ptr + 32), (uint8_t *)result->y.data); 00943 } 00944 00945 if (suite->setups & TLS_SERVER_MODE) { 00946 if (result) { 00947 ecc_library_free_pointer(result); 00948 result = 0; 00949 } 00950 //Cal Signature 00951 if (ecc_signature_calculate_hash(tls_heap) == 0) { 00952 //SET Array to MPINT 00953 uint8_t *ptr = NULL; 00954 certificate_chain_internal_t *temp; 00955 00956 00957 temp = sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN); 00958 00959 if (temp) { 00960 ptr = x509_get_key_from_pki((uint8_t *) temp->key_chain[(temp->chain_length - 1)], 0); 00961 } 00962 00963 if (ptr) { 00964 uint8_t i; 00965 memset(&temp_key_entry.data, 0, MPINT_DATA_SIZE); 00966 00967 //Revert bytes 00968 for (i = 0; i < 32; i++) { 00969 *(((uint8_t *)&temp_key_entry.data) + i) = ptr[31 - i]; 00970 } 00971 status = ecc_calculate_signature(tls_heap->ecc_heap->sgnt, (MPint *) &temp_key_entry, &ecc_operation_done_callback); 00972 if (status == ECC_STATUS_OK) { 00973 tls_heap->ecc_heap->sgnt = 0; 00974 sec_lib_state_machine_lock(suite, TLS_ECC_SIGNATURE_MESSAGE); 00975 sec_ecc_state_save(suite); 00976 } else { 00977 tr_warn("SigNature start Fail"); 00978 alert = 3; 00979 } 00980 } else { 00981 alert = 4; 00982 } 00983 } else { 00984 //Alert 00985 tr_debug("ECC Error"); 00986 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00987 alert = 4; 00988 } 00989 00990 00991 } else { 00992 //Calculate PreMaster Secret 00993 if (result == NULL) { 00994 alert = 5; 00995 } else { 00996 if (tls_ecc_start_premaster_secret(result, suite) == 0) { 00997 alert = 5; 00998 result = 0; 00999 01000 } 01001 } 01002 } 01003 } 01004 01005 break; 01006 01007 case TLS_ECC_GENERATE_PREMASTER_SECRET: { 01008 EllipticPoint *result; 01009 result = result_ptr; 01010 01011 if (result) { 01012 tls_ecc_point_reverse_order(tls_heap->ecc_heap->pre_secret_mat, (uint8_t *)result->x.data); 01013 ecc_library_free_pointer(result); 01014 } 01015 active_ecc_sec_suite = 0; 01016 if ((suite->setups & TLS_SERVER_MODE) == 0) { 01017 suite->setups &= ~TLS_HANSHAKE_HASH; 01018 sec_lib_state_machine_trig(suite, TLS_UPDATE_HAS_WITH_CERTIFICATE); 01019 } else { 01020 sec_prf_state_set(suite); 01021 } 01022 } 01023 break; 01024 01025 case TLS_ECC_SIGNATURE_MESSAGE: 01026 active_ecc_sec_suite = 0; 01027 if (!result_ptr) { 01028 alert = 1; 01029 } else { 01030 tls_heap->ecc_heap->sgnt = result_ptr; 01031 01032 #ifdef PANA_SERVER_API 01033 if (suite->setups & TLS_SERVER_MODE) { 01034 suite->setups &= ~TLS_HANSHAKE_HASH; 01035 sec_lib_state_machine_trig(suite, TLS_TX_SERVER_KEY_EXCHANGE); 01036 } 01037 #endif 01038 } 01039 01040 break; 01041 default: 01042 01043 break; 01044 01045 } 01046 } 01047 if (alert) { 01048 tr_debug("State: %x, Alert: %x", suite->state, alert); 01049 if (suite->state == 0x15) { 01050 sec_lib_state_machine_trig(suite, TLS_ALERT_BAD_CERTIFICATE); 01051 } else { 01052 sec_lib_state_machine_trig(suite, TLS_ALERT_DECRYPT); 01053 } 01054 active_ecc_sec_suite = 0; 01055 } 01056 } 01057 void sec_ecc_client_signature_start(sec_suite_t *suite) 01058 { 01059 uint8_t trig_alert = 0; 01060 if (ecc_state_idle_check() == ECC_STATUS_OK) { 01061 //Signature 01062 tls_heap_t *tls_heap = suite->tls_session->tls_heap; 01063 ECDSASignature *sgnt; 01064 tr_debug("HASH Calc for Cert Verify"); 01065 tls_hanshake_hash_cal(tls_heap); 01066 01067 if (tls_heap->ecc_heap->sgnt == 0) { 01068 sgnt = ecc_get_ecdsa_signature(); 01069 } else { 01070 sgnt = tls_heap->ecc_heap->sgnt; 01071 tls_heap->ecc_heap->sgnt = 0; 01072 } 01073 01074 if (sgnt) { 01075 certificate_chain_internal_t *temp; 01076 uint8_t *ptr = 0; 01077 memset((uint8_t *) sgnt->m_m.data, 0, sizeof(MPint)); 01078 tls_ecc_point_reverse_order((uint8_t *) sgnt->m_m.data, (uint8_t *)tls_heap->hash_buf); 01079 01080 temp = sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN); 01081 01082 01083 ptr = x509_get_key_from_pki((uint8_t *)temp->key_chain[(temp->chain_length - 1)], 0); 01084 if (ptr) { 01085 uint8_t i; 01086 memset(&temp_key_entry.data, 0, MPINT_DATA_SIZE); 01087 01088 //Revert bytes 01089 for (i = 0; i < 32; i++) { 01090 *(((uint8_t *)&temp_key_entry.data) + i) = ptr[31 - i]; 01091 } 01092 01093 if (ecc_calculate_signature(sgnt, (MPint *) &temp_key_entry, &ecc_operation_done_callback) == ECC_STATUS_OK) { 01094 tr_debug("Certi verify"); 01095 sec_lib_state_machine_lock(suite, TLS_ECC_CERTIFICATE_VERIFY_SIGNATURE); 01096 sec_ecc_state_save(suite); 01097 } else { 01098 tr_warn("Signature start Fail"); 01099 ns_dyn_mem_free(sgnt); 01100 trig_alert = 1; 01101 } 01102 } else { 01103 tr_warn("Key get Fail"); 01104 ns_dyn_mem_free(sgnt); 01105 trig_alert = 1; 01106 } 01107 } else { 01108 tr_warn("Signature Allocate Fail"); 01109 trig_alert = 1; 01110 } 01111 if (trig_alert) { 01112 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 01113 } 01114 } else { 01115 //tr_debug("ECC Busy Wait1"); 01116 sec_lib_state_machine_trig(suite, TLS_ECC_CLIENT_SIGNATURE_START); 01117 } 01118 } 01119 void sec_ecc_gen_public_key_start(sec_suite_t *suite) 01120 { 01121 tls_heap_t *tls_heap = suite->tls_session->tls_heap; 01122 01123 if (ecc_calculate_public_key(&(tls_heap->ecc_heap->private_key), &ecc_operation_done_callback) == ECC_STATUS_OK) { 01124 sec_lib_state_machine_lock(suite, TLS_ECC_GENERATE_PUBLIC_KEY); 01125 sec_ecc_state_save(suite); 01126 } else { 01127 sec_lib_state_machine_trig(suite, TLS_ECC_GENERATE_PUBLIC_KEY_START); 01128 } 01129 } 01130 #endif 01131 01132 void eap_fragmentation_init(sec_suite_t *suite) 01133 { 01134 if (suite->pana_session.eap_frag_buf) { 01135 buffer_free(suite->pana_session.eap_frag_buf); 01136 suite->pana_session.eap_frag_buf = NULL; 01137 } 01138 suite->pana_session.frag_length = 0; 01139 if (suite->pana_session.eap_assy_buf) { 01140 buffer_free(suite->pana_session.eap_assy_buf); 01141 suite->pana_session.eap_assy_buf = NULL; 01142 } 01143 suite->pana_session.assy_length = 0; 01144 } 01145 01146 #ifdef ECC 01147 static void seclib_stop_ecc(sec_suite_t *suite) 01148 { 01149 if (active_ecc_sec_suite) { 01150 if (suite == active_ecc_sec_suite) { 01151 tr_debug("Stop ECC"); 01152 ecc_free_memory(); 01153 active_ecc_sec_suite = 0; 01154 } 01155 } 01156 } 01157 #endif 01158 01159 void seclib_session_clean(sec_suite_t *suite) 01160 { 01161 suite->timer = 0; 01162 suite->pana_session.auth_info = NULL; 01163 pana_free_dynamic_ram(suite); 01164 sec_suite_tls_free(suite, true); 01165 #ifdef ECC 01166 seclib_stop_ecc(suite); 01167 #endif 01168 } 01169 01170 01171 uint8_t sec_suite_socket_event(uint8_t event_type, sec_suite_t *suite) 01172 { 01173 suite = sec_suite_verify(suite); 01174 if (!suite) { 01175 return 0; 01176 } 01177 01178 if (event_type == SOCKET_TX_DONE) { 01179 sec_tx_done(suite); 01180 } else { 01181 tr_debug("SEC Suite CB event. Event type: %x", event_type); 01182 suite->timer = 15; 01183 } 01184 return 1; 01185 } 01186 01187 void sec_set_auth_timeout(sec_suite_t *suite, sec_state_machine_t cur_state) 01188 { 01189 suite->retry_counter = pana_retry_req_max_get(); 01190 suite->timer = pana_handshake_timeout(); 01191 suite->state = cur_state; 01192 } 01193 01194 static void sec_tx_done(sec_suite_t *suite) 01195 { 01196 sec_state_machine_t cur_state = suite->state; 01197 if (suite->timer) { 01198 if (cur_state != TLS_INIT) { 01199 switch (cur_state) { 01200 #ifdef ECC 01201 #ifdef PANA_SERVER_API 01202 case TLS_TX_SERVER_KEY_EXCHANGE: 01203 pana_timeout_timer_set(suite, suite->state); 01204 break; 01205 #endif 01206 01207 case TLS_CLIENT_TX_CERTIFICATE_VERIFY: 01208 if ((suite->setups & TLS_SERVER_MODE) == 0) { 01209 sec_set_auth_timeout(suite, TLS_KEY_CHANGE); 01210 } else { 01211 sec_lib_state_machine_trig(suite, PANA_READY); 01212 } 01213 break; 01214 #endif 01215 case PANA_FAILURE: 01216 if (suite->setups & TLS_SERVER_MODE) { 01217 pana_timeout_timer_set(suite, suite->state); 01218 } else { 01219 sec_lib_state_machine_trig(suite, PANA_ERROR); 01220 } 01221 break; 01222 01223 case TLS_SERVER_TX_SERVER_HELLO: 01224 sec_set_auth_timeout(suite, TLS_SERVER_WAIT_CHANGE_CHIPHERSUITE); 01225 break; 01226 01227 case TLS_KEY_CHANGE: 01228 if ((suite->setups & TLS_SERVER_MODE) == 0) { 01229 sec_set_auth_timeout(suite, TLS_KEY_CHANGE); 01230 } else { 01231 01232 tr_debug("Wait EAP RESPONSE"); 01233 pana_timeout_timer_set(suite, suite->state); 01234 } 01235 break; 01236 case TLS_FINISH: 01237 if (suite->setups & TLS_SERVER_MODE) { 01238 pana_timeout_timer_set(suite, suite->state); 01239 } else { 01240 sec_set_auth_timeout(suite, TLS_FINISH); 01241 } 01242 break; 01243 01244 01245 case TLS_ALERT_INTERNAL: 01246 case TLS_ALERT_CHIPHER_SUITE: 01247 case TLS_ALERT_DECRYPT: 01248 case TLS_ALERT_BAD_CERTIFICATE: 01249 01250 tr_debug("Alert TX Done. cur_state: %x", cur_state); 01251 suite->state = PANA_FAILURE; 01252 suite->timer = 15; 01253 suite->retry_counter = 0; 01254 break; 01255 01256 case PANA_PCI_TX: 01257 case PANA_KEY_UPDATE: 01258 case PANA_PING_REQ: 01259 case PANA_KEY_PULL: 01260 case EAP_IDENTITY_REQ: 01261 case PANA_REQUEST_TX: 01262 case TLS_START: 01263 case TLS_EAP_END_PANA_VERIFY: 01264 pana_timeout_timer_set(suite, suite->state); 01265 break; 01266 case EAP_IDENTITY_RES: 01267 case PANA_START_RESPONSE: 01268 case PANA_READY: 01269 break; 01270 01271 default: 01272 tr_debug("unknown cur_state: %x", cur_state); 01273 suite->timer = 100; 01274 break; 01275 } 01276 } 01277 } 01278 } 01279 01280 #endif 01281 01282 01283 //************************ECC Certificates end
Generated on Tue Jul 12 2022 13:54:49 by
