跳到主要内容

上位机使用指南

上位机使用Python语言开发,通过TCP协议与设备进行通信。 推荐在Jupyter环境下使用上位机对设备进行操作,这样可以利用上位机提供的设备控制面板减少代码编辑量,并且能够通过示波器面板实时查看到设备参数配置的效果。

上位机总体架构如下图:

对于上位机SDK的API说明,可访问https://cracknuts.readthedocs.io/zh-cn/stable/了解。

上位机中Cracker代表设备,Acquisition代表采集流程,围绕这两个模块上位机可以实现对设备的控制、数据的采集。

命令行工具

安装完CrackNuts后,在控制台中提供cracknuts命令,提供以下Jupyter快捷命令:

  1. 启动Jupyter lab
    cracknuts lab
  2. 打开教程
    cracknuts tutorials
  3. 创建新笔记文件
    cracknuts create -t [template name] -n [new notebook name]
  4. 全局配置
    cracknuts config set lab.workspace  # 配置 cracknuts lab 打开的默认工作目录

上位机基本使用

上位机安装成功后,可以通过Python对设备进行控制。如下,通过Python控制台直接访问设备并进行配置:

  1. 启动Python环境:
    通过快速安装方式安装的CrackNuts,可以通过快捷图标启动CrackNuts环境,其他方式安装的可以根据自己的情况选择合适的方式进入有CrackNuts依赖的Python环境

    alt text

  2. 连接设备并对Nut配置电压

    alt text

    以上代码解释如下:

    # 引入 cracknuts
    >>> import cracknuts as cn
    # 通过快速入口函数创建一个Cracker对象
    >>> cracker = cn.new_cracker('192.168.0.211')
    # 连接设备
    >>> cracker.connect()
    # 获取设备ID,此处仅用于验证连接状态,这是一个验证设备正确连接的简单有效方法
    >>> cracker.get_id()
    (0, '74332025379485') # 此处为 CrackNuts 上位机 API 的返回格式:元组第一位为函数执行状态位,0 表示成功,其他表示失败; 第二位位返回数据位,此处获取设备ID(S/N)即在此处,对于没有返回数据需求的接口则为None
    # 配置Nut设备电压为3.2V
    >>> cracker.nut_voltage(3.2)
    (0, None)
    # 对Nut进行使能操作,此时默认的stm32 103的Nut板上应该亮灯
    >>> cracker.nut_voltage_enable()
    (0, None)
    >>>

    以上就完成了最简单的上位机的控制,其他更丰富的配置可阅读API文档了解。

采集流程

在“快速开始”章节中,您可能已经注意到,使用 CrackNuts 进行波形采集时,仅需控制 Nut 的动作,即可完成能量波形的采集。这是因为 CrackNuts 设计了一套简化的采集流程,旨在降低操作复杂度,使用户能够专注于 Nut 的加密等核心流程控制。

该采集流程由 Acquisition 类负责管理,即使用控制面板前创建的 acq 对象。该对象实现了指令发送、加密数据保存、能量轨迹保存等关键步骤,并预留了 initdo 两个阶段,供用户插入自定义逻辑。通过该流程,用户可以实现以下功能:

  • 使用图形界面配置参数,支持波形实时展示,便于调整设备设置;
  • 自动保存配置参数,方便实验流程复现;
  • 自动保存采集到的曲线数据,便于后续的数据分析。

采集流程的结构如下图所示:

alt text

与这个流程对应的Cracker及Nut的流程图如下图:

alt text

图中,CrackNuts 表示上位机软件,Cracker 是测试设备,Nut 为被测对象,下发的 Wave 则代表侧信道信号。 用户需实现两个函数:init()do(),其中 init() 函数仅在采集流程开始时执行一次,而 do() 函数则会被循环调用。 在这两个函数中,用户可编写具体的指令逻辑,通过 Cracker 下发给 Nut,并接收 Nut 返回的数据,由 Cracker 再转发回 CrackNuts 上位机程序。 当 init() 函数执行完成后,CrackNuts 会自动向 Cracker 下发 osc_single() 命令,将其设置为“准备采集曲线”模式。具体的触发条件可通过上位机界面或命令进行配置,支持的参数包括:信号源(A/B 通道)、触发对象(如 Nut)、通信协议等。 在 do() 函数执行期间,Cracker 会实时检测触发条件,一旦条件满足,即刻采集波形数据。 待 do() 函数执行完毕后,CrackNuts 会自动判断是否成功触发采集:如触发成功,则从 Cracker 中读取采集到的数据并进行保存。

在快速开始章节中的创建Acquisition,就是这个采集流程:

import random
import time
from cracknuts.cracker import serial


cmd_set_aes_enc_key = "01 00 00 00 00 00 00 10"
cmd_aes_enc = "01 02 00 00 00 00 00 10"

aes_key = "11 22 33 44 55 66 77 88 99 00 aa bb cc dd ee ff"
aes_data_len = 16

sample_length = 1024 * 20

def init(c):
cracker.nut_voltage_enable()
cracker.nut_voltage(3.4)
cracker.nut_clock_enable()
cracker.nut_clock_freq('8M')
cracker.uart_enable()
cracker.osc_sample_clock('48m')
cracker.osc_sample_length(sample_length)
cracker.osc_trigger_source('N')
cracker.osc_analog_gain('B', 10)
cracker.osc_trigger_level(0)
cracker.osc_trigger_mode('E')
cracker.osc_trigger_edge('U')
cracker.uart_config(baudrate=serial.Baudrate.BAUDRATE_115200, bytesize=serial.Bytesize.EIGHTBITS, parity=serial.Parity.PARITY_NONE, stopbits=serial.Stopbits.STOPBITS_ONE)

time.sleep(2)
cmd = cmd_set_aes_enc_key + aes_key
status, ret = cracker.uart_transmit_receive(cmd, timeout=1000, rx_count=6)

def do(c):

plaintext_data = random.randbytes(aes_data_len)
tx_data = bytes.fromhex(cmd_aes_enc.replace(' ', '')) + plaintext_data
status, ret = cracker.uart_transmit_receive(tx_data, rx_count= 6 + aes_data_len, is_trigger=True)

return {
"plaintext": plaintext_data,
"ciphertext": ret[-aes_data_len:],
"key": bytes.fromhex(aes_key)
}

acq = cn.new_acquisition(cracker, do=do, init=init)

这其中new_acquisition必须传入的参数中含义如下,其他更:

  • cracker: Acquisiton 流程要管理的Cracker目标
  • do: 用户具体的加密逻辑函数,并且回需返回要保存到波形文件中的数据
  • init: 能量轨迹采集开始前的准备工作,如一些基础的配置

同样的,在控制面板中(关于控制面板的介绍在后续在Jupyter中使用CrackNuts上位机中有介绍),有着更丰富的流程控制参数可以配置:

alt text

其含义如下(参考上面的流程图可更好的理解)这些参数如果对整体流程不了解的情况下不建议修改:

  • 触发判断等待时长:每次is_trigger判断之间的间隔
  • 触发判断超时:经过该时常后设备依然没有判定到触发状态,则认为该轮采集失败
  • 采集频率:在测试模式下每隔多长时间对设备进行一次加密数据操作
  • do异常最大次数:用户do函数中的代码允许出现错误的次数,默认-1不允许出现错误

除了上面的流程控制参数外,控制面板的流程管理区域其他功能如下:

alt text

  • 流程状态控制:
    • 测试:仅进行数据加密、能量轨迹操作不保存波形文件
    • 运行:进行完整的数据加密、能量采集、文件保存操作
    • 暂停:暂停当前的测试或运行流程
    • 停止:停止当前的测试或运行流程
  • 采集轮数:采集的曲线数量,即执行多少次do函数的内容
  • 保存格式:曲线文件的保存格式,默认是scarr格式,可选numpy格式
  • 保存路径:曲线文件的保存文件夹,曲线文件会以时间戳格式命名保存到这个目录下

CrackNuts面板的其他功能可参考后续章节的介绍。

在Jupyter中使用CrackNuts上位机

除了可以在Python控制台和Python脚本文件中使用CrackNuts外,还可以使用Jupyter环境,也是我们推荐的方式。在Jupyter中我们提供了更为简洁的GUI控制面板方式实现对设备的控制、数据的展现。

并且还提供了cracknuts lab这个简洁命令来启动一个Jupyter环境。

alt text

通过以上命令可以启动一个Jupyter lab 环境,之后就可以创建一个Jupyter Notebook来开始控制设备

alt text

在新建的Notebook中分两个单元格输入如下内容,即可打开设备控制面板:

第一单元格
import cracknuts as cn

cracker = cn.new_cracker('192.168.0.10')
cracker.connect()
cracker.get_id()
第二单元格
cracker.nut_voltage(3.1)
cracker.nut_voltage_enable()

每一个单元格填写完成代码后,执行代码即可完成代码的执行,效果如下图。(可以使用Ctrl+Enter来执行,也可使用Shift+Ctrl执行,后者执行完成后下一个单元将自动激活)

alt text

按照以上步骤执行后,可以同样完成对Nut的电压配置和使能配置。

Jupyter控制面板组件

Jupyter中还可以使用设备控制面板对设备进行控制,执行如下代码开启设备控制面板

# 创建一个空采集流程控制对象,
acq = cn.new_acquisition(cracker)
# 展示面板
cn.panel(acq)

alt text

设备控制面板集成了采集流程管理、NUT管理、SCOPE管理、模型展现四个大功能模块,分别实现能量轨迹的采集管理、NUT目标板控制、Cracker采集板控制、波形展现这四类功能。

alt text

Jupyter Notebook 配置

Jupyter中使用控制面板后,可以使用配置功能,该功能可以将当前面板中的配置进行保存、导出、导入、写入设备操作,也可以读取设备的当前配置到面板。

alt text

保存配置导出配置的区别是,其把当前配置保存到与Jupyter Notebook文件关联的配置文件中,下次打开该Jupyter Notebook中的设备控制面板时自动加载该配置。、 而导出配置则导出到一个配置文件,用户可以在需要的时候通过加载配置加载该配置。

注意

默认情况下,通过代码对Cracker的配置会同步到控制面板中,但是如果控制面中加载了配置文件中配置(无论是加载的关联Jupyter Notebook还是通过加载配置配置加载的外部配置) 并且其与设备中的配置不一致,控制面板将通过写入配置这个按钮变成红色进行提示,此时通过代码对设备的配置将不同步到控制面板中,直到通过写入按钮把配置写入到设备。

alt text

语言切换

控制面板在第一次使用时,默认界面展示的是英文,用户可以通过面板右上角的语言切换按钮进行切换,切换后对所有Jupyter Notebooke生效。

alt text

Jupyter默认工作目录配置

通过cracknuts lab命令启动的Jupter lab实例,可以通过如下命令配置默认的工作空间,保证用户无论在哪个目录下执行这个命令都能从工作空间启动。

cracknuts config set lab.workspace

日志配置

默认情况下,使用CrackNuts时,日志会打印到当前控制台,如果是Jupyter则会打印到运行单元格的下方,这些日志可以方便用户调试程序排查问题。

alt text

日志级别配置

CrackNuts默认的日志是warning级别,只打印必要的警告和错误信息,如果用户需要更详细的诸如发送的数据等信息可以通过以下方式修改日志级别为info来实现:

from cracknuts import logger
logger.set_level('info')

alt text

或者更加详细,把日志级别改成debug,但是这样打印信息会非常多,使用时需要注意:

from cracknuts import logger
logger.set_level('debug')

alt text

日志打印位置配置

有的时候,尤其是在能量轨迹采集过程中,会有有大量的日志打印,此时日志打印在控制台或者Jupyter Notebook中,会使得Jupyter页面变得非常长,难以使用,此时可以通过以下代码把日志重定向到文件,在通过其他工具进行日志的检查。

from cracknuts import logger
logger.handler_to_file(r"d:\a.log")

配置后可以通过任意文本编辑器打开日志文件进行检查:

alt text

当前Linux或者MacOS用户可以通过tail -f的形式实时监控日志打印,Windows 用户可以通过在Powershell中使用Get-Content "d:\a.log" -Wait命令实现tail效果

alt text

更改 Cracker IP地址

如果你是将Cracker接入到已有的以太网中,需要该以太网的IP网络属于192.168.0.0/24这个网络,如果现有网络不在这个网段,则需要修改Cracker的IP。您需要先通过直连方式连接到设备在通过上位机SDK进行IP修改。

打开CrackNuts环境,启动Python 然后在执行如下代码进行IP修改:

import cracknuts as cn
s1 = cn.new_cracker('192.168.0.10')
s1.connect()
s1.get_operator().set_ip('192.168.0.251', '255.255.255.0', '192.168.0.1') # 此处IP地址及掩码、网关等需要修改为您的目标网络的允许的配置

执行成功后,Cracker设备的显示屏上会显示修改后的IP地址。