一文了解LinuxKernel中密码学算法的设计与应用

原创 Linux阅码场 2022-05-09 08:00

阅码场Ftrace公开课火热报名中:Ftrace公开课:学优化,学内核(限50人)。课程报名累计30+,课程报名即将截止,报名咨询客服(小月微信:linuxer2016)。



作者简介:


baron (csdn:代码改变世界ctw),九年手机安全/SOC底层安全开发经验。擅长trustzone/tee安全产品的设计和开发。



说明:
在默认情况下,本文讲述的都是ARMV8-aarch64架构,linux kernel 5.14


思考:

1、Linux Kernel中支持哪些密码学算法?分别都是怎么实现的?哪些是C语言实现?哪些是Neon指令实现?哪些是ARM Cryptography Extension硬件实现?这些不同的实现方式,他们之间的关系是怎样的?并列关系?多选一?多选多?

2、应用程序的密码学算法一般又是怎样实现的?应用程序的密码学算法实现,是否依赖Kernel底层的密码学算法?

3、应用程序是如何调用到Kernel底层的密码学算法?Kernel底层的其它模块,如何调用密码学算法?

4、如何在Kernel底层增加一种密码学算法的实现?

5、Kernel的其它模块中,有哪些需要使用密码学算法的场景?
本文术语定义:算法 :算法的种类,如对称密码算法、非对称密码算法... 算法实现 :具体的某一类算法,如aes-cbc、aes-ebc、sm4-cbc、twofish-ecb...


目录

1、密码学基础知识

2、Kernel密码学算法的软件框架和接口模型

2.1、Userspace对底层密码算法的访问
2.2、Kernelspace对底层密码算法的访问
2.3、增加一个算法实现

3、kernel中实现的算法实现

4、crypto engine的实现

5、代码导读

1、密码学基础知识

基本概念,如下请自行学习和理解:

  • 对称密码

  • 非对称密码

  • 数字摘要

  • 随机数

2、Kernel密码学算法的软件框架和接口模型

Linux Kernel系统中实现了很多算法,这些算法被统一归纳为:对称密码算法、数字摘要算法、随机数算法、认证加密算法、非对称密码算法等,并在Kernel层提供了统一操作的接口,供kernel其他模块调用。部分算法又被封装到了网络层,开放暴露给Userspace。其具体的结构/接口模型如下所示:

2.1、Userspace对底层密码算法的访问

Userspace通过netlink接口方式( PF_ALG)调用到底层算法的实现

在Userspace,需指定socket接口 PF_ALG,需指定算法名称(如skcipher)、需指定具体调用的"算法实现"(如aes-cbc),这样命令传输到Kernel层,就能根据这些信息跳转到响应的算法实现层。注意akcipher算法没有暴露给网络层,也就没有开放给Userspace了,所以在User程序中,是无法调用Kernel层的非对称密码算法的。

如下是一个Userspace程序调用kernel底层算法的示例:

(1)建立一个socket会话的流程:

socket(AF_ALG,...)bind()setsockoptacceptsendmsgrecvmsg

(2)相关代码

static int linux_af_alg_socket(const char *type, const char *name){  struct sockaddr_alg sa;  int s;
s = socket(AF_ALG, SOCK_SEQPACKET, 0); if (s < 0) { LogErr("%s: Failed to open AF_ALG socket: %s\n", __func__, strerror(errno)); return -1; }
os_memset(&sa, 0, sizeof(sa)); sa.salg_family = AF_ALG; os_strlcpy((char *) sa.salg_type, type, sizeof(sa.salg_type)); os_strlcpy((char *) sa.salg_name, name, sizeof(sa.salg_name)); if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) { LogErr("%s: Failed to bind AF_ALG socket(%s,%s): %s\n",__func__, (char *) sa.salg_type, (char *) sa.salg_name, strerror(errno)); close(s); return -1; }
return s;}
static struct linux_af_alg_skcipher *linux_af_alg_skcipher(const char *alg, const u8 *key, size_t key_len){ struct linux_af_alg_skcipher *skcipher;
skcipher = os_zalloc(sizeof(*skcipher)); if (!skcipher) goto fail; skcipher->t = -1;
skcipher->s = linux_af_alg_socket(TYPE_NAME, alg); if (skcipher->s < 0) goto fail;
if (setsockopt(skcipher->s, SOL_ALG, ALG_SET_KEY, key, key_len) < 0) { LogErr("%s: setsockopt(ALG_SET_KEY) failed: %s\n", __func__, strerror(errno)); goto fail; }
skcipher->t = accept(skcipher->s, NULL, NULL); if (skcipher->t < 0) { LogErr("%s: accept on AF_ALG socket failed: %s\n", __func__, strerror(errno)); goto fail; }
return skcipher;fail: linux_af_alg_skcipher_deinit(skcipher); return NULL;}
static int aes_128_cbc_oper(char *alg_name, const u8 *key,size_t key_len, int enc, const u8 *iv, u8 *data, size_t data_len){ struct linux_af_alg_skcipher *skcipher; char buf[100]; struct iovec io[1]; struct msghdr msg; struct cmsghdr *hdr; ssize_t ret; u32 *op; struct af_alg_iv *alg_iv; size_t iv_len = AES_BLOCK_SIZE;
skcipher = linux_af_alg_skcipher(alg_name, key, key_len);//alg_name = "__cbc-aes-asr-ce" if (!skcipher) return -1;
io[0].iov_base = (void *) data; io[0].iov_len = data_len; os_memset(&msg, 0, sizeof(msg)); os_memset(buf, 0, sizeof(buf)); msg.msg_control = buf; msg.msg_controllen = CMSG_SPACE(sizeof(u32)) + CMSG_SPACE(sizeof(*alg_iv) + iv_len); msg.msg_iov = io; msg.msg_iovlen = 1;
hdr = CMSG_FIRSTHDR(&msg); hdr->cmsg_level = SOL_ALG; hdr->cmsg_type = ALG_SET_OP; hdr->cmsg_len = CMSG_LEN(sizeof(u32)); op = (u32 *) CMSG_DATA(hdr); *op = enc ? ALG_OP_ENCRYPT : ALG_OP_DECRYPT;
hdr = CMSG_NXTHDR(&msg, hdr); hdr->cmsg_level = SOL_ALG; hdr->cmsg_type = ALG_SET_IV; hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len); alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr); if(NULL != iv){ alg_iv->ivlen = iv_len; os_memcpy(alg_iv->iv, iv, iv_len); }else { alg_iv->ivlen = 0; }
ret = sendmsg(skcipher->t, &msg, 0); if (ret < 0) { LogErr("%s: sendmsg failed: %s\n", __func__, strerror(errno)); linux_af_alg_skcipher_deinit(skcipher); return -1; }
ret = recvmsg(skcipher->t, &msg, 0); if (ret < 0) { LogErr("%s: recvmsg failed: %s\n", __func__, strerror(errno)); linux_af_alg_skcipher_deinit(skcipher); return -1; } if ((size_t) ret < data_len) { LogErr( "%s: recvmsg not return full data (%d/%d)\n", __func__, (int) ret, (int) data_len); linux_af_alg_skcipher_deinit(skcipher); return -1; }
//s_to_binary(data,data_len); linux_af_alg_skcipher_deinit(skcipher); return 0;}
2.2、Kernelspace对底层密码算法的访问

Kernel程序对底层算法的调用采用函数直接调用的方式。流程为:kernel程序--->算法中间层--->算法实现层. 算法中间层 就是暴露给kernel其它模块的API函数。

如下是一个kernel中调用底层算法的一个示例(因skcipher为例):

static int test_skcipher(void){        struct crypto_skcipher *tfm = NULL;        struct skcipher_request *req = NULL;        u8 *data = NULL;        const size_t datasize = 512; /* data size in bytes */        struct scatterlist sg;        DECLARE_CRYPTO_WAIT(wait);        u8 iv[16];  /* AES-256-XTS takes a 16-byte IV */        u8 key[64]; /* AES-256-XTS takes a 64-byte key */        int err;
/* * Allocate a tfm (a transformation object) and set the key. * * In real-world use, a tfm and key are typically used for many * encryption/decryption operations. But in this example, we'll just do a * single encryption operation with it (which is not very efficient). */
tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); if (IS_ERR(tfm)) { pr_err("Error allocating xts(aes) handle: %ld\n", PTR_ERR(tfm)); return PTR_ERR(tfm); }
get_random_bytes(key, sizeof(key)); err = crypto_skcipher_setkey(tfm, key, sizeof(key)); if (err) { pr_err("Error setting key: %d\n", err); goto out; }
/* Allocate a request object */ req = skcipher_request_alloc(tfm, GFP_KERNEL); if (!req) { err = -ENOMEM; goto out; }
/* Prepare the input data */ data = kmalloc(datasize, GFP_KERNEL); if (!data) { err = -ENOMEM; goto out; } get_random_bytes(data, datasize);
/* Initialize the IV */ get_random_bytes(iv, sizeof(iv));
/* * Encrypt the data in-place. * * For simplicity, in this example we wait for the request to complete * before proceeding, even if the underlying implementation is asynchronous. * * To decrypt instead of encrypt, just change crypto_skcipher_encrypt() to * crypto_skcipher_decrypt(). */ sg_init_one(&sg, data, datasize); skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, crypto_req_done, &wait); skcipher_request_set_crypt(req, &sg, &sg, datasize, iv); err = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); if (err) { pr_err("Error encrypting data: %d\n", err); goto out; }
pr_debug("Encryption was successful\n");out: crypto_free_skcipher(tfm); skcipher_request_free(req); kfree(data); return err;}
2.3、增加一个算法实现

增加一个"算法的实现" 只需要:

  • 定义一个算法的结构体变量并初始化,其实就是实现其中的成员函数

  • 将该算法实现注册到系统中。

结构体的定义并初始化:

static struct skcipher_alg aes_algs[] = {   {    .base.cra_name    = "__ecb(aes)",    .base.cra_driver_name  = "__ecb-aes-neonbs",    .base.cra_priority  = 250,    .base.cra_blocksize  = AES_BLOCK_SIZE,    .base.cra_ctxsize  = sizeof(struct aesbs_ctx),    .base.cra_module  = THIS_MODULE,    .base.cra_flags    = CRYPTO_ALG_INTERNAL,
.min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, .walksize = 8 * AES_BLOCK_SIZE, .setkey = aesbs_setkey, .encrypt = ecb_encrypt, .decrypt = ecb_decrypt, },
{ .base.cra_name = "__cbc(aes)", .base.cra_driver_name = "__cbc-aes-neonbs", .base.cra_priority = 250, .base.cra_blocksize = AES_BLOCK_SIZE, .base.cra_ctxsize = sizeof(struct aesbs_cbc_ctx), .base.cra_module = THIS_MODULE, .base.cra_flags = CRYPTO_ALG_INTERNAL,
.min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, .walksize = 8 * AES_BLOCK_SIZE, .ivsize = AES_BLOCK_SIZE, .setkey = aesbs_cbc_setkey, .encrypt = cbc_encrypt, .decrypt = cbc_decrypt, }};

成员函数的实现,例如:

static int ecb_encrypt(struct skcipher_request *req){  return __ecb_crypt(req, aesbs_ecb_encrypt);}

将该算法实现注册到系统中:

static int __init aes_init(void){...  err = crypto_register_skciphers(aes_algs, ARRAY_SIZE(aes_algs));...}module_init(aes_init);

小小总结一下, 如果您要增加一个算法实现,那么您就是需要实现定义如下结构体,并调用 crypto_register_xxx()注册到kernel系统中:
  • skcipher_alg
  • akcipher_alg
  • ahash_alg
  • rng_alg
  • aead_alg

3、kernel中实现的算法实现

思考:

  • 对称密码底层是怎样实现的?纯软?硬件?Neon指令?CE指令?

  • 非对称密码底层是怎样实现的?

  • Hash、rng、aead 又都是怎样实现的?

实现算法的方式:

  • (1)在armv8/armv9的芯片中,有ARM-CE指令可以进行aes/hash/md5计算,

  • (2)在armv8/armv9的芯片中,也有ARM-NEON指令也可以进行aes/hash/md5计算

  • (3)arm的security IP中,有cryptocell之类的加密芯片

  • (4)另外SOC厂商也可能集成自己设计的crypto engine加解密芯片

  • (5)除此之外,还有C语言、汇编程序等编程语言实现的纯软实现

毫无疑问,在效率这块肯定是:(3)(4) > (1) > (2) > (5). 另外从"实现算法的方式" 来看,如果是rng、aead、rsa之类的算法,那么就不能用ARM-CE这种方式,只有编程语言实现、Neon指令实现、crypto engine(含arm security IP)这几种方式了。

kernel怎么玩的?:

  • 针对 crypto engine(含arm security IP) 这种,先当SOC硬件不支持,跳过此场景。

  • 针对rng、aead、rsa,那么kernel有一套纯软的实现 (似乎没有看到arm neon指令的实现)

  • 针对aes、hash,有arm-ce的实现、arm neon指令的实现、纯软的实现,三者三选一(通过宏开关,只能选1)

crypto engine的实现:如果自定义了crypto engine的实现,那么要看你具体的设计,是设计成“取代原有算法实现”,还是设计成“新增算法实现”。如果是前者,那么对于aes/hash,则变成了四选一的了(crypto engine实现、arm-ce的实现、arm neon指令的实现、纯软)。如果是后者,这和原有实现不冲突。

有关aes/hash底层实现三选一的开关

(1) 开启下面两个宏,使用ARM Neon指令的实现 CONFIG_CRYPTO_AES_ARM64_CE_BLK CONFIG_CRYPTO_AES_ARM64_NEON_BLK(2) 在(1) 的基础之上,再开启如下宏,使用ARM CE指令的实现 USE_V8_CRYPTO_EXTENSIONS(3) 以上三个宏都不开启的情况下,使用默认的纯软实现

4、crypto engine的实现

(以ARM Security IP的cryptocell 712为例)

在Linux Kernel中开启 CONFIG_CRYPTO_DEV_CCREE宏控即可起用该实现, 代码路径如下:

以为aes-cbc为例,其实现的名字 和 Kernel中默认是算法实现的名字是一致的,即使这种实现方式是取代原有算法实现

{  .name = "cbc(aes)",  .driver_name = "cbc-aes-ccree",  .blocksize = AES_BLOCK_SIZE,  .template_skcipher = {    .setkey = cc_cipher_setkey,    .encrypt = cc_cipher_encrypt,    .decrypt = cc_cipher_decrypt,    .min_keysize = AES_MIN_KEY_SIZE,    .max_keysize = AES_MAX_KEY_SIZE,    .ivsize = AES_BLOCK_SIZE,  },  .cipher_mode = DRV_CIPHER_CBC,  .flow_mode = S_DIN_to_AES,  .min_hw_rev = CC_HW_REV_630,  .std_body = CC_STD_NIST,}

4、代码导读

在网络层、算法中间层、算法实现层有着丰富的结构体类型?那么怎么去阅读代码?怎弄清各个层面之间的逻辑呢?事实上我们只要理清这些结构体之间的关系,将其抽象成模型,就会变得更加容易理解了。

如下是以Userspace调用底层的对称密码函数为例总结的一张数据结构图:

sock通信进入网络层后(algifskcipher.c),构建skcipherrequest结构体,通过该结构体,就能寻址到底层的算法实现,继而完成算法实现的调用。这些总结一下就是:

  • skcipher_request //网络层构建的结构体

  • cryptoskcipher // kernel中间层构建的结构体,如果是kernel层调用底层算法,那么就从构建cryptocipher结构体开始。

  • skcipher_alg //算法实现层的结构体,描述着具体的算法实现,有实现厂商自己添加。

上述复杂的结构体流程,进一步抽象,就变成如下这个样子:

既然如此,那么我们还可以举一反三一下:




作者上一篇文章:armv8/armv9中断系列详解-中断示例展示

作者往期文章:

第一篇: 深入学习Cache系列 1: 带着几个疑问,从Cache的应用场景学起

第二篇:深入学习Cache系列 2: Cache是如何工作的?概念以及工作过程

第三篇:深入学起Cache系列 3 : 多核多Cluster多系统之间的缓存一致性

第四篇:armv8-armv9 MMU深度学习

第五篇:armv8-armv9中断系列详解-硬件基础篇

往期精华文章:【精华】Linux阅码场原创精华文章汇总


阅码场付费会员专业交流群

会员招募:各专业群会员费为88元/季度,权益包含群内提问,线下活动8折,全年不定期群技术分享(普通用户直播免费,分享后每次点播价为19元/次),有意加入请私信客服小月(小月微信号:linuxer2016)


专业群介绍:

彭伟林-阅码场内核性能与稳定性
本群定位内核性能与稳定性技术交流,覆盖云/网/车/机/芯领域资深内核专家,由阅码场资深讲师彭伟林主持。


甄建勇-性能优化与体系结构

本群定位Perf、cache和CPU架构技术交流,覆盖云/网/车/机/芯领域资深用户,由阅码场资深讲师甄建勇主持。


邓世强-Xenomai与实时优化

本群定位Xenomai与实时优化技术交流,覆盖云/网/车/机/芯领域资深用户,由阅码场资深讲师邓世强和彭伟林共同主持。


周贺贺-Tee和ARM架构

本群定位Tee和ARM架构技术交流,覆盖云/网/车/机/芯领域资深用户,由阅码场资深讲师周贺贺主持。

Linux阅码场 专业的Linux技术社区和Linux操作系统学习平台,内容涉及Linux内核,Linux内存管理,Linux进程管理,Linux文件系统和IO,Linux性能调优,Linux设备驱动以及Linux虚拟化和云计算等各方各面.
评论 (0)
  • 在CAN总线分析软件领域,当CANoe不再是唯一选择时,虹科PCAN-Explorer 6软件成为了一个有竞争力的解决方案。在现代工业控制和汽车领域,CAN总线分析软件的重要性不言而喻。随着技术的进步和市场需求的多样化,单一的解决方案已无法满足所有用户的需求。正是在这样的背景下,虹科PCAN-Explorer 6软件以其独特的模块化设计和灵活的功能扩展,为CAN总线分析领域带来了新的选择和可能性。本文将深入探讨虹科PCAN-Explorer 6软件如何以其创新的模块化插件策略,提供定制化的功能选
    虹科汽车智能互联 2025-04-28 16:00 235浏览
  • 一、智能家居的痛点与创新机遇随着城市化进程加速,现代家庭正面临两大核心挑战:情感陪伴缺失:超60%的双职工家庭存在“亲子陪伴真空期”,儿童独自居家场景增加;操作复杂度攀升:智能设备功能迭代导致用户学习成本陡增,超40%用户因操作困难放弃高阶功能。而WTR096-16S录音语音芯片方案,通过“语音交互+智能录音”双核驱动,不仅解决设备易用性问题,更构建起家庭成员间的全天候情感纽带。二、WTR096-16S方案的核心技术突破1. 高保真语音交互系统动态情绪语音库:支持8种语气模板(温柔提醒/紧急告警
    广州唯创电子 2025-04-28 09:24 196浏览
  • 你是不是也有在公共场合被偷看手机或笔电的经验呢?科技时代下,不少现代人的各式机密数据都在手机、平板或是笔电等可携式的3C产品上处理,若是经常性地需要在公共场合使用,不管是工作上的机密文件,或是重要的个人信息等,民众都有防窃防盗意识,为了避免他人窥探内容,都会选择使用「防窥保护贴片」,以防止数据外泄。现今市面上「防窥保护贴」、「防窥片」、「屏幕防窥膜」等产品就是这种目的下产物 (以下简称防窥片)!防窥片功能与常见问题解析首先,防窥片最主要的功能就是用来防止他人窥视屏幕上的隐私信息,它是利用百叶窗的
    百佳泰测试实验室 2025-04-30 13:28 525浏览
  • 网约车,真的“饱和”了?近日,网约车市场的 “饱和” 话题再度引发热议。多地陆续发布网约车风险预警,提醒从业者谨慎入局,这背后究竟隐藏着怎样的市场现状呢?从数据来看,网约车市场的“过剩”现象已愈发明显。以东莞为例,截至2024年12月底,全市网约车数量超过5.77万辆,考取网约车驾驶员证的人数更是超过13.48万人。随着司机数量的不断攀升,订单量却未能同步增长,导致单车日均接单量和营收双双下降。2024年下半年,东莞网约出租车单车日均订单量约10.5单,而单车日均营收也不容乐
    用户1742991715177 2025-04-29 18:28 297浏览
  • 贞光科技代理品牌紫光国芯的车规级LPDDR4内存正成为智能驾驶舱的核心选择。在汽车电子国产化浪潮中,其产品以宽温域稳定工作能力、优异电磁兼容性和超长使用寿命赢得市场认可。紫光国芯不仅确保供应链安全可控,还提供专业本地技术支持。面向未来,紫光国芯正研发LPDDR5车规级产品,将以更高带宽、更低功耗支持汽车智能化发展。随着智能网联汽车的迅猛发展,智能驾驶舱作为人机交互的核心载体,对处理器和存储器的性能与可靠性提出了更高要求。在汽车电子国产化浪潮中,贞光科技代理品牌紫光国芯的车规级LPDDR4内存凭借
    贞光科技 2025-04-28 16:52 330浏览
  • 浪潮之上:智能时代的觉醒    近日参加了一场课题的答辩,这是医疗人工智能揭榜挂帅的国家项目的地区考场,参与者众多,围绕着医疗健康的主题,八仙过海各显神通,百花齐放。   中国大地正在发生着激动人心的场景:深圳前海深港人工智能算力中心高速运转的液冷服务器,武汉马路上自动驾驶出租车穿行的智慧道路,机器人参与北京的马拉松竞赛。从中央到地方,人工智能相关政策和消息如雨后春笋般不断出台,数字中国的建设图景正在智能浪潮中徐徐展开,战略布局如同围棋
    广州铁金刚 2025-04-30 15:24 274浏览
  • 晶振在使用过程中可能会受到污染,导致性能下降。可是污染物是怎么进入晶振内部的?如何检测晶振内部污染物?我可不可以使用超声波清洗?今天KOAN凯擎小妹将逐一解答。1. 污染物来源a. 制造过程:生产环境不洁净或封装密封不严,可能导致灰尘和杂质进入晶振。b. 使用环境:高湿度、温度变化、化学物质和机械应力可能导致污染物渗入。c. 储存不当:不良的储存环境和不合适的包装材料可能引发化学物质迁移。建议储存湿度维持相对湿度在30%至75%的范围内,有助于避免湿度对晶振的不利影响。避免雨淋或阳光直射。d.
    koan-xtal 2025-04-28 06:11 173浏览
  • 在智能硬件设备趋向微型化的背景下,语音芯片方案厂商针对小体积设备开发了多款超小型语音芯片方案,其中WTV系列和WT2003H系列凭借其QFN封装设计、高性能与高集成度,成为微型设备语音方案的理想选择。以下从封装特性、功能优势及典型应用场景三个方面进行详细介绍。一、超小体积封装:QFN技术的核心优势WTV系列与WT2003H系列均提供QFN封装(如QFN32,尺寸为4×4mm),这种封装形式具有以下特点:体积紧凑:QFN封装通过减少引脚间距和优化内部结构,显著缩小芯片体积,适用于智能门铃、穿戴设备
    广州唯创电子 2025-04-30 09:02 332浏览
  • 随着电子元器件的快速发展,导致各种常见的贴片电阻元器件也越来越小,给我们分辨也就变得越来越难,下面就由smt贴片加工厂_安徽英特丽就来告诉大家如何分辨的SMT贴片元器件。先来看看贴片电感和贴片电容的区分:(1)看颜色(黑色)——一般黑色都是贴片电感。贴片电容只有勇于精密设备中的贴片钽电容才是黑色的,其他普通贴片电容基本都不是黑色的。(2)看型号标码——贴片电感以L开头,贴片电容以C开头。从外形是圆形初步判断应为电感,测量两端电阻为零点几欧,则为电感。(3)检测——贴片电感一般阻值小,更没有“充放
    贴片加工小安 2025-04-29 14:59 337浏览
  • 文/Leon编辑/cc孙聪颖‍2023年,厨电行业在相对平稳的市场环境中迎来温和复苏,看似为行业增长积蓄势能。带着对市场向好的预期,2024 年初,老板电器副董事长兼总经理任富佳为企业定下双位数增长目标。然而现实与预期相悖,过去一年,这家老牌厨电企业不仅未能达成业绩目标,曾提出的“三年再造一个老板电器”愿景,也因市场下行压力面临落空风险。作为“企二代”管理者,任富佳在掌舵企业穿越市场周期的过程中,正面临着前所未有的挑战。4月29日,老板电器(002508.SZ)发布了2024年年度报告及2025
    华尔街科技眼 2025-04-30 12:40 294浏览
  • 4月22日下午,备受瞩目的飞凌嵌入式「2025嵌入式及边缘AI技术论坛」在深圳深铁皇冠假日酒店盛大举行,此次活动邀请到了200余位嵌入式技术领域的技术专家、企业代表和工程师用户,共享嵌入式及边缘AI技术的盛宴!1、精彩纷呈的展区产品及方案展区是本场活动的第一场重头戏,从硬件产品到软件系统,从企业级应用到高校教学应用,都吸引了现场来宾的驻足观看和交流讨论。全产品矩阵展区展示了飞凌嵌入式丰富的产品线,从嵌入式板卡到工控机,从进口芯片平台到全国产平台,无不体现出飞凌嵌入式在嵌入式主控设备研发设计方面的
    飞凌嵌入式 2025-04-28 14:43 181浏览
  •  探针台的维护直接影响其测试精度与使用寿命,需结合日常清洁、环境控制、定期校准等多维度操作,具体方法如下:一、日常清洁与保养1.‌表面清洁‌l 使用无尘布或软布擦拭探针台表面,避免残留清洁剂或硬物划伤精密部件。l 探针头清洁需用非腐蚀性溶剂(如异丙醇)擦拭,检查是否弯曲或损坏。2.‌光部件维护‌l 镜头、观察窗等光学部件用镜头纸蘸取wu水jiu精从中心向外轻擦,操作时远离火源并保持通风。3.‌内部防尘‌l 使用后及时吹扫灰尘,防止污染物进入机械滑
    锦正茂科技 2025-04-28 11:45 125浏览
  • 文/郭楚妤编辑/cc孙聪颖‍越来越多的企业开始蚕食动力电池市场,行业“去宁王化”态势逐渐明显。随着这种趋势的加强,打开新的市场对于宁德时代而言至关重要。“我们不希望被定义为电池的制造者,而是希望把自己称作新能源产业的开拓者。”4月21日,在宁德时代举行的“超级科技日”发布会上,宁德时代掌门人曾毓群如是说。随着宁德时代核心新品骁遥双核电池的发布,其搭载的“电电增程”技术也走进业界视野。除此之外,经过近3年试水,宁德时代在换电业务上重资加码。曾毓群认为换电是一个重资产、高投入、长周期的产业,涉及的利
    华尔街科技眼 2025-04-28 21:55 208浏览
  • 一、gao效冷却与控温机制‌1、‌冷媒流动设计‌采用低压液氮(或液氦)通过毛细管路导入蒸发器,蒸汽喷射至样品腔实现快速冷却,冷却效率高(室温至80K约20分钟,至4.2K约30分钟)。通过控温仪动态调节蒸发器加热功率,结合温度传感器(如PT100铂电阻或Cernox磁场不敏感传感器),实现±0.01K的高精度温度稳定性。2、‌宽温区覆盖与扩展性‌标准温区为80K-325K,通过降压选件可将下限延伸至65K(液氮模式)或4K(液氦模式)。可选配475K高温模块,满足材料在ji端温度下的性能测试需求
    锦正茂科技 2025-04-30 13:08 417浏览
  • 在电子电路设计和调试中,晶振为电路提供稳定的时钟信号。我们可能会遇到晶振有电压,但不起振,从而导致整个电路无法正常工作的情况。今天凯擎小妹聊一下可能的原因和解决方案。1. 误区解析在硬件调试中,许多工程师在测量晶振时发现两端都有电压,例如1.6V,但没有明显的压差,第一反应可能是怀疑短路。晶振电路本质上是一个交流振荡电路。当晶振未起振时,两端会静止在一个中间电位,通常接近电源电压的一半。万用表测得的是稳定的直流电压,因此没有压差。这种情况一般是:晶振没起振,并不是短路。2. 如何判断真
    koan-xtal 2025-04-28 05:09 311浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦