You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2017/04/29 00:28:40 UTC
[02/19] incubator-mynewt-core git commit: MYNEWT-741 Port of
LoRaMac-node library
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/src/mac/LoRaMacCrypto.c
----------------------------------------------------------------------
diff --git a/net/lora/node/src/mac/LoRaMacCrypto.c b/net/lora/node/src/mac/LoRaMacCrypto.c
new file mode 100644
index 0000000..81f93ed
--- /dev/null
+++ b/net/lora/node/src/mac/LoRaMacCrypto.c
@@ -0,0 +1,203 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech
+ ___ _____ _ ___ _ _____ ___ ___ ___ ___
+/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
+\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
+|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
+embedded.connectivity.solutions===============
+
+Description: LoRa MAC layer implementation
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel J�ckle ( STACKFORCE )
+*/
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include "node/utilities.h"
+
+#include "aes.h"
+#include "cmac.h"
+
+#include "node/mac/LoRaMacCrypto.h"
+
+/*!
+ * CMAC/AES Message Integrity Code (MIC) Block B0 size
+ */
+#define LORAMAC_MIC_BLOCK_B0_SIZE 16
+
+/*!
+ * MIC field computation initial data
+ */
+static uint8_t MicBlockB0[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+/*!
+ * Contains the computed MIC field.
+ *
+ * \remark Only the 4 first bytes are used
+ */
+static uint8_t Mic[16];
+
+/*!
+ * Encryption aBlock and sBlock
+ */
+static uint8_t aBlock[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+static uint8_t sBlock[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+/*!
+ * AES computation context variable
+ */
+static aes_context AesContext;
+
+/*!
+ * CMAC computation context variable
+ */
+//static AES_CMAC_CTX AesCmacCtx[1];
+
+/*!
+ * \brief Computes the LoRaMAC frame MIC field
+ *
+ * \param [IN] buffer Data buffer
+ * \param [IN] size Data buffer size
+ * \param [IN] key AES key to be used
+ * \param [IN] address Frame address
+ * \param [IN] dir Frame direction [0: uplink, 1: downlink]
+ * \param [IN] sequenceCounter Frame sequence counter
+ * \param [OUT] mic Computed MIC field
+ */
+void LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic )
+{
+ MicBlockB0[5] = dir;
+
+ MicBlockB0[6] = ( address ) & 0xFF;
+ MicBlockB0[7] = ( address >> 8 ) & 0xFF;
+ MicBlockB0[8] = ( address >> 16 ) & 0xFF;
+ MicBlockB0[9] = ( address >> 24 ) & 0xFF;
+
+ MicBlockB0[10] = ( sequenceCounter ) & 0xFF;
+ MicBlockB0[11] = ( sequenceCounter >> 8 ) & 0xFF;
+ MicBlockB0[12] = ( sequenceCounter >> 16 ) & 0xFF;
+ MicBlockB0[13] = ( sequenceCounter >> 24 ) & 0xFF;
+
+ MicBlockB0[15] = size & 0xFF;
+
+ //AES_CMAC_Init( AesCmacCtx );
+
+ //AES_CMAC_SetKey( AesCmacCtx, key );
+
+ //AES_CMAC_Update( AesCmacCtx, MicBlockB0, LORAMAC_MIC_BLOCK_B0_SIZE );
+
+ //AES_CMAC_Update( AesCmacCtx, buffer, size & 0xFF );
+
+ //AES_CMAC_Final( Mic, AesCmacCtx );
+
+ *mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] );
+}
+
+void LoRaMacPayloadEncrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer )
+{
+ uint16_t i;
+ uint8_t bufferIndex = 0;
+ uint16_t ctr = 1;
+
+ memset( AesContext.ksch, '\0', 240 );
+ //aes_set_key( key, 16, &AesContext );
+
+ aBlock[5] = dir;
+
+ aBlock[6] = ( address ) & 0xFF;
+ aBlock[7] = ( address >> 8 ) & 0xFF;
+ aBlock[8] = ( address >> 16 ) & 0xFF;
+ aBlock[9] = ( address >> 24 ) & 0xFF;
+
+ aBlock[10] = ( sequenceCounter ) & 0xFF;
+ aBlock[11] = ( sequenceCounter >> 8 ) & 0xFF;
+ aBlock[12] = ( sequenceCounter >> 16 ) & 0xFF;
+ aBlock[13] = ( sequenceCounter >> 24 ) & 0xFF;
+
+ while( size >= 16 )
+ {
+ aBlock[15] = ( ( ctr ) & 0xFF );
+ ctr++;
+ //aes_encrypt( aBlock, sBlock, &AesContext );
+ for( i = 0; i < 16; i++ )
+ {
+ encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];
+ }
+ size -= 16;
+ bufferIndex += 16;
+ }
+
+ if( size > 0 )
+ {
+ aBlock[15] = ( ( ctr ) & 0xFF );
+ //aes_encrypt( aBlock, sBlock, &AesContext );
+ for( i = 0; i < size; i++ )
+ {
+ encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];
+ }
+ }
+}
+
+void LoRaMacPayloadDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer )
+{
+ LoRaMacPayloadEncrypt( buffer, size, key, address, dir, sequenceCounter, decBuffer );
+}
+
+void LoRaMacJoinComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic )
+{
+ //AES_CMAC_Init( AesCmacCtx );
+
+ //AES_CMAC_SetKey( AesCmacCtx, key );
+
+ //AES_CMAC_Update( AesCmacCtx, buffer, size & 0xFF );
+
+ //AES_CMAC_Final( Mic, AesCmacCtx );
+
+ *mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] );
+}
+
+void LoRaMacJoinDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer )
+{
+ memset( AesContext.ksch, '\0', 240 );
+ //aes_set_key( key, 16, &AesContext );
+ //aes_encrypt( buffer, decBuffer, &AesContext );
+ // Check if optional CFList is included
+ if( size >= 16 )
+ {
+ //aes_encrypt( buffer + 16, decBuffer + 16, &AesContext );
+ }
+}
+
+void LoRaMacJoinComputeSKeys( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey )
+{
+ uint8_t nonce[16];
+ uint8_t *pDevNonce = ( uint8_t * )&devNonce;
+
+ memset( AesContext.ksch, '\0', 240 );
+ //aes_set_key( key, 16, &AesContext );
+
+ memset( nonce, 0, sizeof( nonce ) );
+ nonce[0] = 0x01;
+ memcpy( nonce + 1, appNonce, 6 );
+ memcpy( nonce + 7, pDevNonce, 2 );
+ //aes_encrypt( nonce, nwkSKey, &AesContext );
+
+ memset( nonce, 0, sizeof( nonce ) );
+ nonce[0] = 0x02;
+ memcpy( nonce + 1, appNonce, 6 );
+ memcpy( nonce + 7, pDevNonce, 2 );
+ //aes_encrypt( nonce, appSKey, &AesContext );
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/src/mac/aes.h
----------------------------------------------------------------------
diff --git a/net/lora/node/src/mac/aes.h b/net/lora/node/src/mac/aes.h
new file mode 100644
index 0000000..5fdc143
--- /dev/null
+++ b/net/lora/node/src/mac/aes.h
@@ -0,0 +1,160 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
+
+ LICENSE TERMS
+
+ The redistribution and use of this software (with or without changes)
+ is allowed without the payment of fees or royalties provided that:
+
+ 1. source code distributions include the above copyright notice, this
+ list of conditions and the following disclaimer;
+
+ 2. binary distributions include the above copyright notice, this list
+ of conditions and the following disclaimer in their documentation;
+
+ 3. the name of the copyright holder is not used to endorse products
+ built using this software without specific written permission.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue 09/09/2006
+
+ This is an AES implementation that uses only 8-bit byte operations on the
+ cipher state.
+ */
+
+#ifndef AES_H
+#define AES_H
+
+#if 1
+# define AES_ENC_PREKEYED /* AES encryption with a precomputed key schedule */
+#endif
+#if 0
+# define AES_DEC_PREKEYED /* AES decryption with a precomputed key schedule */
+#endif
+#if 0
+# define AES_ENC_128_OTFK /* AES encryption with 'on the fly' 128 bit keying */
+#endif
+#if 0
+# define AES_DEC_128_OTFK /* AES decryption with 'on the fly' 128 bit keying */
+#endif
+#if 0
+# define AES_ENC_256_OTFK /* AES encryption with 'on the fly' 256 bit keying */
+#endif
+#if 0
+# define AES_DEC_256_OTFK /* AES decryption with 'on the fly' 256 bit keying */
+#endif
+
+#define N_ROW 4
+#define N_COL 4
+#define N_BLOCK (N_ROW * N_COL)
+#define N_MAX_ROUNDS 14
+
+typedef uint8_t return_type;
+
+/* Warning: The key length for 256 bit keys overflows a byte
+ (see comment below)
+*/
+
+typedef uint8_t length_type;
+
+typedef struct
+{ uint8_t ksch[(N_MAX_ROUNDS + 1) * N_BLOCK];
+ uint8_t rnd;
+} aes_context;
+
+/* The following calls are for a precomputed key schedule
+
+ NOTE: If the length_type used for the key length is an
+ unsigned 8-bit character, a key length of 256 bits must
+ be entered as a length in bytes (valid inputs are hence
+ 128, 192, 16, 24 and 32).
+*/
+
+#if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED )
+
+return_type aes_set_key( const uint8_t key[],
+ length_type keylen,
+ aes_context ctx[1] );
+#endif
+
+#if defined( AES_ENC_PREKEYED )
+
+return_type aes_encrypt( const uint8_t in[N_BLOCK],
+ uint8_t out[N_BLOCK],
+ const aes_context ctx[1] );
+
+return_type aes_cbc_encrypt( const uint8_t *in,
+ uint8_t *out,
+ int32_t n_block,
+ uint8_t iv[N_BLOCK],
+ const aes_context ctx[1] );
+#endif
+
+#if defined( AES_DEC_PREKEYED )
+
+return_type aes_decrypt( const uint8_t in[N_BLOCK],
+ uint8_t out[N_BLOCK],
+ const aes_context ctx[1] );
+
+return_type aes_cbc_decrypt( const uint8_t *in,
+ uint8_t *out,
+ int32_t n_block,
+ uint8_t iv[N_BLOCK],
+ const aes_context ctx[1] );
+#endif
+
+/* The following calls are for 'on the fly' keying. In this case the
+ encryption and decryption keys are different.
+
+ The encryption subroutines take a key in an array of bytes in
+ key[L] where L is 16, 24 or 32 bytes for key lengths of 128,
+ 192, and 256 bits respectively. They then encrypts the input
+ data, in[] with this key and put the reult in the output array
+ out[]. In addition, the second key array, o_key[L], is used
+ to output the key that is needed by the decryption subroutine
+ to reverse the encryption operation. The two key arrays can
+ be the same array but in this case the original key will be
+ overwritten.
+
+ In the same way, the decryption subroutines output keys that
+ can be used to reverse their effect when used for encryption.
+
+ Only 128 and 256 bit keys are supported in these 'on the fly'
+ modes.
+*/
+
+#if defined( AES_ENC_128_OTFK )
+void aes_encrypt_128( const uint8_t in[N_BLOCK],
+ uint8_t out[N_BLOCK],
+ const uint8_t key[N_BLOCK],
+ uint8_t o_key[N_BLOCK] );
+#endif
+
+#if defined( AES_DEC_128_OTFK )
+void aes_decrypt_128( const uint8_t in[N_BLOCK],
+ uint8_t out[N_BLOCK],
+ const uint8_t key[N_BLOCK],
+ uint8_t o_key[N_BLOCK] );
+#endif
+
+#if defined( AES_ENC_256_OTFK )
+void aes_encrypt_256( const uint8_t in[N_BLOCK],
+ uint8_t out[N_BLOCK],
+ const uint8_t key[2 * N_BLOCK],
+ uint8_t o_key[2 * N_BLOCK] );
+#endif
+
+#if defined( AES_DEC_256_OTFK )
+void aes_decrypt_256( const uint8_t in[N_BLOCK],
+ uint8_t out[N_BLOCK],
+ const uint8_t key[2 * N_BLOCK],
+ uint8_t o_key[2 * N_BLOCK] );
+#endif
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/src/mac/cmac.h
----------------------------------------------------------------------
diff --git a/net/lora/node/src/mac/cmac.h b/net/lora/node/src/mac/cmac.h
new file mode 100644
index 0000000..c12e970
--- /dev/null
+++ b/net/lora/node/src/mac/cmac.h
@@ -0,0 +1,63 @@
+/**************************************************************************
+Copyright (C) 2009 Lander Casado, Philippas Tsigas
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files
+(the "Software"), to deal with the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimers. Redistributions in
+binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimers in the documentation and/or
+other materials provided with the distribution.
+
+In no event shall the authors or copyright holders be liable for any special,
+incidental, indirect or consequential damages of any kind, or any damages
+whatsoever resulting from loss of use, data or profits, whether or not
+advised of the possibility of damage, and on any theory of liability,
+arising out of or in connection with the use or performance of this software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS WITH THE SOFTWARE
+
+*****************************************************************************/
+
+#ifndef _CMAC_H_
+#define _CMAC_H_
+
+#include "aes.h"
+
+#define AES_CMAC_KEY_LENGTH 16
+#define AES_CMAC_DIGEST_LENGTH 16
+
+typedef struct _AES_CMAC_CTX {
+ aes_context rijndael;
+ uint8_t X[16];
+ uint8_t M_last[16];
+ uint32_t M_n;
+ } AES_CMAC_CTX;
+
+//#include <sys/cdefs.h>
+
+//__BEGIN_DECLS
+void AES_CMAC_Init(AES_CMAC_CTX * ctx);
+void AES_CMAC_SetKey(AES_CMAC_CTX * ctx, const uint8_t key[AES_CMAC_KEY_LENGTH]);
+void AES_CMAC_Update(AES_CMAC_CTX * ctx, const uint8_t * data, uint32_t len);
+ // __attribute__((__bounded__(__string__,2,3)));
+void AES_CMAC_Final(uint8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX * ctx);
+ // __attribute__((__bounded__(__minbytes__,1,AES_CMAC_DIGEST_LENGTH)));
+//__END_DECLS
+
+#endif /* _CMAC_H_ */
+
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/src/misc.c
----------------------------------------------------------------------
diff --git a/net/lora/node/src/misc.c b/net/lora/node/src/misc.c
new file mode 100644
index 0000000..3d4576a
--- /dev/null
+++ b/net/lora/node/src/misc.c
@@ -0,0 +1,45 @@
+#include <stdlib.h>
+
+#include "syscfg/syscfg.h"
+#include "node/utilities.h"
+#include "lora_priv.h"
+
+int32_t
+randr(int32_t min, int32_t max)
+{
+ return rand() % (max - min + 1) + min;
+}
+
+void
+memcpyr( uint8_t *dst, const uint8_t *src, uint16_t size )
+{
+ dst = dst + ( size - 1 );
+ while( size-- )
+ {
+ *dst-- = *src++;
+ }
+}
+
+double
+ceil(double d)
+{
+ int64_t i;
+
+ i = d;
+ if (d == i) {
+ return i;
+ }
+ return i + 1;
+}
+
+double
+floor(double d)
+{
+ return (int64_t)d;
+}
+
+double
+round(double d)
+{
+ return (int64_t)(d + 0.5);
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/src/timer.c
----------------------------------------------------------------------
diff --git a/net/lora/node/src/timer.c b/net/lora/node/src/timer.c
new file mode 100644
index 0000000..d445b01
--- /dev/null
+++ b/net/lora/node/src/timer.c
@@ -0,0 +1,15 @@
+#include "os/os.h"
+#include "node/timer.h"
+#include "node/utilities.h"
+
+uint32_t
+TimerGetElapsedTime(uint32_t savedTime)
+{
+ return savedTime - os_cputime_get32();
+}
+
+uint32_t
+TimerGetFutureTime(uint32_t eventInFuture)
+{
+ return os_cputime_get32() + eventInFuture;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/syscfg.yml
----------------------------------------------------------------------
diff --git a/net/lora/node/syscfg.yml b/net/lora/node/syscfg.yml
new file mode 100644
index 0000000..43fd05b
--- /dev/null
+++ b/net/lora/node/syscfg.yml
@@ -0,0 +1,39 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+ LORA_NODE:
+ description: >
+ Used by package management system to include lora/node hardware
+ drivers.
+ value: 1
+
+ LORA_NODE_FREQ_BAND:
+ description: >
+ Which frequency band to use. Valid values are:
+ o 433
+ o 470
+ o 780
+ o 868
+ o 915
+ value: 868
+
+ LORA_NODE_CLI:
+ description: "Include shell commands for LoRa operations"
+ value: 0