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