7
7
8
8
#include <linux/armada-37xx-rwtm-mailbox.h>
9
9
#include <linux/completion.h>
10
+ #include <linux/debugfs.h>
10
11
#include <linux/dma-mapping.h>
11
12
#include <linux/hw_random.h>
12
13
#include <linux/mailbox_client.h>
@@ -69,6 +70,18 @@ struct mox_rwtm {
69
70
/* public key burned in eFuse */
70
71
int has_pubkey ;
71
72
u8 pubkey [135 ];
73
+
74
+ #ifdef CONFIG_DEBUG_FS
75
+ /*
76
+ * Signature process. This is currently done via debugfs, because it
77
+ * does not conform to the sysfs standard "one file per attribute".
78
+ * It should be rewritten via crypto API once akcipher API is available
79
+ * from userspace.
80
+ */
81
+ struct dentry * debugfs_root ;
82
+ u32 last_sig [34 ];
83
+ int last_sig_done ;
84
+ #endif
72
85
};
73
86
74
87
struct mox_kobject {
@@ -279,6 +292,152 @@ static int mox_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
279
292
return ret ;
280
293
}
281
294
295
+ #ifdef CONFIG_DEBUG_FS
296
+ static int rwtm_debug_open (struct inode * inode , struct file * file )
297
+ {
298
+ file -> private_data = inode -> i_private ;
299
+
300
+ return nonseekable_open (inode , file );
301
+ }
302
+
303
+ static ssize_t do_sign_read (struct file * file , char __user * buf , size_t len ,
304
+ loff_t * ppos )
305
+ {
306
+ struct mox_rwtm * rwtm = file -> private_data ;
307
+ ssize_t ret ;
308
+
309
+ /* only allow one read, of 136 bytes, from position 0 */
310
+ if (* ppos != 0 )
311
+ return 0 ;
312
+
313
+ if (len < 136 )
314
+ return - EINVAL ;
315
+
316
+ if (!rwtm -> last_sig_done )
317
+ return - ENODATA ;
318
+
319
+ /* 2 arrays of 17 32-bit words are 136 bytes */
320
+ ret = simple_read_from_buffer (buf , len , ppos , rwtm -> last_sig , 136 );
321
+ rwtm -> last_sig_done = 0 ;
322
+
323
+ return ret ;
324
+ }
325
+
326
+ static ssize_t do_sign_write (struct file * file , const char __user * buf ,
327
+ size_t len , loff_t * ppos )
328
+ {
329
+ struct mox_rwtm * rwtm = file -> private_data ;
330
+ struct armada_37xx_rwtm_rx_msg * reply = & rwtm -> reply ;
331
+ struct armada_37xx_rwtm_tx_msg msg ;
332
+ loff_t dummy = 0 ;
333
+ ssize_t ret ;
334
+
335
+ /* the input is a SHA-512 hash, so exactly 64 bytes have to be read */
336
+ if (len != 64 )
337
+ return - EINVAL ;
338
+
339
+ /* if last result is not zero user has not read that information yet */
340
+ if (rwtm -> last_sig_done )
341
+ return - EBUSY ;
342
+
343
+ if (!mutex_trylock (& rwtm -> busy ))
344
+ return - EBUSY ;
345
+
346
+ /*
347
+ * Here we have to send:
348
+ * 1. Address of the input to sign.
349
+ * The input is an array of 17 32-bit words, the first (most
350
+ * significat) is 0, the rest 16 words are copied from the SHA-512
351
+ * hash given by the user and converted from BE to LE.
352
+ * 2. Address of the buffer where ECDSA signature value R shall be
353
+ * stored by the rWTM firmware.
354
+ * 3. Address of the buffer where ECDSA signature value S shall be
355
+ * stored by the rWTM firmware.
356
+ */
357
+ memset (rwtm -> buf , 0 , 4 );
358
+ ret = simple_write_to_buffer (rwtm -> buf + 4 , 64 , & dummy , buf , len );
359
+ if (ret < 0 )
360
+ goto unlock_mutex ;
361
+ be32_to_cpu_array (rwtm -> buf , rwtm -> buf , 17 );
362
+
363
+ msg .command = MBOX_CMD_SIGN ;
364
+ msg .args [0 ] = 1 ;
365
+ msg .args [1 ] = rwtm -> buf_phys ;
366
+ msg .args [2 ] = rwtm -> buf_phys + 68 ;
367
+ msg .args [3 ] = rwtm -> buf_phys + 2 * 68 ;
368
+ ret = mbox_send_message (rwtm -> mbox , & msg );
369
+ if (ret < 0 )
370
+ goto unlock_mutex ;
371
+
372
+ ret = wait_for_completion_interruptible (& rwtm -> cmd_done );
373
+ if (ret < 0 )
374
+ goto unlock_mutex ;
375
+
376
+ ret = MBOX_STS_VALUE (reply -> retval );
377
+ if (MBOX_STS_ERROR (reply -> retval ) != MBOX_STS_SUCCESS )
378
+ goto unlock_mutex ;
379
+
380
+ /*
381
+ * Here we read the R and S values of the ECDSA signature
382
+ * computed by the rWTM firmware and convert their words from
383
+ * LE to BE.
384
+ */
385
+ memcpy (rwtm -> last_sig , rwtm -> buf + 68 , 136 );
386
+ cpu_to_be32_array (rwtm -> last_sig , rwtm -> last_sig , 34 );
387
+ rwtm -> last_sig_done = 1 ;
388
+
389
+ mutex_unlock (& rwtm -> busy );
390
+ return len ;
391
+ unlock_mutex :
392
+ mutex_unlock (& rwtm -> busy );
393
+ return ret ;
394
+ }
395
+
396
+ static const struct file_operations do_sign_fops = {
397
+ .owner = THIS_MODULE ,
398
+ .open = rwtm_debug_open ,
399
+ .read = do_sign_read ,
400
+ .write = do_sign_write ,
401
+ .llseek = no_llseek ,
402
+ };
403
+
404
+ static int rwtm_register_debugfs (struct mox_rwtm * rwtm )
405
+ {
406
+ struct dentry * root , * entry ;
407
+
408
+ root = debugfs_create_dir ("turris-mox-rwtm" , NULL );
409
+
410
+ if (IS_ERR (root ))
411
+ return PTR_ERR (root );
412
+
413
+ entry = debugfs_create_file_unsafe ("do_sign" , 0600 , root , rwtm ,
414
+ & do_sign_fops );
415
+ if (IS_ERR (entry ))
416
+ goto err_remove ;
417
+
418
+ rwtm -> debugfs_root = root ;
419
+
420
+ return 0 ;
421
+ err_remove :
422
+ debugfs_remove_recursive (root );
423
+ return PTR_ERR (entry );
424
+ }
425
+
426
+ static void rwtm_unregister_debugfs (struct mox_rwtm * rwtm )
427
+ {
428
+ debugfs_remove_recursive (rwtm -> debugfs_root );
429
+ }
430
+ #else
431
+ static inline int rwtm_register_debugfs (struct mox_rwtm * rwtm )
432
+ {
433
+ return 0 ;
434
+ }
435
+
436
+ static inline void rwtm_unregister_debugfs (struct mox_rwtm * rwtm )
437
+ {
438
+ }
439
+ #endif
440
+
282
441
static int turris_mox_rwtm_probe (struct platform_device * pdev )
283
442
{
284
443
struct mox_rwtm * rwtm ;
@@ -340,6 +499,12 @@ static int turris_mox_rwtm_probe(struct platform_device *pdev)
340
499
goto free_channel ;
341
500
}
342
501
502
+ ret = rwtm_register_debugfs (rwtm );
503
+ if (ret < 0 ) {
504
+ dev_err (dev , "Failed creating debugfs entries: %i\n" , ret );
505
+ goto free_channel ;
506
+ }
507
+
343
508
return 0 ;
344
509
345
510
free_channel :
@@ -355,6 +520,7 @@ static int turris_mox_rwtm_remove(struct platform_device *pdev)
355
520
{
356
521
struct mox_rwtm * rwtm = platform_get_drvdata (pdev );
357
522
523
+ rwtm_unregister_debugfs (rwtm );
358
524
sysfs_remove_files (rwtm_to_kobj (rwtm ), mox_rwtm_attrs );
359
525
kobject_put (rwtm_to_kobj (rwtm ));
360
526
mbox_free_channel (rwtm -> mbox );
0 commit comments