forked from mfulz_github/qmk_firmware
Compare commits
49 Commits
master
...
enc_master
Author | SHA1 | Date |
---|---|---|
Matthias Fulz | 19d14d4ef7 | |
Matthias Fulz | 764bcd12c5 | |
Matthias Fulz | fc450f4de0 | |
Matthias Fulz | c644facdac | |
Matthias Fulz | df13bc34bf | |
Matthias Fulz | 143a1afccb | |
Matthias Fulz | f6d7770a85 | |
Matthias Fulz | f5d4b4f86f | |
Matthias Fulz | 89de0b3091 | |
Matthias Fulz | 539f96a2c6 | |
Matthias Fulz | 3a52e1819e | |
Matthias Fulz | f68a65d766 | |
Matthias Fulz | c7d78a05f3 | |
Matthias Fulz | c501395cc1 | |
Matthias Fulz | 4c4bc524c2 | |
Matthias Fulz | 8161c72c75 | |
Matthias Fulz | d7f74c7a6f | |
Matthias Fulz | c54765e246 | |
Matthias Fulz | 8523ffd758 | |
Matthias Fulz | 7145871ccf | |
Matthias Fulz | 3019b56aac | |
Matthias Fulz | ba36d2204b | |
Matthias Fulz | f197e476df | |
Matthias Fulz | 4d3adb0437 | |
Matthias Fulz | e4ff1fdf80 | |
Matthias Fulz | 562df82b85 | |
Matthias Fulz | f7bfe769b8 | |
Matthias Fulz | 914cc32ec0 | |
Matthias Fulz | fc9eb9dd06 | |
Matthias Fulz | 62e448747e | |
Matthias Fulz | 868b416f77 | |
Matthias Fulz | f8a382de40 | |
Matthias Fulz | 8d90fc1474 | |
Matthias Fulz | c473110c89 | |
Matthias Fulz | 4a28710f4b | |
Matthias Fulz | af291b0990 | |
Matthias Fulz | 5acc167a3f | |
Matthias Fulz | 9bda2904f3 | |
Matthias Fulz | 969c680721 | |
Matthias Fulz | 365709dc15 | |
Matthias Fulz | 1e145e0fed | |
Matthias Fulz | d7bdb943f0 | |
Matthias Fulz | 2350ecd5b7 | |
Matthias Fulz | 30a7fa7cd1 | |
Matthias Fulz | dc5cb40c72 | |
Matthias Fulz | b0ff58a23a | |
Matthias Fulz | eb60e9230a | |
Matthias Fulz | 27801eefc8 | |
Matthias Fulz | 43ef5cedf0 |
|
@ -556,6 +556,17 @@ ifeq ($(strip $(VIA_ENABLE)), yes)
|
||||||
OPT_DEFS += -DVIA_ENABLE
|
OPT_DEFS += -DVIA_ENABLE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(ENC_ENABLE)), yes)
|
||||||
|
RAW_ENABLE := yes
|
||||||
|
COMMON_VPATH += $(QUANTUM_DIR)/enc
|
||||||
|
COMMON_VPATH += $(QUANTUM_DIR)/enc/enc_boards
|
||||||
|
include $(QUANTUM_DIR)/enc/enc_boards/enc_boards.mk
|
||||||
|
OPT_DEFS += -DENC_ENABLE
|
||||||
|
SRC += aes.c
|
||||||
|
SRC += pkcs7_padding.c
|
||||||
|
SRC += enc.c
|
||||||
|
endif
|
||||||
|
|
||||||
VALID_MAGIC_TYPES := yes
|
VALID_MAGIC_TYPES := yes
|
||||||
BOOTMAGIC_ENABLE ?= no
|
BOOTMAGIC_ENABLE ?= no
|
||||||
ifneq ($(strip $(BOOTMAGIC_ENABLE)), no)
|
ifneq ($(strip $(BOOTMAGIC_ENABLE)), no)
|
||||||
|
|
|
@ -11,7 +11,8 @@ BUILD_OPTION_NAMES = \
|
||||||
SPLIT_KEYBOARD \
|
SPLIT_KEYBOARD \
|
||||||
DYNAMIC_KEYMAP_ENABLE \
|
DYNAMIC_KEYMAP_ENABLE \
|
||||||
USB_HID_ENABLE \
|
USB_HID_ENABLE \
|
||||||
VIA_ENABLE
|
VIA_ENABLE \
|
||||||
|
ENC_ENABLE
|
||||||
|
|
||||||
HARDWARE_OPTION_NAMES = \
|
HARDWARE_OPTION_NAMES = \
|
||||||
SLEEP_LED_ENABLE \
|
SLEEP_LED_ENABLE \
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
#include "6x6.h"
|
|
@ -0,0 +1,40 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "trenctyl_manuform.h"
|
||||||
|
|
||||||
|
#if defined(KEYBOARD_handwired_trenctyl_manuform_6x6_f401)
|
||||||
|
# include "f401.h"
|
||||||
|
#elif defined(KEYBOARD_handwired_trenctyl_manuform_6x6_f411)
|
||||||
|
# include "f411.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define XXX KC_NO
|
||||||
|
|
||||||
|
#define LAYOUT_6x6( \
|
||||||
|
L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \
|
||||||
|
L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \
|
||||||
|
L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \
|
||||||
|
L30, L31, L32, L33, L34, L35, R30, R31, R32, R33, R34, R35, \
|
||||||
|
L40, L41, L42, L43, L44, L45, R40, R41, R42, R43, R44, R45, \
|
||||||
|
L51, L52, L53, R52, R53, \
|
||||||
|
L54, L55, R50, R51, \
|
||||||
|
L64, L65, R60, R61, \
|
||||||
|
L62, L63 \
|
||||||
|
) { \
|
||||||
|
{ L00, L01, L02, L03, L04, L05 }, \
|
||||||
|
{ L10, L11, L12, L13, L14, L15 }, \
|
||||||
|
{ L20, L21, L22, L23, L24, L25 }, \
|
||||||
|
{ L30, L31, L32, L33, L34, L35 }, \
|
||||||
|
{ L40, L41, L42, L43, L44, L45 }, \
|
||||||
|
{ XXX, L51, L52, L53, L54, L55 }, \
|
||||||
|
{ XXX, XXX, L62, L63, L64, L65 }, \
|
||||||
|
\
|
||||||
|
{ R00, R01, R02, R03, R04, R05 }, \
|
||||||
|
{ R10, R11, R12, R13, R14, R15 }, \
|
||||||
|
{ R20, R21, R22, R23, R24, R25 }, \
|
||||||
|
{ R30, R31, R32, R33, R34, R35 }, \
|
||||||
|
{ R40, R41, R42, R43, R44, R45 }, \
|
||||||
|
{ R50, R51, R52, R53, XXX, XXX }, \
|
||||||
|
{ R60, R61, XXX, XXX, XXX, XXX } \
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||||
|
Copyright 2015 Jack Humbert
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "config_common.h"
|
||||||
|
|
||||||
|
/* key matrix size */
|
||||||
|
// Rows are doubled-up
|
||||||
|
#define MATRIX_ROWS 14
|
||||||
|
#define MATRIX_COLS 6
|
||||||
|
|
||||||
|
#define RGB_MATRIX_KEYPRESSES
|
||||||
|
//#define RGB_MATRIX_KEYRELEASES
|
||||||
|
#define RGB_MATRIX_FRAMEBUFFER_EFFECTS
|
||||||
|
|
||||||
|
#define SPLIT_TRANSPORT_MIRROR
|
||||||
|
#define SPLIT_LAYER_STATE_ENABLE
|
||||||
|
#define SPLIT_ENC_MODE_ENABLE
|
||||||
|
#define SPLIT_ENC_FLAGS_ENABLE
|
||||||
|
#define SPLIT_OLED_ENABLE
|
||||||
|
|
||||||
|
#define POINTING_DEVICE_INVERT_Y TRUE
|
||||||
|
#define PMW3360_LIFTOFF_DISTANCE 0x03
|
||||||
|
|
||||||
|
#define ONESHOT_TAP_TOGGLE 3
|
||||||
|
|
||||||
|
#define OLED_TIMEOUT 0
|
||||||
|
|
||||||
|
#define ENABLE_RGB_MATRIX_NONE
|
||||||
|
#define ENABLE_RGB_MATRIX_SOLID_COLOR // Static single hue, no speed support
|
||||||
|
#define ENABLE_RGB_MATRIX_ALPHAS_MODS // Static dual hue, speed is hue for secondary hue
|
||||||
|
#define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN // Static gradient top to bottom, speed controls how much gradient changes
|
||||||
|
#define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT // Static gradient left to right, speed controls how much gradient changes
|
||||||
|
#define ENABLE_RGB_MATRIX_BREATHING // Single hue brightness cycling animation
|
||||||
|
#define ENABLE_RGB_MATRIX_BAND_SAT // Single hue band fading saturation scrolling left to right
|
||||||
|
#define ENABLE_RGB_MATRIX_BAND_VAL // Single hue band fading brightness scrolling left to right
|
||||||
|
#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT // Single hue 3 blade spinning pinwheel fades saturation
|
||||||
|
#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL // Single hue 3 blade spinning pinwheel fades brightness
|
||||||
|
#define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT // Single hue spinning spiral fades saturation
|
||||||
|
#define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL // Single hue spinning spiral fades brightness
|
||||||
|
#define ENABLE_RGB_MATRIX_CYCLE_ALL // Full keyboard solid hue cycling through full gradient
|
||||||
|
#define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT // Full gradient scrolling left to right
|
||||||
|
#define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN // Full gradient scrolling top to bottom
|
||||||
|
#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN // Full gradient scrolling out to in
|
||||||
|
#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL // Full dual gradients scrolling out to in
|
||||||
|
#define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON // Full gradent Chevron shapped scrolling left to right
|
||||||
|
#define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL // Full gradient spinning pinwheel around center of keyboard
|
||||||
|
#define ENABLE_RGB_MATRIX_CYCLE_SPIRAL // Full gradient spinning spiral around center of keyboard
|
||||||
|
#define ENABLE_RGB_MATRIX_DUAL_BEACON // Full gradient spinning around center of keyboard
|
||||||
|
#define ENABLE_RGB_MATRIX_RAINBOW_BEACON // Full tighter gradient spinning around center of keyboard
|
||||||
|
#define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS // Full dual gradients spinning two halfs of keyboard
|
||||||
|
#define ENABLE_RGB_MATRIX_RAINDROPS // Randomly changes a single key's hue
|
||||||
|
#define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS // Randomly changes a single key's hue and saturation
|
||||||
|
#define ENABLE_RGB_MATRIX_HUE_BREATHING // Hue shifts up a slight ammount at the same time then shifts back
|
||||||
|
#define ENABLE_RGB_MATRIX_HUE_PENDULUM // Hue shifts up a slight ammount in a wave to the right then back to the left
|
||||||
|
#define ENABLE_RGB_MATRIX_HUE_WAVE // Hue shifts up a slight ammount and then back down in a wave to the right
|
||||||
|
#define ENABLE_RGB_MATRIX_PIXEL_FRACTAL // Single hue fractal filled keys pulsing horizontally out to edges
|
||||||
|
#define ENABLE_RGB_MATRIX_PIXEL_RAIN // Randomly light keys with random hues
|
||||||
|
#define ENABLE_RGB_MATRIX_TYPING_HEATMAP // How hot is your WPM!
|
||||||
|
#define ENABLE_RGB_MATRIX_DIGITAL_RAIN // That famous computer simulation
|
||||||
|
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE // Pulses keys hit to hue & value then fades value out
|
||||||
|
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE // Static single hue pulses keys hit to shifted hue then fades to current hue
|
||||||
|
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE // Hue & value pulse near a single key hit then fades value out
|
||||||
|
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE // Hue & value pulse near multiple key hits then fades value out
|
||||||
|
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS // Hue & value pulse the same column and row of a single key hit then fades value out
|
||||||
|
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS // Hue & value pulse the same column and row of multiple key hits then fades value out
|
||||||
|
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS // Hue & value pulse away on the same column and row of a single key hit then fades value out
|
||||||
|
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS // Hue & value pulse away on the same column and row of multiple key hits then fades value out
|
||||||
|
#define ENABLE_RGB_MATRIX_SPLASH // Full gradient & value pulse away from a single key hit then fades value out
|
||||||
|
#define ENABLE_RGB_MATRIX_MULTISPLASH // Full gradient & value pulse away from multiple key hits then fades value out
|
||||||
|
#define ENABLE_RGB_MATRIX_SOLID_SPLASH // Hue & value pulse away from a single key hit then fades value out
|
||||||
|
#define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH // Hue & value pulse away from multiple key hits then fades value out
|
||||||
|
#define ENABLE_RGB_MATRIX_EFFECT_MAX
|
||||||
|
|
||||||
|
#define SPLIT_TRANSACTION_IDS_USER USER_SYNC_VIS_STATUS
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||||
|
Copyright 2015 Jack Humbert
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "config_common.h"
|
||||||
|
|
||||||
|
#define PRODUCT_ID 0x3836
|
||||||
|
#define DEVICE_VER 0x0001
|
||||||
|
#define PRODUCT Trenctyl Manuform (6x6) BlackPill F01
|
||||||
|
|
||||||
|
#define MATRIX_ROW_PINS { A15, B13, B14, B15, A8, B6, B7 }
|
||||||
|
#define MATRIX_COL_PINS { B10, B0, A1, A0, B4, C14 }
|
||||||
|
|
||||||
|
#define MATRIX_ROW_PINS_RIGHT { A15, B13, B14, B15, A8, B6, B7 }
|
||||||
|
#define MATRIX_COL_PINS_RIGHT { B10, B0, A1, A0, B4, C14 }
|
||||||
|
|
||||||
|
#define DIODE_DIRECTION ROW2COL
|
||||||
|
|
||||||
|
#define RGB_DI_PIN B3
|
||||||
|
#define RGBLED_NUM 74
|
||||||
|
#define DRIVER_LED_TOTAL 74
|
||||||
|
|
||||||
|
#define RGBLIGHT_SPLIT
|
||||||
|
#define RGBLED_SPLIT { 38, 36 }
|
||||||
|
#define RGBLIGHT_LIMIT_VAL 200
|
||||||
|
#define RGB_MATRIX_MAXIMUM_BRIGHTNESS RGBLIGHT_LIMIT_VAL
|
||||||
|
#define RGB_MATRIX_SPLIT RGBLED_SPLIT
|
||||||
|
#define RGB_MATRIX_CENTER { 110, 19 }
|
||||||
|
|
||||||
|
#define SERIAL_USART_RX_PIN A2
|
||||||
|
#define SELECT_SOFT_SERIAL_SPEED 1
|
||||||
|
#define FORCED_SYNC_THROTTLE_MS 200
|
||||||
|
#define SERIAL_USART_DRIVER SD2
|
||||||
|
#define SERIAL_USART_TX_PAL_MODE 7
|
||||||
|
#define SERIAL_USART_RX_PAL_MODE 7
|
||||||
|
#define SERIAL_USART_TIMEOUT 10
|
||||||
|
#define I2C1_SCL_PIN B8
|
||||||
|
#define I2C1_SDA_PIN B9
|
||||||
|
|
||||||
|
#define PMW3360_CS_PIN A4
|
||||||
|
|
||||||
|
#define SPI_DRIVER SPID1
|
||||||
|
#define SPI_SCK_PIN A5
|
||||||
|
#define SPI_SCK_PAL_MODE 5
|
||||||
|
#define SPI_MOSI_PIN A7
|
||||||
|
#define SPI_MOSI_PAL_MODE 5
|
||||||
|
#define SPI_MISO_PIN A6
|
||||||
|
#define SPI_MISO_PAL_MODE 5
|
||||||
|
|
||||||
|
#define ENCODERS_PAD_A { C13 }
|
||||||
|
#define ENCODERS_PAD_B { C15 }
|
||||||
|
|
||||||
|
#define WS2812_PWM_DRIVER PWMD2
|
||||||
|
#define WS2812_PWM_CHANNEL 2
|
||||||
|
#define WS2812_DMA_STREAM STM32_DMA1_STREAM7
|
||||||
|
#define WS2812_DMA_CHANNEL 3
|
||||||
|
#define WS2812_PWM_PAL_MODE 1
|
||||||
|
|
||||||
|
// hw rnd generator
|
||||||
|
//#define ENC_HW_RND_STM32F4
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "6x6.h"
|
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define HAL_USE_SERIAL TRUE
|
||||||
|
#define HAL_USE_I2C TRUE
|
||||||
|
#define HAL_USE_SPI TRUE
|
||||||
|
#define HAL_USE_PWM TRUE
|
||||||
|
|
||||||
|
#include_next <halconf.h>
|
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include_next "mcuconf.h"
|
||||||
|
|
||||||
|
#undef STM32_SERIAL_USE_USART2
|
||||||
|
#define STM32_SERIAL_USE_USART2 TRUE
|
||||||
|
|
||||||
|
#undef STM32_UART_USART2_RX_DMA_STREAM
|
||||||
|
#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
|
||||||
|
#undef STM32_UART_USART2_TX_DMA_STREAM
|
||||||
|
#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
|
||||||
|
|
||||||
|
#undef STM32_PWM_USE_TIM2
|
||||||
|
#define STM32_PWM_USE_TIM2 TRUE
|
||||||
|
|
||||||
|
#undef STM32_ST_USE_TIMER
|
||||||
|
#define STM32_ST_USE_TIMER 5
|
||||||
|
|
||||||
|
#undef STM32_SPI_USE_SPI1
|
||||||
|
#define STM32_SPI_USE_SPI1 TRUE
|
||||||
|
|
||||||
|
#undef STM32_SPI_SPI1_RX_DMA_STREAM
|
||||||
|
#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0)
|
||||||
|
#undef STM32_SPI_SPI1_TX_DMA_STREAM
|
||||||
|
#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
|
||||||
|
|
||||||
|
#undef STM32_I2C_USE_I2C1
|
||||||
|
#define STM32_I2C_USE_I2C1 TRUE
|
||||||
|
|
||||||
|
#undef STM32_ADC_USE_ADC0
|
||||||
|
#define STM32_ADC_USE_ADC0 TRUE
|
||||||
|
#undef STM32_ADC_USE_ADC1
|
||||||
|
#define STM32_ADC_USE_ADC1 TRUE
|
|
@ -0,0 +1,6 @@
|
||||||
|
MCU = STM32F401
|
||||||
|
|
||||||
|
BOOTLOADER = stm32-dfu
|
||||||
|
|
||||||
|
LTO_ENABLE = no
|
||||||
|
SERIAL_DRIVER = usart
|
|
@ -0,0 +1,102 @@
|
||||||
|
{
|
||||||
|
"keyboard_name": "Dactyl Manuform 6x6",
|
||||||
|
"url": "",
|
||||||
|
"maintainer": "qmk",
|
||||||
|
"layouts": {
|
||||||
|
"LAYOUT_6x6": {
|
||||||
|
"layout": [
|
||||||
|
{"x": 0, "y": 0},
|
||||||
|
{"x": 1, "y": 0},
|
||||||
|
{"x": 2, "y": 0},
|
||||||
|
{"x": 3, "y": 0},
|
||||||
|
{"x": 4, "y": 0},
|
||||||
|
{"x": 5, "y": 0},
|
||||||
|
|
||||||
|
{"x": 11, "y": 0},
|
||||||
|
{"x": 12, "y": 0},
|
||||||
|
{"x": 13, "y": 0},
|
||||||
|
{"x": 14, "y": 0},
|
||||||
|
{"x": 15, "y": 0},
|
||||||
|
{"x": 16, "y": 0},
|
||||||
|
|
||||||
|
{"x": 0, "y": 1},
|
||||||
|
{"x": 1, "y": 1},
|
||||||
|
{"x": 2, "y": 1},
|
||||||
|
{"x": 3, "y": 1},
|
||||||
|
{"x": 4, "y": 1},
|
||||||
|
{"x": 5, "y": 1},
|
||||||
|
|
||||||
|
{"x": 11, "y": 1},
|
||||||
|
{"x": 12, "y": 1},
|
||||||
|
{"x": 13, "y": 1},
|
||||||
|
{"x": 14, "y": 1},
|
||||||
|
{"x": 15, "y": 1},
|
||||||
|
{"x": 16, "y": 1},
|
||||||
|
|
||||||
|
{"x": 0, "y": 2},
|
||||||
|
{"x": 1, "y": 2},
|
||||||
|
{"x": 2, "y": 2},
|
||||||
|
{"x": 3, "y": 2},
|
||||||
|
{"x": 4, "y": 2},
|
||||||
|
{"x": 5, "y": 2},
|
||||||
|
|
||||||
|
{"x": 11, "y": 2},
|
||||||
|
{"x": 12, "y": 2},
|
||||||
|
{"x": 13, "y": 2},
|
||||||
|
{"x": 14, "y": 2},
|
||||||
|
{"x": 15, "y": 2},
|
||||||
|
{"x": 16, "y": 2},
|
||||||
|
|
||||||
|
{"x": 0, "y": 3},
|
||||||
|
{"x": 1, "y": 3},
|
||||||
|
{"x": 2, "y": 3},
|
||||||
|
{"x": 3, "y": 3},
|
||||||
|
{"x": 4, "y": 3},
|
||||||
|
{"x": 5, "y": 3},
|
||||||
|
|
||||||
|
{"x": 11, "y": 3},
|
||||||
|
{"x": 12, "y": 3},
|
||||||
|
{"x": 13, "y": 3},
|
||||||
|
{"x": 14, "y": 3},
|
||||||
|
{"x": 15, "y": 3},
|
||||||
|
{"x": 16, "y": 3},
|
||||||
|
|
||||||
|
{"x": 0, "y": 4},
|
||||||
|
{"x": 1, "y": 4},
|
||||||
|
{"x": 2, "y": 4},
|
||||||
|
{"x": 3, "y": 4},
|
||||||
|
{"x": 4, "y": 4},
|
||||||
|
{"x": 5, "y": 4},
|
||||||
|
|
||||||
|
{"x": 11, "y": 4},
|
||||||
|
{"x": 12, "y": 4},
|
||||||
|
{"x": 13, "y": 4},
|
||||||
|
{"x": 14, "y": 4},
|
||||||
|
{"x": 15, "y": 4},
|
||||||
|
{"x": 16, "y": 4},
|
||||||
|
|
||||||
|
{"x": 1, "y": 5},
|
||||||
|
{"x": 2, "y": 5},
|
||||||
|
{"x": 3, "y": 5},
|
||||||
|
|
||||||
|
{"x": 13, "y": 5},
|
||||||
|
{"x": 14, "y": 5},
|
||||||
|
|
||||||
|
{"x": 4, "y": 6},
|
||||||
|
{"x": 5, "y": 6},
|
||||||
|
|
||||||
|
{"x": 11, "y": 6},
|
||||||
|
{"x": 12, "y": 6},
|
||||||
|
|
||||||
|
{"x": 6, "y": 7},
|
||||||
|
{"x": 7, "y": 7},
|
||||||
|
|
||||||
|
{"x": 9, "y": 7},
|
||||||
|
{"x": 10, "y": 7},
|
||||||
|
|
||||||
|
{"x": 6, "y": 8},
|
||||||
|
{"x": 7, "y": 8}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define SERIAL_USART_FULL_DUPLEX
|
||||||
|
|
||||||
|
//#define MASTER_LEFT
|
||||||
|
#define MASTER_RIGHT
|
||||||
|
|
||||||
|
//#define EE_HANDS
|
|
@ -0,0 +1,462 @@
|
||||||
|
#include QMK_KEYBOARD_H
|
||||||
|
|
||||||
|
#include "pointing_device.h"
|
||||||
|
|
||||||
|
#include "quantum_keycodes.h"
|
||||||
|
#include "transactions.h"
|
||||||
|
/*#include "enc.h"*/
|
||||||
|
|
||||||
|
#define _QWERTZ 0
|
||||||
|
#define _CONTROL 1
|
||||||
|
#define _I3WM 2
|
||||||
|
#define _MOUSE 3
|
||||||
|
|
||||||
|
#define QWERTZ TO(_QWERTZ)
|
||||||
|
#define CONTROL TT(_CONTROL)
|
||||||
|
#define I3WM TT(_I3WM)
|
||||||
|
#define MOUSE TG(_MOUSE)
|
||||||
|
|
||||||
|
#ifdef RGB_MATRIX_ENABLE
|
||||||
|
// clang-format off
|
||||||
|
led_config_t g_led_config = {{
|
||||||
|
{ 0, 5, 10, 16, 22, 30, },
|
||||||
|
{ 1, 6, 11, 17, 23, 31, },
|
||||||
|
{ 2, 7, 12, 18, 24, 32, },
|
||||||
|
{ 3, 8, 13, 19, 25, 33, },
|
||||||
|
{ 4, 9, 14, 20, 26, 34, },
|
||||||
|
{ NO_LED, NO_LED, 15, 21, 27, 35, },
|
||||||
|
{ NO_LED, NO_LED, 29, 37, 28, 36, },
|
||||||
|
// RIGHT HALF
|
||||||
|
{ 38, 45, 52, 58, 64, 69 },
|
||||||
|
{ 39, 46, 53, 59, 65, 70 },
|
||||||
|
{ 40, 47, 54, 60, 66, 71 },
|
||||||
|
{ 41, 48, 55, 61, 67, 72 },
|
||||||
|
{ 42, 49, 56, 62, 68, 73 },
|
||||||
|
{ 43, 50, 57, 63, NO_LED, NO_LED },
|
||||||
|
{ 44, 51, NO_LED, NO_LED, NO_LED, NO_LED },
|
||||||
|
}, {
|
||||||
|
{ 0, 0 }, { 0, 8 }, { 0, 19 }, { 0, 30 }, { 0, 41 },
|
||||||
|
{ 20, 0 }, { 20, 8 }, { 20, 19 }, { 20, 30 }, { 20, 41 },
|
||||||
|
{ 40, 0 }, { 40, 8 }, { 40, 19 }, { 40, 30 }, { 40, 41 }, { 40, 52 },
|
||||||
|
{ 60, 0 }, { 60, 8 }, { 60, 19 }, { 60, 30 }, { 60, 41 }, { 60, 52 },
|
||||||
|
{ 80, 0 }, { 80, 8 }, { 80, 19 }, { 80, 30 }, { 80, 41 }, { 80, 52 }, { 80, 64 },
|
||||||
|
{ 40, 64 },
|
||||||
|
{ 100, 0 }, { 100, 8 }, { 100, 19 }, { 100, 30 }, { 100, 41 }, { 100, 52 }, { 100, 64 },
|
||||||
|
{ 60, 64 },
|
||||||
|
// RIGHT HALF
|
||||||
|
{ 120, 0 }, { 120, 8 }, { 120, 19 }, { 120, 30 }, { 120, 41 }, { 120, 52 }, { 120, 64 },
|
||||||
|
{ 140, 0 }, { 140, 8 }, { 140, 19 }, { 140, 30 }, { 140, 41 }, { 140, 52 }, { 140, 64 },
|
||||||
|
{ 160, 0 }, { 160, 8 }, { 160, 19 }, { 160, 30 }, { 160, 41 }, { 160, 52 },
|
||||||
|
{ 180, 0 }, { 180, 8 }, { 180, 19 }, { 180, 30 }, { 180, 41 }, { 180, 52 },
|
||||||
|
{ 200, 0 }, { 200, 8 }, { 200, 19 }, { 200, 30 }, { 200, 41 },
|
||||||
|
{ 224, 0 }, { 224, 8 }, { 224, 19 }, { 224, 30 }, { 224, 41 }
|
||||||
|
}, {
|
||||||
|
4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4,
|
||||||
|
4, 4,
|
||||||
|
4, 4,
|
||||||
|
4, 4,
|
||||||
|
/*4, 4, 4, 4, 4, 4,*/
|
||||||
|
// RIGHT HALF
|
||||||
|
4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4,
|
||||||
|
4, 4,
|
||||||
|
4, 4,
|
||||||
|
/*4, 4, 4, 4, 4, 4,*/
|
||||||
|
}};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum my_keycodes {
|
||||||
|
CPI_NEXT = SAFE_RANGE,
|
||||||
|
CPI_PREV,
|
||||||
|
VIS_VAD,
|
||||||
|
VIS_VAI
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
|
[_QWERTZ] = LAYOUT_6x6(
|
||||||
|
KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 ,KC_F10 ,KC_F11 ,KC_F12 ,
|
||||||
|
KC_GRV , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 ,KC_BSPC,
|
||||||
|
KC_TAB , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,KC_LBRC,
|
||||||
|
KC_LCTL, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L ,KC_SCLN,KC_QUOT,
|
||||||
|
OSM(MOD_LSFT), KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M ,KC_DOT,KC_COMM ,KC_SLSH,KC_BSLASH,
|
||||||
|
KC_MUTE,KC_RBRC,KC_MINS, KC_NUBS, KC_EQL,
|
||||||
|
KC_LALT,KC_ENT, KC_SPC, KC_RALT,
|
||||||
|
KC_ESC,I3WM, KC_LGUI,MOUSE,
|
||||||
|
MOUSE,CONTROL
|
||||||
|
),
|
||||||
|
|
||||||
|
[_CONTROL] = LAYOUT_6x6(
|
||||||
|
ENC_INIT,ENC_LOAD,ENC_CLOSE,ENC_KEY,_______,_______, ENC_REQ_ALLOW,ENC_REQ_DENY,_______,_______,_______,EEP_RST,
|
||||||
|
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,KC_DEL,
|
||||||
|
_______,_______,KC_PGDN,KC_UP,KC_PGUP,_______, _______,KC_7,KC_8,KC_9,_______,_______,
|
||||||
|
_______,_______,KC_LEFT,KC_DOWN,KC_RGHT,_______, KC_HOME,KC_4,KC_5,KC_6,KC_END,_______,
|
||||||
|
_______,_______,_______,_______,_______,_______, _______,KC_1,KC_2,KC_3,VIS_VAD,_______,
|
||||||
|
_______,VIS_VAI,_______, KC_0,_______,
|
||||||
|
RGB_MOD,RGB_RMOD, KC_ENT,RGB_VAI,
|
||||||
|
RGB_SPD,RGB_SPI, RGB_VAD,RGB_TOG,
|
||||||
|
QWERTZ,_______
|
||||||
|
),
|
||||||
|
|
||||||
|
[_I3WM] = LAYOUT_6x6(
|
||||||
|
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,
|
||||||
|
_______,LGUI(KC_1),LGUI(KC_2),LGUI(KC_3),LGUI(KC_4),LGUI(KC_5), LGUI(KC_6),LGUI(KC_7),LGUI(KC_8),LGUI(KC_9),LGUI(KC_0),_______,
|
||||||
|
_______,SGUI(KC_C),LGUI(KC_W),LGUI(KC_E),_______,_______, LGUI(KC_Y),_______,LGUI(KC_I),_______,LGUI(KC_P),_______,
|
||||||
|
_______,LGUI(KC_ENT),LGUI(KC_S),LGUI(KC_D),_______,_______, LGUI(KC_H),LGUI(KC_J),LGUI(KC_K),LGUI(KC_L),_______,_______,
|
||||||
|
_______,_______,_______,LGUI(KC_C),_______,_______, LAG(KC_N),_______,_______,_______,_______,_______,
|
||||||
|
_______,_______,_______, _______,_______,
|
||||||
|
_______,_______, LGUI(KC_ENT),_______,
|
||||||
|
_______,_______, _______,_______,
|
||||||
|
QWERTZ,_______
|
||||||
|
),
|
||||||
|
|
||||||
|
[_MOUSE] = LAYOUT_6x6(
|
||||||
|
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,
|
||||||
|
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,
|
||||||
|
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,
|
||||||
|
_______,_______,KC_MS_BTN2,KC_MS_BTN3,KC_MS_BTN1,_______, _______,_______,_______,_______,_______,_______,
|
||||||
|
_______,_______,_______,_______,_______,_______, _______,KC_MS_BTN1,KC_MS_BTN3,KC_MS_BTN2,_______,_______,
|
||||||
|
_______,_______,_______, KC_MS_WH_DOWN,KC_MS_WH_UP,
|
||||||
|
_______,_______, KC_SPC,CPI_NEXT,
|
||||||
|
_______,_______, CPI_PREV,QWERTZ,
|
||||||
|
_______,QWERTZ
|
||||||
|
),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef OLED_ENABLE
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int get_val_percent(void) {
|
||||||
|
#ifdef RGB_MATRIX_MAXIMUM_BRIGHTNESS
|
||||||
|
uint8_t maxVal = RGB_MATRIX_MAXIMUM_BRIGHTNESS;
|
||||||
|
#else
|
||||||
|
uint8_t maxVal = 255;
|
||||||
|
#endif
|
||||||
|
uint8_t actVal = rgb_matrix_get_val();
|
||||||
|
|
||||||
|
float ret = ((float) 100)/((float) maxVal)*((float)actVal);
|
||||||
|
|
||||||
|
return ((int) ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_speed_percent(void) {
|
||||||
|
uint8_t maxVal = 255;
|
||||||
|
uint8_t actVal = rgb_matrix_get_speed();
|
||||||
|
|
||||||
|
float ret = ((float) 100)/((float) maxVal)*((float)actVal);
|
||||||
|
|
||||||
|
return ((int) ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef POINTING_DEVICE_ENABLE
|
||||||
|
static uint16_t _cpi;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static uint8_t _vis_timeout_sec;
|
||||||
|
static uint32_t _vis_timer;
|
||||||
|
static bool _vis_status;
|
||||||
|
|
||||||
|
bool oled_task_user(void) {
|
||||||
|
// Host Keyboard Layer Status
|
||||||
|
if(is_keyboard_master()) {
|
||||||
|
uint32_t _oled_timeout = ((_vis_timeout_sec * 1000) - timer_elapsed32(_vis_timer)) / 1000;
|
||||||
|
if (!_vis_status) {
|
||||||
|
// turn displays off
|
||||||
|
oled_off();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
oled_write_P(PSTR("L: "), false);
|
||||||
|
|
||||||
|
switch (get_highest_layer(layer_state)) {
|
||||||
|
case _QWERTZ:
|
||||||
|
oled_write_P(PSTR("Quertz\n"), false);
|
||||||
|
break;
|
||||||
|
case _CONTROL:
|
||||||
|
oled_write_P(PSTR("Control\n"), false);
|
||||||
|
break;
|
||||||
|
case _I3WM:
|
||||||
|
oled_write_P(PSTR("I3WM\n"), false);
|
||||||
|
break;
|
||||||
|
case _MOUSE:
|
||||||
|
oled_write_P(PSTR("MOUSE\n"), false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
oled_write_P(PSTR("Undefined\n"), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
char brightness[100];
|
||||||
|
memset(brightness, 0x00, 100);
|
||||||
|
if (rgb_matrix_is_enabled()) {
|
||||||
|
snprintf(brightness, 100, "B: %d%% S: %d%%\n", get_val_percent(), get_speed_percent());
|
||||||
|
} else {
|
||||||
|
snprintf(brightness, 100, "B: OFF\n");
|
||||||
|
}
|
||||||
|
oled_write_P(PSTR(brightness), false);
|
||||||
|
|
||||||
|
#ifdef POINTING_DEVICE_ENABLE
|
||||||
|
switch(_cpi) {
|
||||||
|
case 100:
|
||||||
|
oled_write_P(PSTR("M: >\n"), false);
|
||||||
|
break;
|
||||||
|
case 200:
|
||||||
|
oled_write_P(PSTR("M: >>\n"), false);
|
||||||
|
break;
|
||||||
|
case 400:
|
||||||
|
oled_write_P(PSTR("M: >>>\n"), false);
|
||||||
|
break;
|
||||||
|
case 500:
|
||||||
|
oled_write_P(PSTR("M: >>>>\n"), false);
|
||||||
|
break;
|
||||||
|
case 600:
|
||||||
|
oled_write_P(PSTR("M: >>>>>\n"), false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
oled_write_P(PSTR("V: "), false);
|
||||||
|
oled_write_P(get_u8_str(_oled_timeout, ' '), false);
|
||||||
|
oled_write_P(PSTR("s\n"), false);
|
||||||
|
} else {
|
||||||
|
#ifdef ENC_ENABLE
|
||||||
|
enc_write_oled(false);
|
||||||
|
#endif
|
||||||
|
oled_write_P(PSTR("L: "), false);
|
||||||
|
|
||||||
|
switch (get_highest_layer(layer_state)) {
|
||||||
|
case _QWERTZ:
|
||||||
|
oled_write_P(PSTR("Quertz\n"), false);
|
||||||
|
break;
|
||||||
|
case _CONTROL:
|
||||||
|
oled_write_P(PSTR("Control\n"), false);
|
||||||
|
break;
|
||||||
|
case _I3WM:
|
||||||
|
oled_write_P(PSTR("I3WM\n"), false);
|
||||||
|
break;
|
||||||
|
case _MOUSE:
|
||||||
|
oled_write_P(PSTR("MOUSE\n"), false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
oled_write_P(PSTR("Undefined\n"), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef POINTING_DEVICE_ENABLE
|
||||||
|
|
||||||
|
void pointing_device_init_user(void) {
|
||||||
|
_cpi = 400;
|
||||||
|
|
||||||
|
pointing_device_set_cpi(_cpi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cpi_next(void) {
|
||||||
|
switch(_cpi) {
|
||||||
|
case 100:
|
||||||
|
_cpi = 200;
|
||||||
|
break;
|
||||||
|
case 200:
|
||||||
|
_cpi = 400;
|
||||||
|
break;
|
||||||
|
case 400:
|
||||||
|
_cpi = 500;
|
||||||
|
break;
|
||||||
|
case 500:
|
||||||
|
_cpi = 600;
|
||||||
|
break;
|
||||||
|
case 600:
|
||||||
|
_cpi = 100;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointing_device_set_cpi(_cpi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cpi_prev(void) {
|
||||||
|
switch(_cpi) {
|
||||||
|
case 100:
|
||||||
|
_cpi = 600;
|
||||||
|
break;
|
||||||
|
case 200:
|
||||||
|
_cpi = 100;
|
||||||
|
break;
|
||||||
|
case 400:
|
||||||
|
_cpi = 200;
|
||||||
|
break;
|
||||||
|
case 500:
|
||||||
|
_cpi = 400;
|
||||||
|
break;
|
||||||
|
case 600:
|
||||||
|
_cpi = 500;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointing_device_set_cpi(_cpi);
|
||||||
|
}
|
||||||
|
|
||||||
|
report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) {
|
||||||
|
if (!layer_state_is(_MOUSE)) {
|
||||||
|
mouse_report.h = 0;
|
||||||
|
mouse_report.v = 0;
|
||||||
|
mouse_report.x = 0;
|
||||||
|
mouse_report.y = 0;
|
||||||
|
}
|
||||||
|
return mouse_report;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
|
||||||
|
if (!_vis_status) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HSV hsv = (HSV){0, 0, 0};
|
||||||
|
HSV hsv_alt = (HSV){0, 0, 0};
|
||||||
|
bool led_off = false;
|
||||||
|
bool led_alt = false;
|
||||||
|
|
||||||
|
switch(get_highest_layer(layer_state)) { // special handling per layer
|
||||||
|
case _CONTROL:
|
||||||
|
hsv = (HSV){0, 255, 255};
|
||||||
|
break;
|
||||||
|
case _I3WM:
|
||||||
|
hsv = (HSV){85, 255, 255};
|
||||||
|
break;
|
||||||
|
case _MOUSE:
|
||||||
|
hsv = (HSV){170, 255, 255};
|
||||||
|
led_off = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hsv.v = rgb_matrix_get_val();
|
||||||
|
RGB rgb = hsv_to_rgb(hsv);
|
||||||
|
hsv_alt.v = rgb_matrix_get_val();
|
||||||
|
RGB rgb_alt = hsv_to_rgb(hsv_alt);
|
||||||
|
|
||||||
|
for (uint8_t row=0; row<MATRIX_ROWS; ++row) {
|
||||||
|
for (uint8_t col=0; col<MATRIX_COLS; ++col) {
|
||||||
|
uint8_t index = g_led_config.matrix_co[row][col];
|
||||||
|
|
||||||
|
if (index >= led_min && index <= led_max && index != NO_LED) {
|
||||||
|
if (keymap_key_to_keycode(get_highest_layer(layer_state), (keypos_t){col, row}) > KC_TRNS) {
|
||||||
|
rgb_matrix_set_color(index, rgb.r, rgb.g, rgb.b);
|
||||||
|
} else {
|
||||||
|
if (led_alt) {
|
||||||
|
rgb_matrix_set_color(index, rgb_alt.r, rgb_alt.g, rgb_alt.b);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (led_off) {
|
||||||
|
rgb_matrix_set_color(index, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _vis_status {
|
||||||
|
bool m2s_data;
|
||||||
|
} vis_status_t;
|
||||||
|
|
||||||
|
void user_sync_vis_status_slave_handler(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) {
|
||||||
|
const vis_status_t *m2s = (const vis_status_t*)in_data;
|
||||||
|
_vis_status = m2s->m2s_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
if (is_keyboard_master()) {
|
||||||
|
_vis_timer = timer_read32();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (keycode) {
|
||||||
|
#ifdef POINTING_DEVICE_ENABLE
|
||||||
|
case CPI_PREV:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
_cpi_prev();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case CPI_NEXT:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
_cpi_next();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
case VIS_VAD:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
_vis_timeout_sec -= 10;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case VIS_VAI:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
_vis_timeout_sec += 10;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||||
|
switch(index) {
|
||||||
|
case 0:
|
||||||
|
if(clockwise) {
|
||||||
|
tap_code_delay(KC_VOLU, 10);
|
||||||
|
} else {
|
||||||
|
tap_code_delay(KC_VOLD, 10);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void keyboard_pre_init_user(void) {
|
||||||
|
_vis_status = true;
|
||||||
|
_vis_timeout_sec = 120;
|
||||||
|
_vis_timer = timer_read32();
|
||||||
|
pre_init_enc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void eeconfig_init_user(void) {
|
||||||
|
eeconfig_init_enc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void keyboard_post_init_user(void) {
|
||||||
|
transaction_register_rpc(USER_SYNC_VIS_STATUS, user_sync_vis_status_slave_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void housekeeping_task_user(void) {
|
||||||
|
if (is_keyboard_master()) {
|
||||||
|
if (timer_elapsed32(_vis_timer) >= (_vis_timeout_sec * 1000)) {
|
||||||
|
_vis_status = false;
|
||||||
|
} else {
|
||||||
|
_vis_status = true;
|
||||||
|
}
|
||||||
|
static uint32_t last_sync = 0;
|
||||||
|
if (timer_elapsed32(last_sync) > 500) {
|
||||||
|
vis_status_t m2s = {_vis_status};
|
||||||
|
if (transaction_rpc_send(USER_SYNC_VIS_STATUS, sizeof(m2s), &m2s)) {
|
||||||
|
last_sync = timer_read32();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_vis_status) {
|
||||||
|
rgb_matrix_set_color_all(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Build Options
|
||||||
|
# change yes to no to disable
|
||||||
|
#
|
||||||
|
BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
|
||||||
|
MOUSEKEY_ENABLE = yes # Mouse keys
|
||||||
|
EXTRAKEY_ENABLE = yes # Audio control and System control
|
||||||
|
CONSOLE_ENABLE = no # Console for debug
|
||||||
|
COMMAND_ENABLE = no # Commands for debug and configuration
|
||||||
|
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
|
||||||
|
NKRO_ENABLE = yes # USB Nkey Rollover
|
||||||
|
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
|
||||||
|
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
|
||||||
|
AUDIO_ENABLE = no # Audio output
|
||||||
|
SPLIT_KEYBOARD = yes
|
||||||
|
RGB_MATRIX_ENABLE = yes
|
||||||
|
RGB_MATRIX_DRIVER = WS2812
|
||||||
|
WS2812_DRIVER = pwm
|
||||||
|
VIA_ENABLE = yes
|
||||||
|
RAW_ENABLE = yes
|
||||||
|
OLED_ENABLE = yes
|
||||||
|
ENC_ENABLE = yes
|
||||||
|
|
||||||
|
POINTING_DEVICE_ENABLE = yes
|
||||||
|
POINTING_DEVICE_DRIVER = pmw3360
|
||||||
|
#DIP_SWITCH_ENABLE = yes
|
||||||
|
ENCODER_ENABLE = yes
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||||
|
Copyright 2015 Jack Humbert
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "config_common.h"
|
||||||
|
|
||||||
|
/* USB Device descriptor parameter */
|
||||||
|
#define VENDOR_ID 0x44FD
|
||||||
|
#define MANUFACTURER mfulz
|
||||||
|
|
||||||
|
/* mouse config */
|
||||||
|
//#define MOUSEKEY_INTERVAL 20
|
||||||
|
//#define MOUSEKEY_DELAY 0
|
||||||
|
//#define MOUSEKEY_TIME_TO_MAX 60
|
||||||
|
//#define MOUSEKEY_MAX_SPEED 7
|
||||||
|
//#define MOUSEKEY_WHEEL_DELAY 0
|
||||||
|
|
||||||
|
/* Set 0 if debouncing isn't needed */
|
||||||
|
#define DEBOUNCE 5
|
||||||
|
|
||||||
|
/* serial.c configuration for split keyboard */
|
||||||
|
#define SOFT_SERIAL_PIN A3
|
||||||
|
|
||||||
|
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
|
||||||
|
#define LOCKING_SUPPORT_ENABLE
|
||||||
|
/* Locking resynchronize hack */
|
||||||
|
#define LOCKING_RESYNC_ENABLE
|
||||||
|
|
||||||
|
/* Enables This makes it easier for fast typists to use dual-function keys */
|
||||||
|
#define PERMISSIVE_HOLD
|
|
@ -0,0 +1,159 @@
|
||||||
|
Dactyl Manuform (4x5, 5x6, 5x7, 6x6)
|
||||||
|
======
|
||||||
|
the [Dactyl-Manuform](https://github.com/tshort/dactyl-keyboard) is a split curved keyboard based on the design of [adereth dactyl](https://github.com/adereth/dactyl-keyboard) and thumb cluster design of the [manuform](https://geekhack.org/index.php?topic=46015.0) keyboard, the hardware is similar to the let's split keyboard. all information needed for making one is in the first link.
|
||||||
|
![Imgur](https://i.imgur.com/7y0Vbyd.jpg)
|
||||||
|
|
||||||
|
|
||||||
|
## First Time Setup
|
||||||
|
|
||||||
|
Download or clone the `qmk_firmware` repo and navigate to its top level directory. Once your build environment is setup, you'll be able to generate the default .hex using:
|
||||||
|
|
||||||
|
Depending on your Layout chose one of the follwing commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ make handwired/dactyl_manuform/YOUR_LAYOUT:YOUR_KEYMAP_NAME
|
||||||
|
```
|
||||||
|
|
||||||
|
example:
|
||||||
|
```
|
||||||
|
$ make handwired/dactyl_manuform/4x5:default
|
||||||
|
```
|
||||||
|
|
||||||
|
If everything worked correctly you will see a file:
|
||||||
|
|
||||||
|
```
|
||||||
|
dactyl_manuform_YOUR_LAYOUT_YOUR_KEYMAP_NAME.hex
|
||||||
|
```
|
||||||
|
|
||||||
|
For more information on customizing keymaps, take a look at the primary documentation for [Customizing Your Keymap](/docs/faq_keymap.md) in the main readme.md.
|
||||||
|
|
||||||
|
|
||||||
|
## Keymaps
|
||||||
|
|
||||||
|
### [Keymaps 4x5](/keyboards/handwired/dactyl_manuform/4x5/keymaps/)
|
||||||
|
|
||||||
|
#### Default
|
||||||
|
Simple QWERTY layout with 3 Layers.
|
||||||
|
#### Dvorak
|
||||||
|
|
||||||
|
### [Keymaps 5x6](/keyboards/handwired/dactyl_manuform/5x6/keymaps/)
|
||||||
|
|
||||||
|
#### Default
|
||||||
|
Just a copy of the Impstyle keymap. Feel free to adjust it.
|
||||||
|
|
||||||
|
#### Impstyle
|
||||||
|
A simple QWERTY keymap with 3 Layers. Both sides are connected via serial and the Left ist the master.
|
||||||
|
|
||||||
|
### [Keymaps 5x7 aka almost Ergodox](/keyboards/handwired/dactyl_manuform/5x7/keymaps/)
|
||||||
|
#### Default
|
||||||
|
Keymap of Loligagger from geekhack.
|
||||||
|
|
||||||
|
### [Keymaps 6x6](/keyboards/handwired/dactyl_manuform/6x6/keymaps/)
|
||||||
|
|
||||||
|
#### Default
|
||||||
|
Simple QWERTY layout with 3 Layers.
|
||||||
|
|
||||||
|
## Required Hardware
|
||||||
|
|
||||||
|
Apart from diodes and key switches for the keyboard matrix in each half, you
|
||||||
|
will need:
|
||||||
|
|
||||||
|
* 2 Arduino Pro Micros. You can find these on AliExpress for ≈3.50USD each.
|
||||||
|
* 2 TRRS sockets and 1 TRRS cable, or 2 TRS sockets and 1 TRS cable
|
||||||
|
|
||||||
|
Alternatively, you can use any sort of cable and socket that has at least 3
|
||||||
|
wires. If you want to use I2C to communicate between halves, you will need a
|
||||||
|
cable with at least 4 wires and 2x 4.7kΩ pull-up resistors
|
||||||
|
|
||||||
|
## Optional Hardware
|
||||||
|
A speaker can be hooked-up to either side to the `5` (`C6`) pin and `GND`, and turned on via `AUDIO_ENABLE`.
|
||||||
|
|
||||||
|
## Wiring
|
||||||
|
|
||||||
|
The 3 wires of the TRS/TRRS cable need to connect GND, VCC, and digital pin 3 (i.e.
|
||||||
|
PD0 on the ATmega32u4) between the two Pro Micros.
|
||||||
|
|
||||||
|
Next, wire your key matrix to any of the remaining 17 IO pins of the pro micro
|
||||||
|
and modify the `matrix.c` accordingly.
|
||||||
|
|
||||||
|
The wiring for serial:
|
||||||
|
|
||||||
|
![serial wiring](https://i.imgur.com/C3D1GAQ.png)
|
||||||
|
|
||||||
|
The wiring for i2c:
|
||||||
|
|
||||||
|
![i2c wiring](https://i.imgur.com/Hbzhc6E.png)
|
||||||
|
|
||||||
|
The pull-up resistors may be placed on either half. It is also possible
|
||||||
|
to use 4 resistors and have the pull-ups in both halves, but this is
|
||||||
|
unnecessary in simple use cases.
|
||||||
|
|
||||||
|
You can change your configuration between serial and i2c by modifying your `config.h` file.
|
||||||
|
|
||||||
|
## Notes on Software Configuration
|
||||||
|
|
||||||
|
the keymaps in here are for the 4x5 layout of the keyboard only.
|
||||||
|
|
||||||
|
## Flashing
|
||||||
|
|
||||||
|
To flash your firmware take a look at: [Flashing Instructions and Bootloader Information](https://docs.qmk.fm/#/flashing)
|
||||||
|
|
||||||
|
|
||||||
|
## Choosing which board to plug the USB cable into (choosing Master)
|
||||||
|
|
||||||
|
Because the two boards are identical, the firmware has logic to differentiate the left and right board.
|
||||||
|
|
||||||
|
It uses two strategies to figure things out: looking at the EEPROM (memory on the chip) or looking if the current board has the usb cable.
|
||||||
|
|
||||||
|
The EEPROM approach requires additional setup (flashing the eeprom) but allows you to swap the usb cable to either side.
|
||||||
|
|
||||||
|
The USB cable approach is easier to setup and if you just want the usb cable on the left board, you do not need to do anything extra.
|
||||||
|
|
||||||
|
### Setting the left hand as master
|
||||||
|
|
||||||
|
If you always plug the usb cable into the left board, nothing extra is needed as this is the default. Comment out `EE_HANDS` and comment out `I2C_MASTER_RIGHT` or `MASTER_RIGHT` if for some reason it was set.
|
||||||
|
|
||||||
|
### Setting the right hand as master
|
||||||
|
|
||||||
|
If you always plug the usb cable into the right board, add an extra flag to your `config.h`
|
||||||
|
```
|
||||||
|
#define MASTER_RIGHT
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setting EE_hands to use either hands as master
|
||||||
|
|
||||||
|
If you define `EE_HANDS` in your `config.h`, you will need to set the
|
||||||
|
EEPROM for the left and right halves.
|
||||||
|
|
||||||
|
The EEPROM is used to store whether the
|
||||||
|
half is left handed or right handed. This makes it so that the same firmware
|
||||||
|
file will run on both hands instead of having to flash left and right handed
|
||||||
|
versions of the firmware to each half. To flash the EEPROM file for the left
|
||||||
|
half run:
|
||||||
|
```
|
||||||
|
make handwired/dactyl_promicro:default:dfu-split-left
|
||||||
|
make handwired/dactyl_promicro:default:dfu-split-right
|
||||||
|
```
|
||||||
|
|
||||||
|
After you have flashed the EEPROM, you then need to set `EE_HANDS` in your config.h, rebuild the hex files and reflash.
|
||||||
|
|
||||||
|
Note that you need to program both halves, but you have the option of using
|
||||||
|
different keymaps for each half. You could program the left half with a QWERTY
|
||||||
|
layout and the right half with a Colemak layout using bootmagic's default layout option.
|
||||||
|
Then if you connect the left half to a computer by USB the keyboard will use QWERTY and Colemak when the
|
||||||
|
right half is connected.
|
||||||
|
|
||||||
|
|
||||||
|
Notes on Using Pro Micro 3.3V
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Do update the `F_CPU` parameter in `rules.mk` to `8000000` which reflects
|
||||||
|
the frequency on the 3.3V board.
|
||||||
|
|
||||||
|
Also, if the slave board is producing weird characters in certain columns,
|
||||||
|
update the following line in `matrix.c` to the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
// wait_us(30); // without this wait read unstable value.
|
||||||
|
wait_us(300); // without this wait read unstable value.
|
||||||
|
```
|
|
@ -0,0 +1 @@
|
||||||
|
#include "trenctyl_manuform.h"
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(KEYBOARD_handwired_trenctyl_manuform_6x6)
|
||||||
|
# include "6x6.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "quantum.h"
|
|
@ -0,0 +1,572 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode.
|
||||||
|
Block size can be chosen in aes.h - available choices are AES128, AES192, AES256.
|
||||||
|
|
||||||
|
The implementation is verified against the test vectors in:
|
||||||
|
National Institute of Standards and Technology Special Publication 800-38A 2001 ED
|
||||||
|
|
||||||
|
ECB-AES128
|
||||||
|
----------
|
||||||
|
|
||||||
|
plain-text:
|
||||||
|
6bc1bee22e409f96e93d7e117393172a
|
||||||
|
ae2d8a571e03ac9c9eb76fac45af8e51
|
||||||
|
30c81c46a35ce411e5fbc1191a0a52ef
|
||||||
|
f69f2445df4f9b17ad2b417be66c3710
|
||||||
|
|
||||||
|
key:
|
||||||
|
2b7e151628aed2a6abf7158809cf4f3c
|
||||||
|
|
||||||
|
resulting cipher
|
||||||
|
3ad77bb40d7a3660a89ecaf32466ef97
|
||||||
|
f5d3d58503b9699de785895a96fdbaaf
|
||||||
|
43b1cd7f598ece23881b00e3ed030688
|
||||||
|
7b0c785e27e8ad3f8223207104725dd4
|
||||||
|
|
||||||
|
|
||||||
|
NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
|
||||||
|
You should pad the end of the string with zeros if this is not the case.
|
||||||
|
For AES192/256 the key size is proportionally larger.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Includes: */
|
||||||
|
/*****************************************************************************/
|
||||||
|
#include <string.h> // CBC mode, for memset
|
||||||
|
#include "aes.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Defines: */
|
||||||
|
/*****************************************************************************/
|
||||||
|
// The number of columns comprising a state in AES. This is a constant in AES. Value=4
|
||||||
|
#define Nb 4
|
||||||
|
|
||||||
|
#if defined(AES256) && (AES256 == 1)
|
||||||
|
#define Nk 8
|
||||||
|
#define Nr 14
|
||||||
|
#elif defined(AES192) && (AES192 == 1)
|
||||||
|
#define Nk 6
|
||||||
|
#define Nr 12
|
||||||
|
#else
|
||||||
|
#define Nk 4 // The number of 32 bit words in a key.
|
||||||
|
#define Nr 10 // The number of rounds in AES Cipher.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// jcallan@github points out that declaring Multiply as a function
|
||||||
|
// reduces code size considerably with the Keil ARM compiler.
|
||||||
|
// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3
|
||||||
|
#ifndef MULTIPLY_AS_A_FUNCTION
|
||||||
|
#define MULTIPLY_AS_A_FUNCTION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Private variables: */
|
||||||
|
/*****************************************************************************/
|
||||||
|
// state - array holding the intermediate results during decryption.
|
||||||
|
typedef uint8_t state_t[4][4];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
|
||||||
|
// The numbers below can be computed dynamically trading ROM for RAM -
|
||||||
|
// This can be useful in (embedded) bootloader applications, where ROM is often limited.
|
||||||
|
static const uint8_t sbox[256] = {
|
||||||
|
//0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||||
|
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||||
|
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||||
|
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||||
|
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||||
|
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||||
|
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||||
|
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||||
|
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||||
|
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||||
|
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||||
|
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||||
|
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||||
|
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||||
|
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||||
|
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||||
|
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
|
||||||
|
|
||||||
|
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
|
||||||
|
static const uint8_t rsbox[256] = {
|
||||||
|
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||||
|
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||||
|
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
||||||
|
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
||||||
|
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
|
||||||
|
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
||||||
|
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
|
||||||
|
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
||||||
|
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
|
||||||
|
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
||||||
|
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
|
||||||
|
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
||||||
|
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||||
|
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
||||||
|
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
||||||
|
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The round constant word array, Rcon[i], contains the values given by
|
||||||
|
// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
|
||||||
|
static const uint8_t Rcon[11] = {
|
||||||
|
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12),
|
||||||
|
* that you can remove most of the elements in the Rcon array, because they are unused.
|
||||||
|
*
|
||||||
|
* From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
|
||||||
|
*
|
||||||
|
* "Only the first some of these constants are actually used – up to rcon[10] for AES-128 (as 11 round keys are needed),
|
||||||
|
* up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Private functions: */
|
||||||
|
/*****************************************************************************/
|
||||||
|
/*
|
||||||
|
static uint8_t getSBoxValue(uint8_t num)
|
||||||
|
{
|
||||||
|
return sbox[num];
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#define getSBoxValue(num) (sbox[(num)])
|
||||||
|
|
||||||
|
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
|
||||||
|
static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
|
||||||
|
{
|
||||||
|
unsigned i, j, k;
|
||||||
|
uint8_t tempa[4]; // Used for the column/row operations
|
||||||
|
|
||||||
|
// The first round key is the key itself.
|
||||||
|
for (i = 0; i < Nk; ++i)
|
||||||
|
{
|
||||||
|
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
|
||||||
|
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
|
||||||
|
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
|
||||||
|
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
// All other round keys are found from the previous round keys.
|
||||||
|
for (i = Nk; i < Nb * (Nr + 1); ++i)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
k = (i - 1) * 4;
|
||||||
|
tempa[0]=RoundKey[k + 0];
|
||||||
|
tempa[1]=RoundKey[k + 1];
|
||||||
|
tempa[2]=RoundKey[k + 2];
|
||||||
|
tempa[3]=RoundKey[k + 3];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i % Nk == 0)
|
||||||
|
{
|
||||||
|
// This function shifts the 4 bytes in a word to the left once.
|
||||||
|
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
|
||||||
|
|
||||||
|
// Function RotWord()
|
||||||
|
{
|
||||||
|
const uint8_t u8tmp = tempa[0];
|
||||||
|
tempa[0] = tempa[1];
|
||||||
|
tempa[1] = tempa[2];
|
||||||
|
tempa[2] = tempa[3];
|
||||||
|
tempa[3] = u8tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubWord() is a function that takes a four-byte input word and
|
||||||
|
// applies the S-box to each of the four bytes to produce an output word.
|
||||||
|
|
||||||
|
// Function Subword()
|
||||||
|
{
|
||||||
|
tempa[0] = getSBoxValue(tempa[0]);
|
||||||
|
tempa[1] = getSBoxValue(tempa[1]);
|
||||||
|
tempa[2] = getSBoxValue(tempa[2]);
|
||||||
|
tempa[3] = getSBoxValue(tempa[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
tempa[0] = tempa[0] ^ Rcon[i/Nk];
|
||||||
|
}
|
||||||
|
#if defined(AES256) && (AES256 == 1)
|
||||||
|
if (i % Nk == 4)
|
||||||
|
{
|
||||||
|
// Function Subword()
|
||||||
|
{
|
||||||
|
tempa[0] = getSBoxValue(tempa[0]);
|
||||||
|
tempa[1] = getSBoxValue(tempa[1]);
|
||||||
|
tempa[2] = getSBoxValue(tempa[2]);
|
||||||
|
tempa[3] = getSBoxValue(tempa[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
j = i * 4; k=(i - Nk) * 4;
|
||||||
|
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
|
||||||
|
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
|
||||||
|
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
|
||||||
|
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key)
|
||||||
|
{
|
||||||
|
KeyExpansion(ctx->RoundKey, key);
|
||||||
|
}
|
||||||
|
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
|
||||||
|
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv)
|
||||||
|
{
|
||||||
|
KeyExpansion(ctx->RoundKey, key);
|
||||||
|
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
|
||||||
|
}
|
||||||
|
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
|
||||||
|
{
|
||||||
|
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This function adds the round key to state.
|
||||||
|
// The round key is added to the state by an XOR function.
|
||||||
|
static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey)
|
||||||
|
{
|
||||||
|
uint8_t i,j;
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 4; ++j)
|
||||||
|
{
|
||||||
|
(*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The SubBytes Function Substitutes the values in the
|
||||||
|
// state matrix with values in an S-box.
|
||||||
|
static void SubBytes(state_t* state)
|
||||||
|
{
|
||||||
|
uint8_t i, j;
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 4; ++j)
|
||||||
|
{
|
||||||
|
(*state)[j][i] = getSBoxValue((*state)[j][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The ShiftRows() function shifts the rows in the state to the left.
|
||||||
|
// Each row is shifted with different offset.
|
||||||
|
// Offset = Row number. So the first row is not shifted.
|
||||||
|
static void ShiftRows(state_t* state)
|
||||||
|
{
|
||||||
|
uint8_t temp;
|
||||||
|
|
||||||
|
// Rotate first row 1 columns to left
|
||||||
|
temp = (*state)[0][1];
|
||||||
|
(*state)[0][1] = (*state)[1][1];
|
||||||
|
(*state)[1][1] = (*state)[2][1];
|
||||||
|
(*state)[2][1] = (*state)[3][1];
|
||||||
|
(*state)[3][1] = temp;
|
||||||
|
|
||||||
|
// Rotate second row 2 columns to left
|
||||||
|
temp = (*state)[0][2];
|
||||||
|
(*state)[0][2] = (*state)[2][2];
|
||||||
|
(*state)[2][2] = temp;
|
||||||
|
|
||||||
|
temp = (*state)[1][2];
|
||||||
|
(*state)[1][2] = (*state)[3][2];
|
||||||
|
(*state)[3][2] = temp;
|
||||||
|
|
||||||
|
// Rotate third row 3 columns to left
|
||||||
|
temp = (*state)[0][3];
|
||||||
|
(*state)[0][3] = (*state)[3][3];
|
||||||
|
(*state)[3][3] = (*state)[2][3];
|
||||||
|
(*state)[2][3] = (*state)[1][3];
|
||||||
|
(*state)[1][3] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t xtime(uint8_t x)
|
||||||
|
{
|
||||||
|
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
|
||||||
|
}
|
||||||
|
|
||||||
|
// MixColumns function mixes the columns of the state matrix
|
||||||
|
static void MixColumns(state_t* state)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t Tmp, Tm, t;
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
t = (*state)[i][0];
|
||||||
|
Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
|
||||||
|
Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;
|
||||||
|
Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;
|
||||||
|
Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;
|
||||||
|
Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiply is used to multiply numbers in the field GF(2^8)
|
||||||
|
// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary
|
||||||
|
// The compiler seems to be able to vectorize the operation better this way.
|
||||||
|
// See https://github.com/kokke/tiny-AES-c/pull/34
|
||||||
|
#if MULTIPLY_AS_A_FUNCTION
|
||||||
|
static uint8_t Multiply(uint8_t x, uint8_t y)
|
||||||
|
{
|
||||||
|
return (((y & 1) * x) ^
|
||||||
|
((y>>1 & 1) * xtime(x)) ^
|
||||||
|
((y>>2 & 1) * xtime(xtime(x))) ^
|
||||||
|
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
|
||||||
|
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define Multiply(x, y) \
|
||||||
|
( ((y & 1) * x) ^ \
|
||||||
|
((y>>1 & 1) * xtime(x)) ^ \
|
||||||
|
((y>>2 & 1) * xtime(xtime(x))) ^ \
|
||||||
|
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
|
||||||
|
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
|
||||||
|
/*
|
||||||
|
static uint8_t getSBoxInvert(uint8_t num)
|
||||||
|
{
|
||||||
|
return rsbox[num];
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#define getSBoxInvert(num) (rsbox[(num)])
|
||||||
|
|
||||||
|
// MixColumns function mixes the columns of the state matrix.
|
||||||
|
// The method used to multiply may be difficult to understand for the inexperienced.
|
||||||
|
// Please use the references to gain more information.
|
||||||
|
static void InvMixColumns(state_t* state)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint8_t a, b, c, d;
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
a = (*state)[i][0];
|
||||||
|
b = (*state)[i][1];
|
||||||
|
c = (*state)[i][2];
|
||||||
|
d = (*state)[i][3];
|
||||||
|
|
||||||
|
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
|
||||||
|
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
|
||||||
|
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
|
||||||
|
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The SubBytes Function Substitutes the values in the
|
||||||
|
// state matrix with values in an S-box.
|
||||||
|
static void InvSubBytes(state_t* state)
|
||||||
|
{
|
||||||
|
uint8_t i, j;
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 4; ++j)
|
||||||
|
{
|
||||||
|
(*state)[j][i] = getSBoxInvert((*state)[j][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InvShiftRows(state_t* state)
|
||||||
|
{
|
||||||
|
uint8_t temp;
|
||||||
|
|
||||||
|
// Rotate first row 1 columns to right
|
||||||
|
temp = (*state)[3][1];
|
||||||
|
(*state)[3][1] = (*state)[2][1];
|
||||||
|
(*state)[2][1] = (*state)[1][1];
|
||||||
|
(*state)[1][1] = (*state)[0][1];
|
||||||
|
(*state)[0][1] = temp;
|
||||||
|
|
||||||
|
// Rotate second row 2 columns to right
|
||||||
|
temp = (*state)[0][2];
|
||||||
|
(*state)[0][2] = (*state)[2][2];
|
||||||
|
(*state)[2][2] = temp;
|
||||||
|
|
||||||
|
temp = (*state)[1][2];
|
||||||
|
(*state)[1][2] = (*state)[3][2];
|
||||||
|
(*state)[3][2] = temp;
|
||||||
|
|
||||||
|
// Rotate third row 3 columns to right
|
||||||
|
temp = (*state)[0][3];
|
||||||
|
(*state)[0][3] = (*state)[1][3];
|
||||||
|
(*state)[1][3] = (*state)[2][3];
|
||||||
|
(*state)[2][3] = (*state)[3][3];
|
||||||
|
(*state)[3][3] = temp;
|
||||||
|
}
|
||||||
|
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
|
||||||
|
|
||||||
|
// Cipher is the main function that encrypts the PlainText.
|
||||||
|
static void Cipher(state_t* state, const uint8_t* RoundKey)
|
||||||
|
{
|
||||||
|
uint8_t round = 0;
|
||||||
|
|
||||||
|
// Add the First round key to the state before starting the rounds.
|
||||||
|
AddRoundKey(0, state, RoundKey);
|
||||||
|
|
||||||
|
// There will be Nr rounds.
|
||||||
|
// The first Nr-1 rounds are identical.
|
||||||
|
// These Nr rounds are executed in the loop below.
|
||||||
|
// Last one without MixColumns()
|
||||||
|
for (round = 1; ; ++round)
|
||||||
|
{
|
||||||
|
SubBytes(state);
|
||||||
|
ShiftRows(state);
|
||||||
|
if (round == Nr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
MixColumns(state);
|
||||||
|
AddRoundKey(round, state, RoundKey);
|
||||||
|
}
|
||||||
|
// Add round key to last round
|
||||||
|
AddRoundKey(Nr, state, RoundKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
|
||||||
|
static void InvCipher(state_t* state, const uint8_t* RoundKey)
|
||||||
|
{
|
||||||
|
uint8_t round = 0;
|
||||||
|
|
||||||
|
// Add the First round key to the state before starting the rounds.
|
||||||
|
AddRoundKey(Nr, state, RoundKey);
|
||||||
|
|
||||||
|
// There will be Nr rounds.
|
||||||
|
// The first Nr-1 rounds are identical.
|
||||||
|
// These Nr rounds are executed in the loop below.
|
||||||
|
// Last one without InvMixColumn()
|
||||||
|
for (round = (Nr - 1); ; --round)
|
||||||
|
{
|
||||||
|
InvShiftRows(state);
|
||||||
|
InvSubBytes(state);
|
||||||
|
AddRoundKey(round, state, RoundKey);
|
||||||
|
if (round == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
InvMixColumns(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Public functions: */
|
||||||
|
/*****************************************************************************/
|
||||||
|
#if defined(ECB) && (ECB == 1)
|
||||||
|
|
||||||
|
|
||||||
|
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf)
|
||||||
|
{
|
||||||
|
// The next function call encrypts the PlainText with the Key using AES algorithm.
|
||||||
|
Cipher((state_t*)buf, ctx->RoundKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf)
|
||||||
|
{
|
||||||
|
// The next function call decrypts the PlainText with the Key using AES algorithm.
|
||||||
|
InvCipher((state_t*)buf, ctx->RoundKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // #if defined(ECB) && (ECB == 1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(CBC) && (CBC == 1)
|
||||||
|
|
||||||
|
|
||||||
|
static void XorWithIv(uint8_t* buf, const uint8_t* Iv)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
|
||||||
|
{
|
||||||
|
buf[i] ^= Iv[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, size_t length)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
uint8_t *Iv = ctx->Iv;
|
||||||
|
for (i = 0; i < length; i += AES_BLOCKLEN)
|
||||||
|
{
|
||||||
|
XorWithIv(buf, Iv);
|
||||||
|
Cipher((state_t*)buf, ctx->RoundKey);
|
||||||
|
Iv = buf;
|
||||||
|
buf += AES_BLOCKLEN;
|
||||||
|
}
|
||||||
|
/* store Iv in ctx for next call */
|
||||||
|
memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
uint8_t storeNextIv[AES_BLOCKLEN];
|
||||||
|
for (i = 0; i < length; i += AES_BLOCKLEN)
|
||||||
|
{
|
||||||
|
memcpy(storeNextIv, buf, AES_BLOCKLEN);
|
||||||
|
InvCipher((state_t*)buf, ctx->RoundKey);
|
||||||
|
XorWithIv(buf, ctx->Iv);
|
||||||
|
memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
|
||||||
|
buf += AES_BLOCKLEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #if defined(CBC) && (CBC == 1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(CTR) && (CTR == 1)
|
||||||
|
|
||||||
|
/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */
|
||||||
|
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
|
||||||
|
{
|
||||||
|
uint8_t buffer[AES_BLOCKLEN];
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
int bi;
|
||||||
|
for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
|
||||||
|
{
|
||||||
|
if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
|
||||||
|
{
|
||||||
|
|
||||||
|
memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
|
||||||
|
Cipher((state_t*)buffer,ctx->RoundKey);
|
||||||
|
|
||||||
|
/* Increment Iv and handle overflow */
|
||||||
|
for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
|
||||||
|
{
|
||||||
|
/* inc will overflow */
|
||||||
|
if (ctx->Iv[bi] == 255)
|
||||||
|
{
|
||||||
|
ctx->Iv[bi] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ctx->Iv[bi] += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bi = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[i] = (buf[i] ^ buffer[bi]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #if defined(CTR) && (CTR == 1)
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
#ifndef _AES_H_
|
||||||
|
#define _AES_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// #define the macros below to 1/0 to enable/disable the mode of operation.
|
||||||
|
//
|
||||||
|
// CBC enables AES encryption in CBC-mode of operation.
|
||||||
|
// CTR enables encryption in counter-mode.
|
||||||
|
// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously.
|
||||||
|
|
||||||
|
// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
|
||||||
|
#ifndef CBC
|
||||||
|
#define CBC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ECB
|
||||||
|
#define ECB 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CTR
|
||||||
|
#define CTR 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//#define AES128 1
|
||||||
|
//#define AES192 1
|
||||||
|
#define AES256 1
|
||||||
|
|
||||||
|
#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only
|
||||||
|
|
||||||
|
#if defined(AES256) && (AES256 == 1)
|
||||||
|
#define AES_KEYLEN 32
|
||||||
|
#define AES_keyExpSize 240
|
||||||
|
#elif defined(AES192) && (AES192 == 1)
|
||||||
|
#define AES_KEYLEN 24
|
||||||
|
#define AES_keyExpSize 208
|
||||||
|
#else
|
||||||
|
#define AES_KEYLEN 16 // Key length in bytes
|
||||||
|
#define AES_keyExpSize 176
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct AES_ctx
|
||||||
|
{
|
||||||
|
uint8_t RoundKey[AES_keyExpSize];
|
||||||
|
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
|
||||||
|
uint8_t Iv[AES_BLOCKLEN];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
|
||||||
|
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
|
||||||
|
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
|
||||||
|
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ECB) && (ECB == 1)
|
||||||
|
// buffer size is exactly AES_BLOCKLEN bytes;
|
||||||
|
// you need only AES_init_ctx as IV is not used in ECB
|
||||||
|
// NB: ECB is considered insecure for most uses
|
||||||
|
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf);
|
||||||
|
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf);
|
||||||
|
|
||||||
|
#endif // #if defined(ECB) && (ECB == !)
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(CBC) && (CBC == 1)
|
||||||
|
// buffer size MUST be mutile of AES_BLOCKLEN;
|
||||||
|
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
|
||||||
|
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
|
||||||
|
// no IV should ever be reused with the same key
|
||||||
|
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
|
||||||
|
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
|
||||||
|
|
||||||
|
#endif // #if defined(CBC) && (CBC == 1)
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(CTR) && (CTR == 1)
|
||||||
|
|
||||||
|
// Same function for encrypting as for decrypting.
|
||||||
|
// IV is incremented for every block, and used after encryption as XOR-compliment for output
|
||||||
|
// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
|
||||||
|
// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
|
||||||
|
// no IV should ever be reused with the same key
|
||||||
|
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
|
||||||
|
|
||||||
|
#endif // #if defined(CTR) && (CTR == 1)
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _AES_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,174 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "quantum.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define CBC 1
|
||||||
|
|
||||||
|
#define ENC_ERR_OK 0x00
|
||||||
|
#define ENC_ERR_EMPTY_BUF 0x01
|
||||||
|
#define ENC_ERR_NO_CTX 0x02
|
||||||
|
#define ENC_ERR_NOT_ALLOWED 0x03
|
||||||
|
#define ENC_ERR_INVALID 0x04
|
||||||
|
#define ENC_ERR_RETRY 0x05
|
||||||
|
#define ENC_ERR_HW_SUPPORT 0x06
|
||||||
|
#define ENC_ERR_MORE_DATA 0x07
|
||||||
|
|
||||||
|
#define ENC_CMD_RESET 0x00
|
||||||
|
#define ENC_CMD_ENCRYPT 0x01
|
||||||
|
#define ENC_CMD_DECRYPT 0x02
|
||||||
|
#define ENC_CMD_MORE_DATA 0x03
|
||||||
|
#define ENC_CMD_UNLOCK 0x04
|
||||||
|
#define ENC_CMD_LOCK 0x05
|
||||||
|
#define ENC_CMD_SET_CFG 0x06
|
||||||
|
#define ENC_CMD_GET_MODE 0x07
|
||||||
|
#define ENC_CMD_GET_BUFFER 0x08
|
||||||
|
#define ENC_CMD_GET_KEYS 0x09
|
||||||
|
#define ENC_CMD_GET_BUFSIZE 0x0A
|
||||||
|
#define ENC_CMD_SET_KEYS 0x0B
|
||||||
|
#define ENC_CMD_GET_CFG 0x0C
|
||||||
|
#define ENC_CMD_INITIALIZE 0x0D
|
||||||
|
#define ENC_CMD_NONE 0x0E
|
||||||
|
#define ENC_CMD_SET_BUFFER 0x0F
|
||||||
|
|
||||||
|
#define ENC_MODE_CLOSED 0x00
|
||||||
|
#define ENC_MODE_OPEN 0x01
|
||||||
|
#define ENC_MODE_LOAD 0x02
|
||||||
|
#define ENC_MODE_INIT 0x03
|
||||||
|
#define ENC_MODE_KEY 0x04
|
||||||
|
|
||||||
|
#define ENC_SUB_MODE_NONE 0x00
|
||||||
|
#define ENC_SUB_MODE_SEED 0x01
|
||||||
|
#define ENC_SUB_MODE_PASSWORD 0x02
|
||||||
|
#define ENC_SUB_MODE_VERIFY_PASSWORD 0x03
|
||||||
|
#define ENC_SUB_MODE_REQUEST 0x04
|
||||||
|
#define ENC_SUB_MODE_REQUEST_ALLOW 0x05
|
||||||
|
#define ENC_SUB_MODE_REQUEST_DENY 0x06
|
||||||
|
#define ENC_SUB_MODE_KEY 0x07
|
||||||
|
|
||||||
|
#define ENC_CFG_PARANOIA 0x00
|
||||||
|
#define ENC_CFG_SECURE 0x01
|
||||||
|
#define ENC_CFG_MAX_ERROR 0x02
|
||||||
|
#define ENC_CFG_TIMEOUT 0x03
|
||||||
|
|
||||||
|
#define ENC_FALSE 0x00
|
||||||
|
#define ENC_TRUE 0x01
|
||||||
|
|
||||||
|
#define ENC_EEPROM_SIZE 123
|
||||||
|
|
||||||
|
#ifdef VIA_ENABLE
|
||||||
|
# include "via.h"
|
||||||
|
# define ENC_EEPROM_ADDR (VIA_EEPROM_CUSTOM_CONFIG_ADDR - ENC_EEPROM_SIZE)
|
||||||
|
#else
|
||||||
|
# include "eeconfig.h"
|
||||||
|
# define ENC_EEPROM_ADDR (EECONFIG_SIZE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
unsigned int max_error:4;
|
||||||
|
unsigned int error_count:4;
|
||||||
|
unsigned int paranoia_mode:1;
|
||||||
|
unsigned int secure_mode:1;
|
||||||
|
unsigned int timeout:6;
|
||||||
|
unsigned int initialized:1;
|
||||||
|
unsigned int reserved:7;
|
||||||
|
} enc_config_flags_t;
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
enc_config_flags_t flags;
|
||||||
|
uint8_t identifier[8];
|
||||||
|
uint8_t salt[16];
|
||||||
|
uint8_t validate[32];
|
||||||
|
uint8_t key_store[64];
|
||||||
|
} enc_config_t;
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
uint32_t seed;
|
||||||
|
uint8_t key[32];
|
||||||
|
} enc_keys_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t mode;
|
||||||
|
uint8_t sub_mode;
|
||||||
|
uint32_t pw_timeout;
|
||||||
|
bool pw_timeout_enabled;
|
||||||
|
uint8_t req_cmd;
|
||||||
|
uint32_t req_timeout;
|
||||||
|
bool req_timeout_enabled;
|
||||||
|
// key just temporary
|
||||||
|
uint8_t key[64];
|
||||||
|
uint16_t key_size;
|
||||||
|
} enc_mode_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t pw[32];
|
||||||
|
uint16_t pw_check[32];
|
||||||
|
uint16_t pw_size;
|
||||||
|
uint16_t pw_check_size;
|
||||||
|
bool pw_ready;
|
||||||
|
bool pw_check_ready;
|
||||||
|
uint8_t key[64];
|
||||||
|
uint16_t key_size;
|
||||||
|
bool key_ready;
|
||||||
|
uint32_t seed;
|
||||||
|
bool seed_ready;
|
||||||
|
uint32_t pw_timer;
|
||||||
|
uint32_t req_timer;
|
||||||
|
bool cfg_ready;
|
||||||
|
} enc_state_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
enc_mode_t mode;
|
||||||
|
enc_config_t cnf;
|
||||||
|
enc_keys_t keys;
|
||||||
|
enc_state_t state;
|
||||||
|
} ENC_CTX;
|
||||||
|
|
||||||
|
#define ENC_REQUEST_HEADER_LEN 9
|
||||||
|
|
||||||
|
#define ENC_RESPONSE_HEADER_POS_SIZE 1
|
||||||
|
#define ENC_RESPONSE_HEADER_LEN 3
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
uint8_t magic[2];
|
||||||
|
uint8_t cmd;
|
||||||
|
uint16_t size;
|
||||||
|
uint32_t id;
|
||||||
|
} enc_request_header_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t *data;
|
||||||
|
uint16_t dsize;
|
||||||
|
uint16_t dpos;
|
||||||
|
} enc_data_buffer_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
enc_request_header_t req_header;
|
||||||
|
enc_data_buffer_t data;
|
||||||
|
uint8_t req_cmd;
|
||||||
|
uint32_t req_id;
|
||||||
|
uint8_t state_cmd;
|
||||||
|
uint8_t state_cmd_old;
|
||||||
|
uint8_t *res_data;
|
||||||
|
uint32_t req_timer;
|
||||||
|
} enc_request_state_t;
|
||||||
|
|
||||||
|
#define ENC_HID_REQUEST_TIMEOUT 30
|
||||||
|
|
||||||
|
// Called by QMK core to process ENC-specific keycodes.
|
||||||
|
bool process_record_enc(uint16_t keycode, keyrecord_t *record);
|
||||||
|
|
||||||
|
// called to allow having config ready instantly
|
||||||
|
void pre_init_enc(void);
|
||||||
|
void eeconfig_init_enc(void);
|
||||||
|
|
||||||
|
enc_config_flags_t enc_get_config_flags(void);
|
||||||
|
void enc_set_config_flags(enc_config_flags_t);
|
||||||
|
enc_mode_t enc_get_mode(void);
|
||||||
|
void enc_set_mode(enc_mode_t);
|
||||||
|
|
||||||
|
const char* enc_mode_to_str(uint8_t mode);
|
||||||
|
const char* enc_sub_mode_to_str(uint8_t mode);
|
||||||
|
const char* enc_cmd_to_str(uint8_t cmd);
|
||||||
|
void enc_write_oled(bool invert);
|
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef ENC_OPTLOCK
|
||||||
|
# undef ENC_OPTLOCK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(STM32F401xx) || defined(STMF411xx)
|
||||||
|
# define ENC_OPTLOCK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENC_OPTLOCK
|
||||||
|
void enc_flash_lock(void);
|
||||||
|
int enc_is_flash_locked(void);
|
||||||
|
#endif
|
|
@ -0,0 +1,3 @@
|
||||||
|
ifneq ($(filter %_STM32F401xC %_STM32F401xE %_STM32F405xG %_STM32F411xE, %_STM32F412xB, $(MCU_SERIES)_$(MCU_LDSCRIPT)),)
|
||||||
|
SRC += enc_stm32f40xx_stm32f41xx.c
|
||||||
|
endif
|
|
@ -0,0 +1,51 @@
|
||||||
|
#include "hal.h"
|
||||||
|
#include "enc.h"
|
||||||
|
|
||||||
|
#define FLASH_OPTKEY1 0x08192A3B
|
||||||
|
#define FLASH_OPTKEY2 0x4C5D6E7F
|
||||||
|
|
||||||
|
static inline void OPT_WaitNotBusy(void) {
|
||||||
|
uint32_t sr = 0;
|
||||||
|
for (sr = FLASH->SR; sr & FLASH_SR_BSY; sr = FLASH->SR) {
|
||||||
|
__WFI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void OPT_Unlock(void) {
|
||||||
|
OPT_WaitNotBusy();
|
||||||
|
if (FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) {
|
||||||
|
FLASH->OPTKEYR = FLASH_OPTKEY1;
|
||||||
|
FLASH->OPTKEYR = FLASH_OPTKEY2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void OPT_Lock(void) {
|
||||||
|
OPT_WaitNotBusy();
|
||||||
|
FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void OPT_Set(uint32_t OptionBytes) {
|
||||||
|
__IO uint32_t *optionBytes = &(FLASH->OPTCR);
|
||||||
|
if (*optionBytes != OptionBytes) {
|
||||||
|
OPT_Unlock();
|
||||||
|
*optionBytes = OptionBytes;
|
||||||
|
FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT;
|
||||||
|
OPT_Lock();
|
||||||
|
/*NVIC_SystemReset();*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool enc_is_flash_locked(void) {
|
||||||
|
if (FLASH->OPTCR & FLASH_OPTCR_RDP) {
|
||||||
|
return ENC_TRUE;
|
||||||
|
}
|
||||||
|
return ENC_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void enc_flash_lock(void) {
|
||||||
|
OPT_Unlock();
|
||||||
|
FLASH->OPTCR |= FLASH_OPTCR_RDP;
|
||||||
|
FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT;
|
||||||
|
OPT_Lock();
|
||||||
|
/*NVIC_SystemReset();*/
|
||||||
|
}
|
|
@ -0,0 +1,855 @@
|
||||||
|
/*
|
||||||
|
* FIPS-180-2 compliant SHA-256 implementation
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2010, Brainspark B.V.
|
||||||
|
*
|
||||||
|
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||||
|
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
|
||||||
|
*
|
||||||
|
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned long total[2]; /*!< number of bytes processed */
|
||||||
|
unsigned long state[8]; /*!< intermediate digest state */
|
||||||
|
unsigned char buffer[64]; /*!< data block being processed */
|
||||||
|
|
||||||
|
unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||||
|
unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||||
|
int is224; /*!< 0 => SHA-256, else SHA-224 */
|
||||||
|
} sha2_context;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 32-bit integer manipulation macros (big endian)
|
||||||
|
*/
|
||||||
|
#ifndef GET_ULONG_BE
|
||||||
|
#define GET_ULONG_BE(n,b,i) \
|
||||||
|
{ \
|
||||||
|
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
|
||||||
|
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
|
||||||
|
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
|
||||||
|
| ( (unsigned long) (b)[(i) + 3] ); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PUT_ULONG_BE
|
||||||
|
#define PUT_ULONG_BE(n,b,i) \
|
||||||
|
{ \
|
||||||
|
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||||
|
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||||
|
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||||
|
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 context setup
|
||||||
|
*/
|
||||||
|
void sha2_starts( sha2_context *ctx, int is224 )
|
||||||
|
{
|
||||||
|
ctx->total[0] = 0;
|
||||||
|
ctx->total[1] = 0;
|
||||||
|
|
||||||
|
if( is224 == 0 )
|
||||||
|
{
|
||||||
|
/* SHA-256 */
|
||||||
|
ctx->state[0] = 0x6A09E667;
|
||||||
|
ctx->state[1] = 0xBB67AE85;
|
||||||
|
ctx->state[2] = 0x3C6EF372;
|
||||||
|
ctx->state[3] = 0xA54FF53A;
|
||||||
|
ctx->state[4] = 0x510E527F;
|
||||||
|
ctx->state[5] = 0x9B05688C;
|
||||||
|
ctx->state[6] = 0x1F83D9AB;
|
||||||
|
ctx->state[7] = 0x5BE0CD19;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* SHA-224 */
|
||||||
|
ctx->state[0] = 0xC1059ED8;
|
||||||
|
ctx->state[1] = 0x367CD507;
|
||||||
|
ctx->state[2] = 0x3070DD17;
|
||||||
|
ctx->state[3] = 0xF70E5939;
|
||||||
|
ctx->state[4] = 0xFFC00B31;
|
||||||
|
ctx->state[5] = 0x68581511;
|
||||||
|
ctx->state[6] = 0x64F98FA7;
|
||||||
|
ctx->state[7] = 0xBEFA4FA4;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->is224 = is224;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sha2_process( sha2_context *ctx, const unsigned char data[64] )
|
||||||
|
{
|
||||||
|
unsigned long temp1, temp2, W[64];
|
||||||
|
unsigned long A, B, C, D, E, F, G, H;
|
||||||
|
|
||||||
|
GET_ULONG_BE( W[ 0], data, 0 );
|
||||||
|
GET_ULONG_BE( W[ 1], data, 4 );
|
||||||
|
GET_ULONG_BE( W[ 2], data, 8 );
|
||||||
|
GET_ULONG_BE( W[ 3], data, 12 );
|
||||||
|
GET_ULONG_BE( W[ 4], data, 16 );
|
||||||
|
GET_ULONG_BE( W[ 5], data, 20 );
|
||||||
|
GET_ULONG_BE( W[ 6], data, 24 );
|
||||||
|
GET_ULONG_BE( W[ 7], data, 28 );
|
||||||
|
GET_ULONG_BE( W[ 8], data, 32 );
|
||||||
|
GET_ULONG_BE( W[ 9], data, 36 );
|
||||||
|
GET_ULONG_BE( W[10], data, 40 );
|
||||||
|
GET_ULONG_BE( W[11], data, 44 );
|
||||||
|
GET_ULONG_BE( W[12], data, 48 );
|
||||||
|
GET_ULONG_BE( W[13], data, 52 );
|
||||||
|
GET_ULONG_BE( W[14], data, 56 );
|
||||||
|
GET_ULONG_BE( W[15], data, 60 );
|
||||||
|
|
||||||
|
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
|
||||||
|
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
|
||||||
|
|
||||||
|
#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
|
||||||
|
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
|
||||||
|
|
||||||
|
#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
|
||||||
|
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
|
||||||
|
|
||||||
|
#define XF0(x,y,z) ((x & y) | (z & (x | y)))
|
||||||
|
#define XF1(x,y,z) (z ^ (x & (y ^ z)))
|
||||||
|
|
||||||
|
#define R(t) \
|
||||||
|
( \
|
||||||
|
W[t] = S1(W[t - 2]) + W[t - 7] + \
|
||||||
|
S0(W[t - 15]) + W[t - 16] \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define P(a,b,c,d,e,f,g,h,x,K) \
|
||||||
|
{ \
|
||||||
|
temp1 = h + S3(e) + XF1(e,f,g) + K + x; \
|
||||||
|
temp2 = S2(a) + XF0(a,b,c); \
|
||||||
|
d += temp1; h = temp1 + temp2; \
|
||||||
|
}
|
||||||
|
|
||||||
|
A = ctx->state[0];
|
||||||
|
B = ctx->state[1];
|
||||||
|
C = ctx->state[2];
|
||||||
|
D = ctx->state[3];
|
||||||
|
E = ctx->state[4];
|
||||||
|
F = ctx->state[5];
|
||||||
|
G = ctx->state[6];
|
||||||
|
H = ctx->state[7];
|
||||||
|
|
||||||
|
P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
|
||||||
|
P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
|
||||||
|
P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
|
||||||
|
P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
|
||||||
|
P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
|
||||||
|
P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
|
||||||
|
P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
|
||||||
|
P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
|
||||||
|
P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
|
||||||
|
P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
|
||||||
|
P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
|
||||||
|
P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
|
||||||
|
P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
|
||||||
|
P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
|
||||||
|
P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
|
||||||
|
P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
|
||||||
|
|
||||||
|
ctx->state[0] += A;
|
||||||
|
ctx->state[1] += B;
|
||||||
|
ctx->state[2] += C;
|
||||||
|
ctx->state[3] += D;
|
||||||
|
ctx->state[4] += E;
|
||||||
|
ctx->state[5] += F;
|
||||||
|
ctx->state[6] += G;
|
||||||
|
ctx->state[7] += H;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 process buffer
|
||||||
|
*/
|
||||||
|
void sha2_update( sha2_context *ctx, const unsigned char *input, size_t ilen )
|
||||||
|
{
|
||||||
|
size_t fill;
|
||||||
|
unsigned long left;
|
||||||
|
|
||||||
|
if( ilen <= 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
left = ctx->total[0] & 0x3F;
|
||||||
|
fill = 64 - left;
|
||||||
|
|
||||||
|
ctx->total[0] += (unsigned long) ilen;
|
||||||
|
ctx->total[0] &= 0xFFFFFFFF;
|
||||||
|
|
||||||
|
if( ctx->total[0] < (unsigned long) ilen )
|
||||||
|
ctx->total[1]++;
|
||||||
|
|
||||||
|
if( left && ilen >= fill )
|
||||||
|
{
|
||||||
|
memcpy( (void *) (ctx->buffer + left),
|
||||||
|
(void *) input, fill );
|
||||||
|
sha2_process( ctx, ctx->buffer );
|
||||||
|
input += fill;
|
||||||
|
ilen -= fill;
|
||||||
|
left = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( ilen >= 64 )
|
||||||
|
{
|
||||||
|
sha2_process( ctx, input );
|
||||||
|
input += 64;
|
||||||
|
ilen -= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ilen > 0 )
|
||||||
|
{
|
||||||
|
memcpy( (void *) (ctx->buffer + left),
|
||||||
|
(void *) input, ilen );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const unsigned char sha2_padding[64] =
|
||||||
|
{
|
||||||
|
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 final digest
|
||||||
|
*/
|
||||||
|
void sha2_finish( sha2_context *ctx, unsigned char output[32] )
|
||||||
|
{
|
||||||
|
unsigned long last, padn;
|
||||||
|
unsigned long high, low;
|
||||||
|
unsigned char msglen[8];
|
||||||
|
|
||||||
|
high = ( ctx->total[0] >> 29 )
|
||||||
|
| ( ctx->total[1] << 3 );
|
||||||
|
low = ( ctx->total[0] << 3 );
|
||||||
|
|
||||||
|
PUT_ULONG_BE( high, msglen, 0 );
|
||||||
|
PUT_ULONG_BE( low, msglen, 4 );
|
||||||
|
|
||||||
|
last = ctx->total[0] & 0x3F;
|
||||||
|
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||||
|
|
||||||
|
sha2_update( ctx, (unsigned char *) sha2_padding, padn );
|
||||||
|
sha2_update( ctx, msglen, 8 );
|
||||||
|
|
||||||
|
PUT_ULONG_BE( ctx->state[0], output, 0 );
|
||||||
|
PUT_ULONG_BE( ctx->state[1], output, 4 );
|
||||||
|
PUT_ULONG_BE( ctx->state[2], output, 8 );
|
||||||
|
PUT_ULONG_BE( ctx->state[3], output, 12 );
|
||||||
|
PUT_ULONG_BE( ctx->state[4], output, 16 );
|
||||||
|
PUT_ULONG_BE( ctx->state[5], output, 20 );
|
||||||
|
PUT_ULONG_BE( ctx->state[6], output, 24 );
|
||||||
|
|
||||||
|
if( ctx->is224 == 0 )
|
||||||
|
PUT_ULONG_BE( ctx->state[7], output, 28 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output = SHA-256( input buffer )
|
||||||
|
*/
|
||||||
|
void sha2( const unsigned char *input, size_t ilen,
|
||||||
|
unsigned char output[32], int is224 )
|
||||||
|
{
|
||||||
|
sha2_context ctx;
|
||||||
|
|
||||||
|
sha2_starts( &ctx, is224 );
|
||||||
|
sha2_update( &ctx, input, ilen );
|
||||||
|
sha2_finish( &ctx, output );
|
||||||
|
|
||||||
|
memset( &ctx, 0, sizeof( sha2_context ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 HMAC context setup
|
||||||
|
*/
|
||||||
|
void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, size_t keylen,
|
||||||
|
int is224 )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
unsigned char sum[32];
|
||||||
|
|
||||||
|
if( keylen > 64 )
|
||||||
|
{
|
||||||
|
sha2( key, keylen, sum, is224 );
|
||||||
|
keylen = ( is224 ) ? 28 : 32;
|
||||||
|
key = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset( ctx->ipad, 0x36, 64 );
|
||||||
|
memset( ctx->opad, 0x5C, 64 );
|
||||||
|
|
||||||
|
for( i = 0; i < keylen; i++ )
|
||||||
|
{
|
||||||
|
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
|
||||||
|
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
sha2_starts( ctx, is224 );
|
||||||
|
sha2_update( ctx, ctx->ipad, 64 );
|
||||||
|
|
||||||
|
memset( sum, 0, sizeof( sum ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 HMAC process buffer
|
||||||
|
*/
|
||||||
|
void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, size_t ilen )
|
||||||
|
{
|
||||||
|
sha2_update( ctx, input, ilen );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 HMAC final digest
|
||||||
|
*/
|
||||||
|
void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] )
|
||||||
|
{
|
||||||
|
int is224, hlen;
|
||||||
|
unsigned char tmpbuf[32];
|
||||||
|
|
||||||
|
is224 = ctx->is224;
|
||||||
|
hlen = ( is224 == 0 ) ? 32 : 28;
|
||||||
|
|
||||||
|
sha2_finish( ctx, tmpbuf );
|
||||||
|
sha2_starts( ctx, is224 );
|
||||||
|
sha2_update( ctx, ctx->opad, 64 );
|
||||||
|
sha2_update( ctx, tmpbuf, hlen );
|
||||||
|
sha2_finish( ctx, output );
|
||||||
|
|
||||||
|
memset( tmpbuf, 0, sizeof( tmpbuf ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 HMAC context reset
|
||||||
|
*/
|
||||||
|
void sha2_hmac_reset( sha2_context *ctx )
|
||||||
|
{
|
||||||
|
sha2_starts( ctx, ctx->is224 );
|
||||||
|
sha2_update( ctx, ctx->ipad, 64 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output = HMAC-SHA-256( hmac key, input buffer )
|
||||||
|
*/
|
||||||
|
void sha2_hmac( const unsigned char *key, size_t keylen,
|
||||||
|
const unsigned char *input, size_t ilen,
|
||||||
|
unsigned char output[32], int is224 )
|
||||||
|
{
|
||||||
|
sha2_context ctx;
|
||||||
|
|
||||||
|
sha2_hmac_starts( &ctx, key, keylen, is224 );
|
||||||
|
sha2_hmac_update( &ctx, input, ilen );
|
||||||
|
sha2_hmac_finish( &ctx, output );
|
||||||
|
|
||||||
|
memset( &ctx, 0, sizeof( sha2_context ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef min
|
||||||
|
#define min( a, b ) ( ((a) < (b)) ? (a) : (b) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void PKCS5_PBKDF2_HMAC(unsigned char *password, size_t plen,
|
||||||
|
unsigned char *salt, size_t slen,
|
||||||
|
const unsigned long iteration_count, const unsigned long key_length,
|
||||||
|
unsigned char *output)
|
||||||
|
{
|
||||||
|
sha2_context ctx;
|
||||||
|
sha2_starts(&ctx, 0);
|
||||||
|
|
||||||
|
// Size of the generated digest
|
||||||
|
unsigned char md_size = 32;
|
||||||
|
unsigned char md1[32];
|
||||||
|
unsigned char work[32];
|
||||||
|
|
||||||
|
unsigned long counter = 1;
|
||||||
|
unsigned long generated_key_length = 0;
|
||||||
|
while (generated_key_length < key_length) {
|
||||||
|
// U1 ends up in md1 and work
|
||||||
|
unsigned char c[4];
|
||||||
|
c[0] = (counter >> 24) & 0xff;
|
||||||
|
c[1] = (counter >> 16) & 0xff;
|
||||||
|
c[2] = (counter >> 8) & 0xff;
|
||||||
|
c[3] = (counter >> 0) & 0xff;
|
||||||
|
|
||||||
|
sha2_hmac_starts(&ctx, password, plen, 0);
|
||||||
|
sha2_hmac_update(&ctx, salt, slen);
|
||||||
|
sha2_hmac_update(&ctx, c, 4);
|
||||||
|
sha2_hmac_finish(&ctx, md1);
|
||||||
|
memcpy(work, md1, md_size);
|
||||||
|
|
||||||
|
unsigned long ic = 1;
|
||||||
|
for (ic = 1; ic < iteration_count; ic++) {
|
||||||
|
// U2 ends up in md1
|
||||||
|
sha2_hmac_starts(&ctx, password, plen, 0);
|
||||||
|
sha2_hmac_update(&ctx, md1, md_size);
|
||||||
|
sha2_hmac_finish(&ctx, md1);
|
||||||
|
// U1 xor U2
|
||||||
|
unsigned long i = 0;
|
||||||
|
for (i = 0; i < md_size; i++) {
|
||||||
|
work[i] ^= md1[i];
|
||||||
|
}
|
||||||
|
// and so on until iteration_count
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the generated bytes to the key
|
||||||
|
unsigned long bytes_to_write =
|
||||||
|
min((key_length - generated_key_length), md_size);
|
||||||
|
memcpy(output + generated_key_length, work, bytes_to_write);
|
||||||
|
generated_key_length += bytes_to_write;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
/*
|
||||||
|
* FIPS-180-2 test vectors
|
||||||
|
*/
|
||||||
|
static unsigned char sha2_test_buf[3][57] =
|
||||||
|
{
|
||||||
|
{ "abc" },
|
||||||
|
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
|
||||||
|
{ "" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int sha2_test_buflen[3] =
|
||||||
|
{
|
||||||
|
3, 56, 1000
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char sha2_test_sum[6][32] =
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* SHA-224 test vectors
|
||||||
|
*/
|
||||||
|
{ 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
|
||||||
|
0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
|
||||||
|
0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
|
||||||
|
0xE3, 0x6C, 0x9D, 0xA7 },
|
||||||
|
{ 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
|
||||||
|
0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
|
||||||
|
0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
|
||||||
|
0x52, 0x52, 0x25, 0x25 },
|
||||||
|
{ 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
|
||||||
|
0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
|
||||||
|
0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
|
||||||
|
0x4E, 0xE7, 0xAD, 0x67 },
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 test vectors
|
||||||
|
*/
|
||||||
|
{ 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
|
||||||
|
0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
|
||||||
|
0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
|
||||||
|
0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
|
||||||
|
{ 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
|
||||||
|
0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
|
||||||
|
0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
|
||||||
|
0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
|
||||||
|
{ 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
|
||||||
|
0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
|
||||||
|
0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
|
||||||
|
0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RFC 4231 test vectors
|
||||||
|
*/
|
||||||
|
static unsigned char sha2_hmac_test_key[7][26] = {
|
||||||
|
{"\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
|
||||||
|
"\x0B\x0B\x0B\x0B"},
|
||||||
|
{"Jefe"},
|
||||||
|
{"\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
|
||||||
|
"\xAA\xAA\xAA\xAA"},
|
||||||
|
{"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
|
||||||
|
"\x11\x12\x13\x14\x15\x16\x17\x18\x19"},
|
||||||
|
{"\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
|
||||||
|
"\x0C\x0C\x0C\x0C"},
|
||||||
|
{""}, /* 0xAA 131 times */
|
||||||
|
{""}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int sha2_hmac_test_keylen[7] = {
|
||||||
|
20, 4, 20, 25, 20, 131, 131
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char sha2_hmac_test_buf[7][153] =
|
||||||
|
{
|
||||||
|
{ "Hi There" },
|
||||||
|
{ "what do ya want for nothing?" },
|
||||||
|
{ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||||
|
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||||
|
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||||
|
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||||
|
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
|
||||||
|
{ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||||
|
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||||
|
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||||
|
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||||
|
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
|
||||||
|
{ "Test With Truncation" },
|
||||||
|
{ "Test Using Larger Than Block-Size Key - Hash Key First" },
|
||||||
|
{ "This is a test using a larger than block-size key "
|
||||||
|
"and a larger than block-size data. The key needs to "
|
||||||
|
"be hashed before being used by the HMAC algorithm." }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int sha2_hmac_test_buflen[7] =
|
||||||
|
{
|
||||||
|
8, 28, 50, 50, 20, 54, 152
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char sha2_hmac_test_sum[14][32] =
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* HMAC-SHA-224 test vectors
|
||||||
|
*/
|
||||||
|
{ 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19,
|
||||||
|
0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F,
|
||||||
|
0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F,
|
||||||
|
0x53, 0x68, 0x4B, 0x22 },
|
||||||
|
{ 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF,
|
||||||
|
0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F,
|
||||||
|
0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00,
|
||||||
|
0x8F, 0xD0, 0x5E, 0x44 },
|
||||||
|
{ 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6,
|
||||||
|
0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64,
|
||||||
|
0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1,
|
||||||
|
0xEC, 0x83, 0x33, 0xEA },
|
||||||
|
{ 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC,
|
||||||
|
0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C,
|
||||||
|
0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D,
|
||||||
|
0xE7, 0xAF, 0xEC, 0x5A },
|
||||||
|
{ 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37,
|
||||||
|
0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 },
|
||||||
|
{ 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD,
|
||||||
|
0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2,
|
||||||
|
0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27,
|
||||||
|
0x3F, 0xA6, 0x87, 0x0E },
|
||||||
|
{ 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02,
|
||||||
|
0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD,
|
||||||
|
0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9,
|
||||||
|
0xF6, 0xF5, 0x65, 0xD1 },
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HMAC-SHA-256 test vectors
|
||||||
|
*/
|
||||||
|
{ 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53,
|
||||||
|
0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B,
|
||||||
|
0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7,
|
||||||
|
0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 },
|
||||||
|
{ 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E,
|
||||||
|
0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7,
|
||||||
|
0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83,
|
||||||
|
0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 },
|
||||||
|
{ 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46,
|
||||||
|
0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7,
|
||||||
|
0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22,
|
||||||
|
0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE },
|
||||||
|
{ 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E,
|
||||||
|
0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A,
|
||||||
|
0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07,
|
||||||
|
0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B },
|
||||||
|
{ 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0,
|
||||||
|
0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B },
|
||||||
|
{ 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F,
|
||||||
|
0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F,
|
||||||
|
0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14,
|
||||||
|
0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 },
|
||||||
|
{ 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB,
|
||||||
|
0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44,
|
||||||
|
0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93,
|
||||||
|
0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 }
|
||||||
|
};
|
||||||
|
typedef struct {
|
||||||
|
char *t;
|
||||||
|
char *p;
|
||||||
|
int plen;
|
||||||
|
char *s;
|
||||||
|
int slen;
|
||||||
|
int c;
|
||||||
|
int dkLen;
|
||||||
|
char dk[1024]; // Remember to set this to max dkLen
|
||||||
|
} testvector;
|
||||||
|
|
||||||
|
int do_test(testvector * tv)
|
||||||
|
{
|
||||||
|
printf("Started %s\n", tv->t);
|
||||||
|
fflush(stdout);
|
||||||
|
char *key = malloc(tv->dkLen);
|
||||||
|
if (key == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PKCS5_PBKDF2_HMAC((unsigned char*)tv->p, tv->plen,
|
||||||
|
(unsigned char*)tv->s, tv->slen, tv->c,
|
||||||
|
tv->dkLen, (unsigned char*)key);
|
||||||
|
|
||||||
|
if (memcmp(tv->dk, key, tv->dkLen) != 0) {
|
||||||
|
// Failed
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checkup routine
|
||||||
|
*/
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int verbose = 1;
|
||||||
|
int i, j, k, buflen;
|
||||||
|
unsigned char buf[1024];
|
||||||
|
unsigned char sha2sum[32];
|
||||||
|
sha2_context ctx;
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
j = i % 3;
|
||||||
|
k = i < 3;
|
||||||
|
|
||||||
|
if (verbose != 0)
|
||||||
|
printf(" SHA-%d test #%d: ", 256 - k * 32, j + 1);
|
||||||
|
|
||||||
|
sha2_starts(&ctx, k);
|
||||||
|
|
||||||
|
if (j == 2) {
|
||||||
|
memset(buf, 'a', buflen = 1000);
|
||||||
|
|
||||||
|
for (j = 0; j < 1000; j++)
|
||||||
|
sha2_update(&ctx, buf, buflen);
|
||||||
|
} else
|
||||||
|
sha2_update(&ctx, sha2_test_buf[j],
|
||||||
|
sha2_test_buflen[j]);
|
||||||
|
|
||||||
|
sha2_finish(&ctx, sha2sum);
|
||||||
|
|
||||||
|
if (memcmp(sha2sum, sha2_test_sum[i], 32 - k * 4) != 0) {
|
||||||
|
if (verbose != 0)
|
||||||
|
printf("failed\n");
|
||||||
|
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose != 0)
|
||||||
|
printf("passed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose != 0)
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
for (i = 0; i < 14; i++) {
|
||||||
|
j = i % 7;
|
||||||
|
k = i < 7;
|
||||||
|
|
||||||
|
if (verbose != 0)
|
||||||
|
printf(" HMAC-SHA-%d test #%d: ", 256 - k * 32,
|
||||||
|
j + 1);
|
||||||
|
|
||||||
|
if (j == 5 || j == 6) {
|
||||||
|
memset(buf, '\xAA', buflen = 131);
|
||||||
|
sha2_hmac_starts(&ctx, buf, buflen, k);
|
||||||
|
} else
|
||||||
|
sha2_hmac_starts(&ctx, sha2_hmac_test_key[j],
|
||||||
|
sha2_hmac_test_keylen[j], k);
|
||||||
|
|
||||||
|
sha2_hmac_update(&ctx, sha2_hmac_test_buf[j],
|
||||||
|
sha2_hmac_test_buflen[j]);
|
||||||
|
|
||||||
|
sha2_hmac_finish(&ctx, sha2sum);
|
||||||
|
|
||||||
|
buflen = (j == 4) ? 16 : 32 - k * 4;
|
||||||
|
|
||||||
|
if (memcmp(sha2sum, sha2_hmac_test_sum[i], buflen) != 0) {
|
||||||
|
if (verbose != 0)
|
||||||
|
printf("failed\n");
|
||||||
|
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose != 0)
|
||||||
|
printf("passed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose != 0)
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
testvector *tv = 0;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
testvector t1 = {
|
||||||
|
"Test 1",
|
||||||
|
"password", 8, "salt", 4, 1, 32,
|
||||||
|
.dk = { 0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c,
|
||||||
|
0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37,
|
||||||
|
0xa8, 0x65, 0x48, 0xc9, 0x2c, 0xcc, 0x35, 0x48,
|
||||||
|
0x08, 0x05, 0x98, 0x7c, 0xb7, 0x0b, 0xe1, 0x7b }
|
||||||
|
};
|
||||||
|
|
||||||
|
tv = &t1;
|
||||||
|
res = do_test(tv);
|
||||||
|
if (res != 0) {
|
||||||
|
printf("%s failed\n", tv->t);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
testvector t2 = {
|
||||||
|
"Test 2",
|
||||||
|
"password", 8, "salt", 4, 2, 32, {
|
||||||
|
0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3,
|
||||||
|
0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0,
|
||||||
|
0x2a, 0x30, 0x3f, 0x8e, 0xf3, 0xc2, 0x51, 0xdf,
|
||||||
|
0xd6, 0xe2, 0xd8, 0x5a, 0x95, 0x47, 0x4c, 0x43 }
|
||||||
|
};
|
||||||
|
|
||||||
|
tv = &t2;
|
||||||
|
res = do_test(tv);
|
||||||
|
if (res != 0) {
|
||||||
|
printf("%s failed\n", tv->t);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
testvector t3 = {
|
||||||
|
"Test 3",
|
||||||
|
"password", 8, "salt", 4, 4096, 32, {
|
||||||
|
0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41,
|
||||||
|
0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d,
|
||||||
|
0x96, 0x28, 0x93, 0xa0, 0x01, 0xce, 0x4e, 0x11,
|
||||||
|
0xa4, 0x96, 0x38, 0x73, 0xaa, 0x98, 0x13, 0x4a }
|
||||||
|
};
|
||||||
|
|
||||||
|
tv = &t3;
|
||||||
|
res = do_test(tv);
|
||||||
|
if (res != 0) {
|
||||||
|
printf("%s failed\n", tv->t);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
testvector t4 = {
|
||||||
|
"Test 4",
|
||||||
|
"password", 8, "salt", 4, 16777216, 32, {
|
||||||
|
0xcf, 0x81, 0xc6, 0x6f, 0xe8, 0xcf, 0xc0, 0x4d,
|
||||||
|
0x1f, 0x31, 0xec, 0xb6, 0x5d, 0xab, 0x40, 0x89,
|
||||||
|
0xf7, 0xf1, 0x79, 0xe8, 0x9b, 0x3b, 0x0b, 0xcb,
|
||||||
|
0x17, 0xad, 0x10, 0xe3, 0xac, 0x6e, 0xba, 0x46 }
|
||||||
|
};
|
||||||
|
|
||||||
|
tv = &t4;
|
||||||
|
// res = do_test(tv);
|
||||||
|
if (res != 0) {
|
||||||
|
printf("%s failed\n", tv->t);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
testvector t5 = {
|
||||||
|
"Test 5",
|
||||||
|
"passwordPASSWORDpassword", 24,
|
||||||
|
"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 4096, 40, {
|
||||||
|
0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f,
|
||||||
|
0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf,
|
||||||
|
0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18,
|
||||||
|
0x1c, 0x4e, 0x2a, 0x1f, 0xb8, 0xdd, 0x53, 0xe1,
|
||||||
|
0xc6, 0x35, 0x51, 0x8c, 0x7d, 0xac, 0x47, 0xe9 }
|
||||||
|
};
|
||||||
|
|
||||||
|
tv = &t5;
|
||||||
|
res = do_test(tv);
|
||||||
|
if (res != 0) {
|
||||||
|
printf("%s failed\n", tv->t);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
testvector t6 = {
|
||||||
|
"Test 6",
|
||||||
|
"pass\0word", 9, "sa\0lt", 5, 4096, 16, {
|
||||||
|
0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89,
|
||||||
|
0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87 }
|
||||||
|
};
|
||||||
|
|
||||||
|
tv = &t6;
|
||||||
|
res = do_test(tv);
|
||||||
|
if (res != 0) {
|
||||||
|
printf("%s failed\n", tv->t);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include "pkcs7_padding.h"
|
||||||
|
|
||||||
|
int pkcs7_padding_pad_buffer( uint8_t *buffer, size_t data_length, size_t buffer_size, uint8_t modulus ){
|
||||||
|
uint8_t pad_byte = modulus - ( data_length % modulus ) ;
|
||||||
|
if( data_length + pad_byte > buffer_size ){
|
||||||
|
return -pad_byte;
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
while( i < pad_byte){
|
||||||
|
buffer[data_length+i] = pad_byte;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return pad_byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pkcs7_padding_valid( uint8_t *buffer, size_t data_length, size_t buffer_size, uint8_t modulus ){
|
||||||
|
uint8_t expected_pad_byte = modulus - ( data_length % modulus ) ;
|
||||||
|
if( data_length + expected_pad_byte > buffer_size ){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
while( i < expected_pad_byte ){
|
||||||
|
if( buffer[data_length + i] != expected_pad_byte){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t pkcs7_padding_data_length( uint8_t * buffer, size_t buffer_size, uint8_t modulus ){
|
||||||
|
/* test for valid buffer size */
|
||||||
|
if( buffer_size % modulus != 0 ||
|
||||||
|
buffer_size < modulus ){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint8_t padding_value;
|
||||||
|
padding_value = buffer[buffer_size-1];
|
||||||
|
/* test for valid padding value */
|
||||||
|
if( padding_value < 1 || padding_value > modulus ){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* buffer must be at least padding_value + 1 in size */
|
||||||
|
if( buffer_size < padding_value + 1 ){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint8_t count = 1;
|
||||||
|
buffer_size --;
|
||||||
|
for( ; count < padding_value ; count++){
|
||||||
|
buffer_size --;
|
||||||
|
if( buffer[buffer_size] != padding_value ){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer_size;
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef _PKCS7_PADDING_H_
|
||||||
|
#define _PKCS7_PADDING_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Pad a buffer with bytes as defined in PKCS#7
|
||||||
|
* Returns the number of pad bytes added, or zero if
|
||||||
|
* the buffer size is not large enough to hold the correctly padded data
|
||||||
|
*/
|
||||||
|
int pkcs7_padding_pad_buffer( uint8_t *buffer, size_t data_length, size_t buffer_size, uint8_t modulus );
|
||||||
|
|
||||||
|
int pkcs7_padding_valid( uint8_t *buffer, size_t data_length, size_t buffer_size, uint8_t modulus );
|
||||||
|
|
||||||
|
/* Given a block of pkcs7 padded data, return the actual data length in the block based on the padding applied.
|
||||||
|
* buffer_size must be a multiple of modulus
|
||||||
|
* last byte 'x' in buffer must be between 1 and modulus
|
||||||
|
* buffer_size must be at least x + 1 in size
|
||||||
|
* last 'x' bytes in buffer must be same as 'x'
|
||||||
|
* returned size will be buffer_size - 'x'
|
||||||
|
*/
|
||||||
|
size_t pkcs7_padding_data_length( uint8_t * buffer, size_t buffer_size, uint8_t modulus );
|
||||||
|
|
||||||
|
#endif
|
|
@ -260,6 +260,9 @@ bool process_record_quantum(keyrecord_t *record) {
|
||||||
#endif
|
#endif
|
||||||
#if defined(VIA_ENABLE)
|
#if defined(VIA_ENABLE)
|
||||||
process_record_via(keycode, record) &&
|
process_record_via(keycode, record) &&
|
||||||
|
#endif
|
||||||
|
#if defined(ENC_ENABLE)
|
||||||
|
process_record_enc(keycode, record) &&
|
||||||
#endif
|
#endif
|
||||||
process_record_kb(keycode, record) &&
|
process_record_kb(keycode, record) &&
|
||||||
#if defined(SECURE_ENABLE)
|
#if defined(SECURE_ENABLE)
|
||||||
|
|
|
@ -217,6 +217,10 @@ extern layer_state_t layer_state;
|
||||||
# include "via.h"
|
# include "via.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENC_ENABLE
|
||||||
|
# include "enc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WPM_ENABLE
|
#ifdef WPM_ENABLE
|
||||||
# include "wpm.h"
|
# include "wpm.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -605,6 +605,18 @@ enum quantum_keycodes {
|
||||||
|
|
||||||
CAPS_WORD,
|
CAPS_WORD,
|
||||||
|
|
||||||
|
#ifdef ENC_ENABLE
|
||||||
|
ENC_INIT,
|
||||||
|
ENC_LOAD,
|
||||||
|
ENC_CLOSE,
|
||||||
|
ENC_PASTE,
|
||||||
|
ENC_KEYSPASTE,
|
||||||
|
ENC_RESET,
|
||||||
|
ENC_REQ_ALLOW,
|
||||||
|
ENC_REQ_DENY,
|
||||||
|
ENC_KEY,
|
||||||
|
#endif
|
||||||
|
|
||||||
// Start of custom keycode range for keyboards and keymaps - always leave at the end
|
// Start of custom keycode range for keyboards and keymaps - always leave at the end
|
||||||
SAFE_RANGE
|
SAFE_RANGE
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,6 +84,14 @@ enum serial_transaction_id {
|
||||||
PUT_POINTING_CPI,
|
PUT_POINTING_CPI,
|
||||||
#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
||||||
|
|
||||||
|
#if defined(ENC_ENABLE) && defined(SPLIT_ENC_MODE_ENABLE)
|
||||||
|
PUT_ENC_MODE,
|
||||||
|
#endif // defined(ENC_ENABLE) && defined(SPLIT_ENC_MODE_ENABLE)
|
||||||
|
|
||||||
|
#if defined(ENC_ENABLE) && defined(SPLIT_ENC_FLAGS_ENABLE)
|
||||||
|
PUT_ENC_FLAGS,
|
||||||
|
#endif // defined(ENC_ENABLE) && defined(SPLIT_ENC_FLAGS_ENABLE)
|
||||||
|
|
||||||
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
||||||
PUT_RPC_INFO,
|
PUT_RPC_INFO,
|
||||||
PUT_RPC_REQ_DATA,
|
PUT_RPC_REQ_DATA,
|
||||||
|
|
|
@ -663,6 +663,59 @@ static void pointing_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s
|
||||||
|
|
||||||
#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////
|
||||||
|
// ENC
|
||||||
|
|
||||||
|
#if defined(ENC_ENABLE) && defined(SPLIT_ENC_MODE_ENABLE)
|
||||||
|
|
||||||
|
static bool enc_mode_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
|
||||||
|
static uint32_t last_update = 0;
|
||||||
|
enc_mode_t enc_mode_sync;
|
||||||
|
enc_mode_sync = enc_get_mode();
|
||||||
|
return send_if_data_mismatch(PUT_ENC_MODE, &last_update, &enc_mode_sync, &split_shmem->enc_mode_sync, sizeof(enc_mode_sync));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void enc_mode_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
|
||||||
|
enc_set_mode(split_shmem->enc_mode_sync);
|
||||||
|
}
|
||||||
|
|
||||||
|
# define TRANSACTIONS_ENC_MODE_MASTER() TRANSACTION_HANDLER_MASTER(enc_mode)
|
||||||
|
# define TRANSACTIONS_ENC_MODE_SLAVE() TRANSACTION_HANDLER_SLAVE(enc_mode)
|
||||||
|
# define TRANSACTIONS_ENC_MODE_REGISTRATIONS [PUT_ENC_MODE] = trans_initiator2target_initializer(enc_mode_sync),
|
||||||
|
|
||||||
|
#else // defined(ENC_ENABLE) && defined(SPLIT_ENC_MODE_ENABLE)
|
||||||
|
|
||||||
|
# define TRANSACTIONS_ENC_MODE_MASTER()
|
||||||
|
# define TRANSACTIONS_ENC_MODE_SLAVE()
|
||||||
|
# define TRANSACTIONS_ENC_MODE_REGISTRATIONS
|
||||||
|
|
||||||
|
#endif // defined(ENC_ENABLE) && defined(SPLIT_ENC_MODE_ENABLE)
|
||||||
|
|
||||||
|
#if defined(ENC_ENABLE) && defined(SPLIT_ENC_FLAGS_ENABLE)
|
||||||
|
|
||||||
|
static bool enc_flags_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
|
||||||
|
static uint32_t last_update = 0;
|
||||||
|
enc_config_flags_t enc_flags_sync;
|
||||||
|
enc_flags_sync = enc_get_config_flags();
|
||||||
|
return send_if_data_mismatch(PUT_ENC_FLAGS, &last_update, &enc_flags_sync, &split_shmem->enc_flags_sync, sizeof(enc_flags_sync));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void enc_flags_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
|
||||||
|
enc_set_config_flags(split_shmem->enc_flags_sync);
|
||||||
|
}
|
||||||
|
|
||||||
|
# define TRANSACTIONS_ENC_FLAGS_MASTER() TRANSACTION_HANDLER_MASTER(enc_flags)
|
||||||
|
# define TRANSACTIONS_ENC_FLAGS_SLAVE() TRANSACTION_HANDLER_SLAVE(enc_flags)
|
||||||
|
# define TRANSACTIONS_ENC_FLAGS_REGISTRATIONS [PUT_ENC_FLAGS] = trans_initiator2target_initializer(enc_flags_sync),
|
||||||
|
|
||||||
|
#else // defined(ENC_ENABLE) && defined(SPLIT_ENC_FLAGS_ENABLE)
|
||||||
|
|
||||||
|
# define TRANSACTIONS_ENC_FLAGS_MASTER()
|
||||||
|
# define TRANSACTIONS_ENC_FLAGS_SLAVE()
|
||||||
|
# define TRANSACTIONS_ENC_FLAGS_REGISTRATIONS
|
||||||
|
|
||||||
|
#endif // defined(ENC_ENABLE) && defined(SPLIT_ENC_FLAGS_ENABLE)
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
|
|
||||||
split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = {
|
split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = {
|
||||||
|
@ -689,6 +742,8 @@ split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = {
|
||||||
TRANSACTIONS_OLED_REGISTRATIONS
|
TRANSACTIONS_OLED_REGISTRATIONS
|
||||||
TRANSACTIONS_ST7565_REGISTRATIONS
|
TRANSACTIONS_ST7565_REGISTRATIONS
|
||||||
TRANSACTIONS_POINTING_REGISTRATIONS
|
TRANSACTIONS_POINTING_REGISTRATIONS
|
||||||
|
TRANSACTIONS_ENC_MODE_REGISTRATIONS
|
||||||
|
TRANSACTIONS_ENC_FLAGS_REGISTRATIONS
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
||||||
|
@ -715,6 +770,8 @@ bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix
|
||||||
TRANSACTIONS_OLED_MASTER();
|
TRANSACTIONS_OLED_MASTER();
|
||||||
TRANSACTIONS_ST7565_MASTER();
|
TRANSACTIONS_ST7565_MASTER();
|
||||||
TRANSACTIONS_POINTING_MASTER();
|
TRANSACTIONS_POINTING_MASTER();
|
||||||
|
TRANSACTIONS_ENC_MODE_MASTER();
|
||||||
|
TRANSACTIONS_ENC_FLAGS_MASTER();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,6 +791,8 @@ void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[
|
||||||
TRANSACTIONS_OLED_SLAVE();
|
TRANSACTIONS_OLED_SLAVE();
|
||||||
TRANSACTIONS_ST7565_SLAVE();
|
TRANSACTIONS_ST7565_SLAVE();
|
||||||
TRANSACTIONS_POINTING_SLAVE();
|
TRANSACTIONS_POINTING_SLAVE();
|
||||||
|
TRANSACTIONS_ENC_MODE_SLAVE();
|
||||||
|
TRANSACTIONS_ENC_FLAGS_SLAVE();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
||||||
|
|
|
@ -185,6 +185,14 @@ typedef struct _split_shared_memory_t {
|
||||||
split_slave_pointing_sync_t pointing;
|
split_slave_pointing_sync_t pointing;
|
||||||
#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
|
||||||
|
|
||||||
|
#if defined(ENC_ENABLE) && defined(SPLIT_ENC_MODE_ENABLE)
|
||||||
|
enc_mode_t enc_mode_sync;
|
||||||
|
#endif // defined(ENC_ENABLE) && defined(SPLIT_ENC_MODE_ENABLE)
|
||||||
|
|
||||||
|
#if defined(ENC_ENABLE) && defined(SPLIT_ENC_FLAGS_ENABLE)
|
||||||
|
enc_config_flags_t enc_flags_sync;
|
||||||
|
#endif // defined(ENC_ENABLE) && defined(SPLIT_ENC_FLAGS_ENABLE)
|
||||||
|
|
||||||
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
|
||||||
rpc_sync_info_t rpc_info;
|
rpc_sync_info_t rpc_info;
|
||||||
uint8_t rpc_m2s_buffer[RPC_M2S_BUFFER_SIZE];
|
uint8_t rpc_m2s_buffer[RPC_M2S_BUFFER_SIZE];
|
||||||
|
|
|
@ -45,10 +45,17 @@
|
||||||
# define VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT 0x00000000
|
# define VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT 0x00000000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// If ENC_ENABLE the layout has to be adjusted
|
||||||
|
// for storing the needed crypto stuff inside the EEPROM
|
||||||
|
#ifdef ENC_ENABLE
|
||||||
|
# include "enc.h"
|
||||||
|
# define VIA_EEPROM_CUSTOM_CONFIG_ADDR (VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE + ENC_EEPROM_SIZE)
|
||||||
|
#else
|
||||||
// The end of the EEPROM memory used by VIA
|
// The end of the EEPROM memory used by VIA
|
||||||
// By default, dynamic keymaps will start at this if there is no
|
// By default, dynamic keymaps will start at this if there is no
|
||||||
// custom config
|
// custom config
|
||||||
#define VIA_EEPROM_CUSTOM_CONFIG_ADDR (VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE)
|
# define VIA_EEPROM_CUSTOM_CONFIG_ADDR (VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef VIA_EEPROM_CUSTOM_CONFIG_SIZE
|
#ifndef VIA_EEPROM_CUSTOM_CONFIG_SIZE
|
||||||
# define VIA_EEPROM_CUSTOM_CONFIG_SIZE 0
|
# define VIA_EEPROM_CUSTOM_CONFIG_SIZE 0
|
||||||
|
|
Loading…
Reference in New Issue