Toyomasa Watarai
/
Mbed-example-WS-W27
Mbed Cloud example program for workshop in W27 2018.
Embed:
(wiki syntax)
Show/hide line numbers
arm_uc_crypto.c
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2017 ARM Ltd. 00003 // 00004 // SPDX-License-Identifier: Apache-2.0 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the "License"); 00007 // you may not use this file except in compliance with the License. 00008 // You may obtain a copy of the License at 00009 // 00010 // http://www.apache.org/licenses/LICENSE-2.0 00011 // 00012 // Unless required by applicable law or agreed to in writing, software 00013 // distributed under the License is distributed on an "AS IS" BASIS, 00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 // See the License for the specific language governing permissions and 00016 // limitations under the License. 00017 // ---------------------------------------------------------------------------- 00018 00019 #include "update-client-common/arm_uc_config.h" 00020 #include "update-client-common/arm_uc_error.h" 00021 #include "update-client-common/arm_uc_crypto.h" 00022 00023 #include <string.h> 00024 00025 00026 #if ARM_UC_USE_PAL_CRYPTO 00027 #include "pal.h" 00028 #ifndef palMDHandle_t 00029 #include "pal_Crypto.h" 00030 #endif 00031 00032 #define ARM_UC_CU_SHA256 PAL_SHA256 00033 arm_uc_error_t ARM_UC_verifyPkSignature(const arm_uc_buffer_t* ca, const arm_uc_buffer_t* hash, const arm_uc_buffer_t* sig) 00034 { 00035 arm_uc_error_t err = {MFST_ERR_CERT_INVALID}; 00036 palX509Handle_t x509Cert; 00037 if (PAL_SUCCESS == pal_x509Initiate(&x509Cert)) 00038 { 00039 err.code = MFST_ERR_CERT_INVALID; 00040 if (PAL_SUCCESS == pal_x509CertParse(x509Cert, ca->ptr, ca->size)) 00041 { 00042 // if (PAL_SUCCESS == pal_x509CertVerify(x509Cert, palX509Handle_t x509CertChain)) 00043 // { 00044 err.code = MFST_ERR_INVALID_SIGNATURE; 00045 if (PAL_SUCCESS == pal_verifySignature(x509Cert, PAL_SHA256, hash->ptr, hash->size, sig->ptr, sig->size)) 00046 { 00047 err.code = MFST_ERR_NONE; 00048 } 00049 // } 00050 } 00051 pal_x509Free(&x509Cert); 00052 } 00053 return err; 00054 } 00055 00056 arm_uc_error_t ARM_UC_cryptoHashSetup(arm_uc_mdHandle_t* hDigest, arm_uc_mdType_t mdType) 00057 { 00058 arm_uc_error_t result = (arm_uc_error_t){ ARM_UC_CU_ERR_INVALID_PARAMETER }; 00059 if (hDigest) 00060 { 00061 palStatus_t rc = pal_mdInit(hDigest, mdType); 00062 if (rc == PAL_SUCCESS) 00063 { 00064 result.code = ARM_UC_CU_ERR_NONE; 00065 } 00066 } 00067 return result; 00068 } 00069 00070 arm_uc_error_t ARM_UC_cryptoHashUpdate(arm_uc_mdHandle_t* hDigest, arm_uc_buffer_t* input) 00071 { 00072 arm_uc_error_t result = (arm_uc_error_t){ ARM_UC_CU_ERR_INVALID_PARAMETER }; 00073 if (hDigest && input) 00074 { 00075 palStatus_t rc = pal_mdUpdate(*hDigest, input->ptr, input->size); 00076 if (rc == PAL_SUCCESS) 00077 { 00078 result = (arm_uc_error_t){ ARM_UC_CU_ERR_NONE }; 00079 } 00080 } 00081 return result; 00082 } 00083 00084 arm_uc_error_t ARM_UC_cryptoHashFinish(arm_uc_mdHandle_t* hDigest, arm_uc_buffer_t* output) 00085 { 00086 arm_uc_error_t result = (arm_uc_error_t){ ARM_UC_CU_ERR_INVALID_PARAMETER }; 00087 00088 // TODO: validate buffer size? I guess we just hope for the best! 00089 if (hDigest && output && output->size_max >= 256/8) // FIXME:PAL does not provide a method to extract this 00090 { 00091 palStatus_t rc = pal_mdFinal(*hDigest, output->ptr); 00092 00093 if (rc == PAL_SUCCESS) 00094 { 00095 result = (arm_uc_error_t){ ARM_UC_CU_ERR_NONE }; 00096 output->size = 256/8; // FIXME:PAL does not provide a method to extract this 00097 } 00098 } 00099 if (hDigest) 00100 { 00101 palStatus_t rc = pal_mdFree(hDigest); 00102 if (rc != PAL_SUCCESS && result.error == ERR_NONE) 00103 { 00104 result.module = TWO_CC('P','A'); 00105 result.error = rc; 00106 } 00107 } 00108 return result; 00109 } 00110 arm_uc_error_t ARM_UC_cryptoDecryptSetup(arm_uc_cipherHandle_t* hCipher, arm_uc_buffer_t* key, arm_uc_buffer_t* iv, int32_t aesKeySize) 00111 { 00112 arm_uc_error_t result = (arm_uc_error_t){ ARM_UC_CU_ERR_INVALID_PARAMETER }; 00113 00114 if (key && key->ptr && iv && iv->ptr) 00115 { 00116 palStatus_t rc = 1; 00117 00118 switch (aesKeySize) 00119 { 00120 case 128: 00121 case 256: 00122 { 00123 rc = pal_initAes(&hCipher->aes_context); 00124 /* NOTE: From the mbedtls documentation: 00125 * Due to the nature of CTR you should use the same key schedule for 00126 * both encryption and decryption. So a context initialized with 00127 * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. 00128 */ 00129 if (rc == PAL_SUCCESS) 00130 { 00131 rc = pal_setAesKey(hCipher->aes_context, key->ptr, aesKeySize, PAL_KEY_TARGET_DECRYPTION); 00132 } 00133 hCipher->aes_iv = iv->ptr; 00134 break; 00135 } 00136 default: 00137 // rc is still 1, this means the function returns Invalid Parameter 00138 break; 00139 } 00140 00141 if (rc == PAL_SUCCESS) 00142 { 00143 result = (arm_uc_error_t){ ARM_UC_CU_ERR_NONE }; 00144 } 00145 } 00146 00147 return result; 00148 } 00149 arm_uc_error_t ARM_UC_cryptoDecryptUpdate(arm_uc_cipherHandle_t* hCipher, const uint8_t* input_ptr, uint32_t input_size, arm_uc_buffer_t* output) 00150 { 00151 arm_uc_error_t result = (arm_uc_error_t){ ARM_UC_CU_ERR_INVALID_PARAMETER }; 00152 size_t data_size = input_size < output->size_max ? input_size : output->size_max; 00153 output->size = 0; 00154 palStatus_t rc = pal_aesCTR( 00155 hCipher->aes_context, 00156 input_ptr, 00157 output->ptr, 00158 data_size, 00159 hCipher->aes_iv 00160 ); 00161 if (rc == PAL_SUCCESS) 00162 { 00163 result = (arm_uc_error_t){ ARM_UC_CU_ERR_NONE }; 00164 output->size = data_size; 00165 } 00166 return result; 00167 } 00168 arm_uc_error_t ARM_UC_cryptoDecryptFinish(arm_uc_cipherHandle_t* hCipher, arm_uc_buffer_t* output) 00169 { 00170 pal_freeAes(&hCipher->aes_context); 00171 (void) output; 00172 return (arm_uc_error_t){ARM_UC_CU_ERR_NONE}; 00173 } 00174 00175 #else 00176 arm_uc_error_t ARM_UC_verifyPkSignature(const arm_uc_buffer_t* ca, const arm_uc_buffer_t* hash, const arm_uc_buffer_t* sig) 00177 { 00178 int rc = 1; 00179 arm_uc_error_t err = {MFST_ERR_NONE}; 00180 mbedtls_x509_crt crt; 00181 mbedtls_x509_crt_init(&crt); 00182 rc = mbedtls_x509_crt_parse_der(&crt, ca->ptr, ca->size); 00183 if (rc < 0) { 00184 err.code = MFST_ERR_CERT_INVALID; 00185 } else { 00186 rc = mbedtls_pk_verify(&crt.pk, MBEDTLS_MD_SHA256, hash->ptr, hash->size, sig->ptr, sig->size); 00187 if (rc < 0) { 00188 err.code = MFST_ERR_INVALID_SIGNATURE; 00189 } 00190 } 00191 return err; 00192 } 00193 arm_uc_error_t ARM_UC_cryptoHashSetup(arm_uc_mdHandle_t* hDigest, arm_uc_mdType_t mdType) 00194 { 00195 arm_uc_error_t result = (arm_uc_error_t){ ARM_UC_CU_ERR_INVALID_PARAMETER }; 00196 00197 const mbedtls_md_info_t* md_info = NULL; 00198 int mbedtls_result = 1; 00199 00200 if (hDigest) 00201 { 00202 mbedtls_md_init(hDigest); 00203 md_info = mbedtls_md_info_from_type(mdType); 00204 mbedtls_result = mbedtls_md_setup(hDigest, md_info, 0); 00205 mbedtls_result |= mbedtls_md_starts(hDigest); 00206 00207 if (mbedtls_result == 0) 00208 { 00209 result = (arm_uc_error_t){ ARM_UC_CU_ERR_NONE }; 00210 } 00211 } 00212 00213 return result; 00214 } 00215 00216 arm_uc_error_t ARM_UC_cryptoHashUpdate(arm_uc_mdHandle_t* hDigest, arm_uc_buffer_t* input) 00217 { 00218 arm_uc_error_t result = (arm_uc_error_t){ ARM_UC_CU_ERR_INVALID_PARAMETER }; 00219 00220 if (hDigest && input) 00221 { 00222 int mbedtls_result = 1; 00223 00224 mbedtls_result = mbedtls_md_update(hDigest, input->ptr, input->size); 00225 00226 if (mbedtls_result == 0) 00227 { 00228 result = (arm_uc_error_t){ ARM_UC_CU_ERR_NONE }; 00229 } 00230 } 00231 00232 return result; 00233 } 00234 arm_uc_error_t ARM_UC_cryptoHashFinish(arm_uc_mdHandle_t* hDigest, arm_uc_buffer_t* output) 00235 { 00236 arm_uc_error_t result = (arm_uc_error_t){ ARM_UC_CU_ERR_INVALID_PARAMETER }; 00237 00238 if (hDigest && output && (output->size_max >= (unsigned)hDigest->md_info->size)) 00239 { 00240 int mbedtls_result = 1; 00241 00242 mbedtls_result = mbedtls_md_finish(hDigest, output->ptr); 00243 00244 if (mbedtls_result == 0) 00245 { 00246 result = (arm_uc_error_t){ ARM_UC_CU_ERR_NONE }; 00247 00248 output->size = hDigest->md_info->size; 00249 } 00250 } 00251 00252 // free memory 00253 mbedtls_md_free(hDigest); 00254 00255 return result; 00256 } 00257 00258 arm_uc_error_t ARM_UC_cryptoDecryptSetup(arm_uc_cipherHandle_t* hCipher, arm_uc_buffer_t* key, arm_uc_buffer_t* iv, int32_t aesKeySize) 00259 { 00260 arm_uc_error_t result = (arm_uc_error_t){ ARM_UC_CU_ERR_INVALID_PARAMETER }; 00261 00262 if (key && key->ptr && iv && iv->ptr) 00263 { 00264 int mbedtls_result = 1; 00265 00266 switch (aesKeySize) 00267 { 00268 case 128: 00269 case 256: 00270 { 00271 memset(hCipher->aes_partial, 0, sizeof(hCipher->aes_partial)); 00272 hCipher->aes_nc_off = 0; 00273 mbedtls_aes_init(&hCipher->aes_context); 00274 /* NOTE: From the mbedtls documentation: 00275 * Due to the nature of CTR you should use the same key schedule for 00276 * both encryption and decryption. So a context initialized with 00277 * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. 00278 */ 00279 mbedtls_result = mbedtls_aes_setkey_enc(&hCipher->aes_context, key->ptr, aesKeySize); 00280 hCipher->aes_iv = iv->ptr; 00281 break; 00282 } 00283 default: 00284 // mbedtls_result is still 1, this means the function returns Invalid Parameter 00285 break; 00286 } 00287 00288 if (mbedtls_result == 0) 00289 { 00290 result = (arm_uc_error_t){ ARM_UC_CU_ERR_NONE }; 00291 } 00292 } 00293 00294 return result; 00295 } 00296 arm_uc_error_t ARM_UC_cryptoDecryptUpdate(arm_uc_cipherHandle_t* hCipher, const uint8_t* input_ptr, uint32_t input_size, arm_uc_buffer_t* output) 00297 { 00298 arm_uc_error_t result = (arm_uc_error_t){ ARM_UC_CU_ERR_INVALID_PARAMETER }; 00299 size_t data_size = input_size < output->size_max ? input_size : output->size_max; 00300 output->size = 0; 00301 int mbedtls_result = mbedtls_aes_crypt_ctr( 00302 &hCipher->aes_context, 00303 data_size, 00304 &hCipher->aes_nc_off, 00305 hCipher->aes_iv, 00306 hCipher->aes_partial, 00307 input_ptr, 00308 output->ptr 00309 00310 ); 00311 if (mbedtls_result == 0) 00312 { 00313 result = (arm_uc_error_t){ ARM_UC_CU_ERR_NONE }; 00314 output->size = data_size; 00315 } 00316 return result; 00317 } 00318 arm_uc_error_t ARM_UC_cryptoDecryptFinish(arm_uc_cipherHandle_t* hCipher, arm_uc_buffer_t* output) 00319 { 00320 (void) output; 00321 return (arm_uc_error_t){ARM_UC_CU_ERR_NONE}; 00322 } 00323 00324 #endif
Generated on Tue Jul 12 2022 16:22:03 by 1.7.2